Version 3.19.9

Implemented Load IC support for loading properties from primitive values to avoid perpetual soft deopts.  (Chromium issue 242512)

Implemented Freeing of PerThreadAssertData when possible to avoid memory leak. (Chromium issue 246567)

Removed V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS.

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@14954 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index f9ddd6c..25d11b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2013-06-05: Version 3.19.9
+
+        Implemented Load IC support for loading properties from primitive
+        values to avoid perpetual soft deopts.  (Chromium issue 242512)
+
+        Implemented Freeing of PerThreadAssertData when possible to avoid
+        memory leak. (Chromium issue 246567)
+
+        Removed V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS.
+
+        Performance and stability improvements on all platforms.
+
+
 2013-06-03: Version 3.19.8
 
         Fixed bug with inlining 'Array' function. (Chromium issue 244461)
diff --git a/include/v8.h b/include/v8.h
index a41445d..28a63f0 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -223,7 +223,6 @@
 
 
 #define V8_USE_UNSAFE_HANDLES
-#define V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS
 
 /**
  * An object reference managed by the v8 garbage collector.
@@ -4125,13 +4124,8 @@
 class V8EXPORT PersistentHandleVisitor {  // NOLINT
  public:
   virtual ~PersistentHandleVisitor() {}
-#ifdef V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS
-  virtual void VisitPersistentHandle(Persistent<Value> value,
-                                     uint16_t class_id) {}
-#else
   virtual void VisitPersistentHandle(Persistent<Value>* value,
                                      uint16_t class_id) {}
-#endif
 };
 
 
diff --git a/samples/lineprocessor.cc b/samples/lineprocessor.cc
index 635691e..214af05 100644
--- a/samples/lineprocessor.cc
+++ b/samples/lineprocessor.cc
@@ -102,8 +102,8 @@
 v8::Handle<v8::String> ReadFile(const char* name);
 v8::Handle<v8::String> ReadLine();
 
-v8::Handle<v8::Value> Print(const v8::Arguments& args);
-v8::Handle<v8::Value> ReadLine(const v8::Arguments& args);
+void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
+void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args);
 bool RunCppCycle(v8::Handle<v8::Script> script,
                  v8::Local<v8::Context> context,
                  bool report_exceptions);
@@ -393,7 +393,7 @@
 // The callback that is invoked by v8 whenever the JavaScript 'print'
 // function is called.  Prints its arguments on stdout separated by
 // spaces and ending with a newline.
-v8::Handle<v8::Value> Print(const v8::Arguments& args) {
+void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
   bool first = true;
   for (int i = 0; i < args.Length(); i++) {
     v8::HandleScope handle_scope(args.GetIsolate());
@@ -408,17 +408,17 @@
   }
   printf("\n");
   fflush(stdout);
-  return v8::Undefined();
 }
 
 
 // The callback that is invoked by v8 whenever the JavaScript 'read_line'
 // function is called. Reads a string from standard input and returns.
-v8::Handle<v8::Value> ReadLine(const v8::Arguments& args) {
+void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() > 0) {
-    return v8::ThrowException(v8::String::New("Unexpected arguments"));
+    v8::ThrowException(v8::String::New("Unexpected arguments"));
+    return;
   }
-  return ReadLine();
+  args.GetReturnValue().Set(ReadLine());
 }
 
 v8::Handle<v8::String> ReadLine() {
diff --git a/samples/process.cc b/samples/process.cc
index 1c1e7be..97eec14 100644
--- a/samples/process.cc
+++ b/samples/process.cc
@@ -102,18 +102,21 @@
   static Handle<ObjectTemplate> MakeMapTemplate(Isolate* isolate);
 
   // Callbacks that access the individual fields of request objects.
-  static Handle<Value> GetPath(Local<String> name, const AccessorInfo& info);
-  static Handle<Value> GetReferrer(Local<String> name,
-                                   const AccessorInfo& info);
-  static Handle<Value> GetHost(Local<String> name, const AccessorInfo& info);
-  static Handle<Value> GetUserAgent(Local<String> name,
-                                    const AccessorInfo& info);
+  static void GetPath(Local<String> name,
+                      const PropertyCallbackInfo<Value>& info);
+  static void GetReferrer(Local<String> name,
+                          const PropertyCallbackInfo<Value>& info);
+  static void GetHost(Local<String> name,
+                      const PropertyCallbackInfo<Value>& info);
+  static void GetUserAgent(Local<String> name,
+                           const PropertyCallbackInfo<Value>& info);
 
   // Callbacks that access maps
-  static Handle<Value> MapGet(Local<String> name, const AccessorInfo& info);
-  static Handle<Value> MapSet(Local<String> name,
-                              Local<Value> value,
-                              const AccessorInfo& info);
+  static void MapGet(Local<String> name,
+                     const PropertyCallbackInfo<Value>& info);
+  static void MapSet(Local<String> name,
+                     Local<Value> value,
+                     const PropertyCallbackInfo<Value>& info);
 
   // Utility methods for wrapping C++ objects as JavaScript objects,
   // and going back again.
@@ -137,13 +140,12 @@
 // -------------------------
 
 
-static Handle<Value> LogCallback(const Arguments& args) {
-  if (args.Length() < 1) return Undefined();
+static void LogCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (args.Length() < 1) return;
   HandleScope scope(args.GetIsolate());
   Handle<Value> arg = args[0];
   String::Utf8Value value(arg);
   HttpRequestProcessor::Log(*value);
-  return Undefined();
 }
 
 
@@ -350,8 +352,8 @@
 }
 
 
-Handle<Value> JsHttpRequestProcessor::MapGet(Local<String> name,
-                                             const AccessorInfo& info) {
+void JsHttpRequestProcessor::MapGet(Local<String> name,
+                                    const PropertyCallbackInfo<Value>& info) {
   // Fetch the map wrapped by this object.
   map<string, string>* obj = UnwrapMap(info.Holder());
 
@@ -362,17 +364,18 @@
   map<string, string>::iterator iter = obj->find(key);
 
   // If the key is not present return an empty handle as signal
-  if (iter == obj->end()) return Handle<Value>();
+  if (iter == obj->end()) return;
 
   // Otherwise fetch the value and wrap it in a JavaScript string
   const string& value = (*iter).second;
-  return String::New(value.c_str(), static_cast<int>(value.length()));
+  info.GetReturnValue().Set(
+      String::New(value.c_str(), static_cast<int>(value.length())));
 }
 
 
-Handle<Value> JsHttpRequestProcessor::MapSet(Local<String> name,
-                                             Local<Value> value_obj,
-                                             const AccessorInfo& info) {
+void JsHttpRequestProcessor::MapSet(Local<String> name,
+                                    Local<Value> value_obj,
+                                    const PropertyCallbackInfo<Value>& info) {
   // Fetch the map wrapped by this object.
   map<string, string>* obj = UnwrapMap(info.Holder());
 
@@ -384,7 +387,7 @@
   (*obj)[key] = value;
 
   // Return the value; any non-empty handle will work.
-  return value_obj;
+  info.GetReturnValue().Set(value_obj);
 }
 
 
@@ -451,8 +454,8 @@
 }
 
 
-Handle<Value> JsHttpRequestProcessor::GetPath(Local<String> name,
-                                              const AccessorInfo& info) {
+void JsHttpRequestProcessor::GetPath(Local<String> name,
+                                     const PropertyCallbackInfo<Value>& info) {
   // Extract the C++ request object from the JavaScript wrapper.
   HttpRequest* request = UnwrapRequest(info.Holder());
 
@@ -460,31 +463,37 @@
   const string& path = request->Path();
 
   // Wrap the result in a JavaScript string and return it.
-  return String::New(path.c_str(), static_cast<int>(path.length()));
+  info.GetReturnValue().Set(
+      String::New(path.c_str(), static_cast<int>(path.length())));
 }
 
 
-Handle<Value> JsHttpRequestProcessor::GetReferrer(Local<String> name,
-                                                  const AccessorInfo& info) {
+void JsHttpRequestProcessor::GetReferrer(
+    Local<String> name,
+    const PropertyCallbackInfo<Value>& info) {
   HttpRequest* request = UnwrapRequest(info.Holder());
   const string& path = request->Referrer();
-  return String::New(path.c_str(), static_cast<int>(path.length()));
+  info.GetReturnValue().Set(
+      String::New(path.c_str(), static_cast<int>(path.length())));
 }
 
 
-Handle<Value> JsHttpRequestProcessor::GetHost(Local<String> name,
-                                              const AccessorInfo& info) {
+void JsHttpRequestProcessor::GetHost(Local<String> name,
+                                     const PropertyCallbackInfo<Value>& info) {
   HttpRequest* request = UnwrapRequest(info.Holder());
   const string& path = request->Host();
-  return String::New(path.c_str(), static_cast<int>(path.length()));
+  info.GetReturnValue().Set(
+      String::New(path.c_str(), static_cast<int>(path.length())));
 }
 
 
-Handle<Value> JsHttpRequestProcessor::GetUserAgent(Local<String> name,
-                                                   const AccessorInfo& info) {
+void JsHttpRequestProcessor::GetUserAgent(
+    Local<String> name,
+    const PropertyCallbackInfo<Value>& info) {
   HttpRequest* request = UnwrapRequest(info.Holder());
   const string& path = request->UserAgent();
-  return String::New(path.c_str(), static_cast<int>(path.length()));
+  info.GetReturnValue().Set(
+      String::New(path.c_str(), static_cast<int>(path.length())));
 }
 
 
diff --git a/samples/shell.cc b/samples/shell.cc
index 430dd96..a0af931 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -53,11 +53,11 @@
                    v8::Handle<v8::Value> name,
                    bool print_result,
                    bool report_exceptions);
-v8::Handle<v8::Value> Print(const v8::Arguments& args);
-v8::Handle<v8::Value> Read(const v8::Arguments& args);
-v8::Handle<v8::Value> Load(const v8::Arguments& args);
-v8::Handle<v8::Value> Quit(const v8::Arguments& args);
-v8::Handle<v8::Value> Version(const v8::Arguments& args);
+void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
+void Read(const v8::FunctionCallbackInfo<v8::Value>& args);
+void Load(const v8::FunctionCallbackInfo<v8::Value>& args);
+void Quit(const v8::FunctionCallbackInfo<v8::Value>& args);
+void Version(const v8::FunctionCallbackInfo<v8::Value>& args);
 v8::Handle<v8::String> ReadFile(const char* name);
 void ReportException(v8::Isolate* isolate, v8::TryCatch* handler);
 
@@ -116,7 +116,7 @@
 // The callback that is invoked by v8 whenever the JavaScript 'print'
 // function is called.  Prints its arguments on stdout separated by
 // spaces and ending with a newline.
-v8::Handle<v8::Value> Print(const v8::Arguments& args) {
+void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
   bool first = true;
   for (int i = 0; i < args.Length(); i++) {
     v8::HandleScope handle_scope(args.GetIsolate());
@@ -131,70 +131,73 @@
   }
   printf("\n");
   fflush(stdout);
-  return v8::Undefined();
 }
 
 
 // The callback that is invoked by v8 whenever the JavaScript 'read'
 // function is called.  This function loads the content of the file named in
 // the argument into a JavaScript string.
-v8::Handle<v8::Value> Read(const v8::Arguments& args) {
+void Read(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
-    return v8::ThrowException(v8::String::New("Bad parameters"));
+    v8::ThrowException(v8::String::New("Bad parameters"));
+    return;
   }
   v8::String::Utf8Value file(args[0]);
   if (*file == NULL) {
-    return v8::ThrowException(v8::String::New("Error loading file"));
+    v8::ThrowException(v8::String::New("Error loading file"));
+    return;
   }
   v8::Handle<v8::String> source = ReadFile(*file);
   if (source.IsEmpty()) {
-    return v8::ThrowException(v8::String::New("Error loading file"));
+    v8::ThrowException(v8::String::New("Error loading file"));
+    return;
   }
-  return source;
+  args.GetReturnValue().Set(source);
 }
 
 
 // The callback that is invoked by v8 whenever the JavaScript 'load'
 // function is called.  Loads, compiles and executes its argument
 // JavaScript file.
-v8::Handle<v8::Value> Load(const v8::Arguments& args) {
+void Load(const v8::FunctionCallbackInfo<v8::Value>& args) {
   for (int i = 0; i < args.Length(); i++) {
     v8::HandleScope handle_scope(args.GetIsolate());
     v8::String::Utf8Value file(args[i]);
     if (*file == NULL) {
-      return v8::ThrowException(v8::String::New("Error loading file"));
+      v8::ThrowException(v8::String::New("Error loading file"));
+      return;
     }
     v8::Handle<v8::String> source = ReadFile(*file);
     if (source.IsEmpty()) {
-      return v8::ThrowException(v8::String::New("Error loading file"));
+      v8::ThrowException(v8::String::New("Error loading file"));
+      return;
     }
     if (!ExecuteString(args.GetIsolate(),
                        source,
                        v8::String::New(*file),
                        false,
                        false)) {
-      return v8::ThrowException(v8::String::New("Error executing file"));
+      v8::ThrowException(v8::String::New("Error executing file"));
+      return;
     }
   }
-  return v8::Undefined();
 }
 
 
 // The callback that is invoked by v8 whenever the JavaScript 'quit'
 // function is called.  Quits.
-v8::Handle<v8::Value> Quit(const v8::Arguments& args) {
+void Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
   // If not arguments are given args[0] will yield undefined which
   // converts to the integer value 0.
   int exit_code = args[0]->Int32Value();
   fflush(stdout);
   fflush(stderr);
   exit(exit_code);
-  return v8::Undefined();
 }
 
 
-v8::Handle<v8::Value> Version(const v8::Arguments& args) {
-  return v8::String::New(v8::V8::GetVersion());
+void Version(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  args.GetReturnValue().Set(v8::String::New(v8::V8::GetVersion()));
 }
 
 
diff --git a/src/accessors.cc b/src/accessors.cc
index 202a517..e441de4 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -793,9 +793,9 @@
 // Accessors::MakeModuleExport
 //
 
-static v8::Handle<v8::Value> ModuleGetExport(
+static void ModuleGetExport(
     v8::Local<v8::String> property,
-    const v8::AccessorInfo& info) {
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
   JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
   Context* context = Context::cast(instance->context());
   ASSERT(context->IsModuleContext());
@@ -807,16 +807,16 @@
     isolate->ScheduleThrow(
         *isolate->factory()->NewReferenceError("not_defined",
                                                HandleVector(&name, 1)));
-    return v8::Handle<v8::Value>();
+    return;
   }
-  return v8::Utils::ToLocal(Handle<Object>(value, isolate));
+  info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
 }
 
 
 static void ModuleSetExport(
     v8::Local<v8::String> property,
     v8::Local<v8::Value> value,
-    const v8::AccessorInfo& info) {
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
   JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
   Context* context = Context::cast(instance->context());
   ASSERT(context->IsModuleContext());
diff --git a/src/api.cc b/src/api.cc
index 7645a3f..b2dc2e1 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -886,7 +886,8 @@
   int length = this->length();
   int size = obj_.size();
   if (length == size - 1) {
-    i::Handle<i::FixedArray> new_elms = FACTORY->NewFixedArray(2 * size);
+    i::Factory* factory = i::Isolate::Current()->factory();
+    i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
     for (int i = 0; i < length; i++)
       new_elms->set(i + 1, get(i));
     obj_.value()->set_elements(*new_elms);
@@ -1213,7 +1214,7 @@
       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
   i::Handle<i::CallHandlerInfo> obj =
       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
-  InvocationCallback callback =
+  FunctionCallback callback =
       i::CallbackTable::Register(isolate, callback_in);
   SET_FIELD_WRAPPED(obj, set_callback, callback);
   if (data.IsEmpty()) data = v8::Undefined();
@@ -1261,9 +1262,11 @@
   i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
   i::Handle<i::ExecutableAccessorInfo> obj =
       isolate->factory()->NewExecutableAccessorInfo();
-  AccessorGetter getter = i::CallbackTable::Register(isolate, getter_in);
+  AccessorGetterCallback getter =
+      i::CallbackTable::Register(isolate, getter_in);
   SET_FIELD_WRAPPED(obj, set_getter, getter);
-  AccessorSetter setter = i::CallbackTable::Register(isolate, setter_in);
+  AccessorSetterCallback setter =
+      i::CallbackTable::Register(isolate, setter_in);
   SET_FIELD_WRAPPED(obj, set_setter, setter);
   if (data.IsEmpty()) data = v8::Undefined();
   obj->set_data(*Utils::OpenHandle(*data));
@@ -1366,16 +1369,19 @@
   i::Handle<i::InterceptorInfo> obj =
       i::Handle<i::InterceptorInfo>::cast(struct_obj);
 
-  NamedPropertyGetter getter = i::CallbackTable::Register(isolate, getter_in);
+  NamedPropertyGetterCallback getter =
+      i::CallbackTable::Register(isolate, getter_in);
   if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
-  NamedPropertySetter setter = i::CallbackTable::Register(isolate, setter_in);
+  NamedPropertySetterCallback setter =
+      i::CallbackTable::Register(isolate, setter_in);
   if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
-  NamedPropertyQuery query = i::CallbackTable::Register(isolate, query_in);
+  NamedPropertyQueryCallback query =
+      i::CallbackTable::Register(isolate, query_in);
   if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
-  NamedPropertyDeleter remover =
+  NamedPropertyDeleterCallback remover =
       i::CallbackTable::Register(isolate, remover_in);
   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
-  NamedPropertyEnumerator enumerator =
+  NamedPropertyEnumeratorCallback enumerator =
       i::CallbackTable::Register(isolate, enumerator_in);
   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
 
@@ -1411,18 +1417,19 @@
   i::Handle<i::InterceptorInfo> obj =
       i::Handle<i::InterceptorInfo>::cast(struct_obj);
 
-  IndexedPropertyGetter getter =
+  IndexedPropertyGetterCallback getter =
       i::CallbackTable::Register(isolate, getter_in);
   if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
-  IndexedPropertySetter setter =
+  IndexedPropertySetterCallback setter =
       i::CallbackTable::Register(isolate, setter_in);
   if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
-  IndexedPropertyQuery query = i::CallbackTable::Register(isolate, query_in);
+  IndexedPropertyQueryCallback query =
+      i::CallbackTable::Register(isolate, query_in);
   if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
-  IndexedPropertyDeleter remover =
+  IndexedPropertyDeleterCallback remover =
       i::CallbackTable::Register(isolate, remover_in);
   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
-  IndexedPropertyEnumerator enumerator =
+  IndexedPropertyEnumeratorCallback enumerator =
       i::CallbackTable::Register(isolate, enumerator_in);
   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
 
@@ -1448,7 +1455,7 @@
       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
   i::Handle<i::CallHandlerInfo> obj =
       i::Handle<i::CallHandlerInfo>::cast(struct_obj);
-  InvocationCallback callback =
+  FunctionCallback callback =
       i::CallbackTable::Register(isolate, callback_in);
   SET_FIELD_WRAPPED(obj, set_callback, callback);
   if (data.IsEmpty()) data = v8::Undefined();
@@ -3856,7 +3863,8 @@
   ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
-  i::Handle<i::String> key_string = FACTORY->InternalizeString(key_obj);
+  i::Handle<i::String> key_string =
+      isolate->factory()->InternalizeString(key_obj);
   i::Handle<i::Object> result(self->GetHiddenProperty(*key_string), isolate);
   if (result->IsUndefined()) return v8::Local<v8::Value>();
   return Utils::ToLocal(result);
@@ -3870,7 +3878,8 @@
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
-  i::Handle<i::String> key_string = FACTORY->InternalizeString(key_obj);
+  i::Handle<i::String> key_string =
+      isolate->factory()->InternalizeString(key_obj);
   self->DeleteHiddenProperty(*key_string);
   return true;
 }
@@ -5084,14 +5093,9 @@
     UNREACHABLE();
   }
   virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
-#ifdef V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS
-    visitor_->VisitPersistentHandle(ToApi<Value>(i::Handle<i::Object>(p)),
-                                    class_id);
-#else
     Value* value = ToApi<Value>(i::Handle<i::Object>(p));
     visitor_->VisitPersistentHandle(
         reinterpret_cast<Persistent<Value>*>(&value), class_id);
-#endif
   }
  private:
   PersistentHandleVisitor* visitor_;
@@ -5897,13 +5901,14 @@
 
 
 static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
+  i::Isolate* isolate = i::Isolate::Current();
   uint8_t flags_buf[3];
   int num_flags = 0;
   if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
   if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
   if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
   ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
-  return FACTORY->InternalizeOneByteString(
+  return isolate->factory()->InternalizeOneByteString(
       i::Vector<const uint8_t>(flags_buf, num_flags));
 }
 
diff --git a/src/api.h b/src/api.h
index 3d7e377..3c141f7 100644
--- a/src/api.h
+++ b/src/api.h
@@ -126,8 +126,9 @@
 
 template <typename T>
 inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) {
+  v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
   STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address));
-  return FACTORY->NewForeign(
+  return isolate->factory()->NewForeign(
       reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj)));
 }
 
diff --git a/src/arguments.h b/src/arguments.h
index a80b613..e13ddc9 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -152,8 +152,7 @@
 // TODO(dcarney): Remove this class when old callbacks are gone.
 class CallbackTable {
  public:
-  // TODO(dcarney): Flip this when it makes sense for performance.
-  static const bool kStoreVoidFunctions = true;
+  static const bool kStoreVoidFunctions = false;
   static inline bool ReturnsVoid(Isolate* isolate, void* function) {
     CallbackTable* table = isolate->callback_table();
     bool contains =
@@ -171,13 +170,13 @@
   }
 
 #define WRITE_REGISTER(OldFunction, NewFunction)                    \
-  static OldFunction Register(Isolate* isolate, NewFunction f) {    \
-    InsertCallback(isolate, FunctionToVoidPtr(f), true);            \
-    return reinterpret_cast<OldFunction>(f);                        \
+  static NewFunction Register(Isolate* isolate, OldFunction f) {    \
+    InsertCallback(isolate, FunctionToVoidPtr(f), false);           \
+    return reinterpret_cast<NewFunction>(f);                        \
   }                                                                 \
                                                                     \
-  static OldFunction Register(Isolate* isolate, OldFunction f) {    \
-    InsertCallback(isolate, FunctionToVoidPtr(f), false);           \
+  static NewFunction Register(Isolate* isolate, NewFunction f) {    \
+    InsertCallback(isolate, FunctionToVoidPtr(f), true);            \
     return f;                                                       \
   }
   FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_REGISTER)
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 6333924..4d7bc8e 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -480,15 +480,20 @@
 
   // Run the native code for the InternalArray function called as a normal
   // function.
-  ArrayNativeCode(masm, &generic_array_code);
+  if (FLAG_optimize_constructed_arrays) {
+    // tail call a stub
+    InternalArrayConstructorStub stub(masm->isolate());
+    __ TailCallStub(&stub);
+  } else {
+    ArrayNativeCode(masm, &generic_array_code);
 
-  // Jump to the generic array code if the specialized code cannot handle the
-  // construction.
-  __ bind(&generic_array_code);
-
-  Handle<Code> array_code =
-      masm->isolate()->builtins()->InternalArrayCodeGeneric();
-  __ Jump(array_code, RelocInfo::CODE_TARGET);
+    // Jump to the generic array code if the specialized code cannot handle the
+    // construction.
+    __ bind(&generic_array_code);
+    Handle<Code> array_code =
+        masm->isolate()->builtins()->InternalArrayCodeGeneric();
+    __ Jump(array_code, RelocInfo::CODE_TARGET);
+  }
 }
 
 
@@ -513,15 +518,24 @@
   }
 
   // Run the native code for the Array function called as a normal function.
-  ArrayNativeCode(masm, &generic_array_code);
+  if (FLAG_optimize_constructed_arrays) {
+    // tail call a stub
+    Handle<Object> undefined_sentinel(
+        masm->isolate()->heap()->undefined_value(),
+        masm->isolate());
+    __ mov(r2, Operand(undefined_sentinel));
+    ArrayConstructorStub stub(masm->isolate());
+    __ TailCallStub(&stub);
+  } else {
+    ArrayNativeCode(masm, &generic_array_code);
 
-  // Jump to the generic array code if the specialized code cannot handle
-  // the construction.
-  __ bind(&generic_array_code);
-
-  Handle<Code> array_code =
-      masm->isolate()->builtins()->ArrayCodeGeneric();
-  __ Jump(array_code, RelocInfo::CODE_TARGET);
+    // Jump to the generic array code if the specialized code cannot handle
+    // the construction.
+    __ bind(&generic_array_code);
+    Handle<Code> array_code =
+        masm->isolate()->builtins()->ArrayCodeGeneric();
+    __ Jump(array_code, RelocInfo::CODE_TARGET);
+  }
 }
 
 
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index c15ecb2..d5b4816 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -150,6 +150,28 @@
 }
 
 
+static void InitializeInternalArrayConstructorDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor,
+    int constant_stack_parameter_count) {
+  // register state
+  // r0 -- number of arguments
+  // r1 -- constructor function
+  static Register registers[] = { r1 };
+  descriptor->register_param_count_ = 1;
+
+  if (constant_stack_parameter_count != 0) {
+    // stack param count needs (constructor pointer, and single argument)
+    descriptor->stack_parameter_count_ = &r0;
+  }
+  descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
+  descriptor->register_params_ = registers;
+  descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
+  descriptor->deoptimization_handler_ =
+      FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
+}
+
+
 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -184,6 +206,27 @@
 }
 
 
+void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+}
+
+
+void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+}
+
+
+void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+}
+
+
 #define __ ACCESS_MASM(masm)
 
 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
@@ -658,7 +701,7 @@
   __ cmp(r0, r1);
   __ b(ne, &not_identical);
 
-  // Test for NaN. Sadly, we can't just compare to FACTORY->nan_value(),
+  // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
   // so we do the second best thing - test it ourselves.
   // They are both equal and they are not both Smis so both of them are not
   // Smis.  If it's not a heap number, then return equal.
@@ -2029,7 +2072,14 @@
 
 
 void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
-  Label not_smis, call_runtime;
+  Label right_arg_changed, call_runtime;
+
+  if (op_ == Token::MOD && has_fixed_right_arg_) {
+    // It is guaranteed that the value will fit into a Smi, because if it
+    // didn't, we wouldn't be here, see BinaryOp_Patch.
+    __ cmp(r0, Operand(Smi::FromInt(fixed_right_arg_value())));
+    __ b(ne, &right_arg_changed);
+  }
 
   if (result_type_ == BinaryOpIC::UNINITIALIZED ||
       result_type_ == BinaryOpIC::SMI) {
@@ -2046,6 +2096,7 @@
 
   // Code falls through if the result is not returned as either a smi or heap
   // number.
+  __ bind(&right_arg_changed);
   GenerateTypeTransition(masm);
 
   __ bind(&call_runtime);
@@ -2217,6 +2268,12 @@
         // to type transition.
 
       } else {
+        if (has_fixed_right_arg_) {
+          __ Vmov(d8, fixed_right_arg_value(), scratch1);
+          __ VFPCompareAndSetFlags(d1, d8);
+          __ b(ne, &transition);
+        }
+
         // We preserved r0 and r1 to be able to call runtime.
         // Save the left value on the stack.
         __ Push(r5, r4);
@@ -4731,7 +4788,11 @@
   __ b(ne, &slow);
 
   if (RecordCallTarget()) {
-    GenerateRecordCallTargetNoArray(masm);
+    if (FLAG_optimize_constructed_arrays) {
+      GenerateRecordCallTarget(masm);
+    } else {
+      GenerateRecordCallTargetNoArray(masm);
+    }
   }
 
   // Fast-case: Invoke the function now.
@@ -7230,6 +7291,10 @@
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
     T stub(kind);
     stub.GetCode(isolate)->set_is_pregenerated(true);
+    if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+      T stub1(kind, true);
+      stub1.GetCode(isolate)->set_is_pregenerated(true);
+    }
   }
 }
 
@@ -7244,6 +7309,21 @@
 }
 
 
+void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
+    Isolate* isolate) {
+  ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
+  for (int i = 0; i < 2; i++) {
+    // For internal arrays we only need a few things
+    InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
+    stubh1.GetCode(isolate)->set_is_pregenerated(true);
+    InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
+    stubh2.GetCode(isolate)->set_is_pregenerated(true);
+    InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
+    stubh3.GetCode(isolate)->set_is_pregenerated(true);
+  }
+}
+
+
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r0 : argc (only if argument_count_ == ANY)
@@ -7330,6 +7410,105 @@
 }
 
 
+void InternalArrayConstructorStub::GenerateCase(
+    MacroAssembler* masm, ElementsKind kind) {
+  Label not_zero_case, not_one_case;
+  Label normal_sequence;
+
+  __ tst(r0, r0);
+  __ b(ne, &not_zero_case);
+  InternalArrayNoArgumentConstructorStub stub0(kind);
+  __ TailCallStub(&stub0);
+
+  __ bind(&not_zero_case);
+  __ cmp(r0, Operand(1));
+  __ b(gt, &not_one_case);
+
+  if (IsFastPackedElementsKind(kind)) {
+    // We might need to create a holey array
+    // look at the first argument
+    __ ldr(r3, MemOperand(sp, 0));
+    __ cmp(r3, Operand::Zero());
+    __ b(eq, &normal_sequence);
+
+    InternalArraySingleArgumentConstructorStub
+        stub1_holey(GetHoleyElementsKind(kind));
+    __ TailCallStub(&stub1_holey);
+  }
+
+  __ bind(&normal_sequence);
+  InternalArraySingleArgumentConstructorStub stub1(kind);
+  __ TailCallStub(&stub1);
+
+  __ bind(&not_one_case);
+  InternalArrayNArgumentsConstructorStub stubN(kind);
+  __ TailCallStub(&stubN);
+}
+
+
+void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r0 : argc
+  //  -- r1 : constructor
+  //  -- sp[0] : return address
+  //  -- sp[4] : last argument
+  // -----------------------------------
+
+  if (FLAG_debug_code) {
+    // The array construct code is only set for the global and natives
+    // builtin Array functions which always have maps.
+
+    // Initial map for the builtin Array function should be a map.
+    __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
+    // Will both indicate a NULL and a Smi.
+    __ tst(r3, Operand(kSmiTagMask));
+    __ Assert(ne, "Unexpected initial map for Array function");
+    __ CompareObjectType(r3, r3, r4, MAP_TYPE);
+    __ Assert(eq, "Unexpected initial map for Array function");
+  }
+
+  if (FLAG_optimize_constructed_arrays) {
+    // Figure out the right elements kind
+    __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
+
+    // Load the map's "bit field 2" into |result|. We only need the first byte,
+    // but the following bit field extraction takes care of that anyway.
+    __ ldr(r3, FieldMemOperand(r3, Map::kBitField2Offset));
+    // Retrieve elements_kind from bit field 2.
+    __ ubfx(r3, r3, Map::kElementsKindShift, Map::kElementsKindBitCount);
+
+    if (FLAG_debug_code) {
+      Label done;
+      __ cmp(r3, Operand(FAST_ELEMENTS));
+      __ b(eq, &done);
+      __ cmp(r3, Operand(FAST_HOLEY_ELEMENTS));
+      __ Assert(eq,
+          "Invalid ElementsKind for InternalArray or InternalPackedArray");
+      __ bind(&done);
+    }
+
+    Label fast_elements_case;
+    __ cmp(r3, Operand(FAST_ELEMENTS));
+    __ b(eq, &fast_elements_case);
+    GenerateCase(masm, FAST_HOLEY_ELEMENTS);
+
+    __ bind(&fast_elements_case);
+    GenerateCase(masm, FAST_ELEMENTS);
+  } else {
+    Label generic_constructor;
+    // Run the native code for the Array function called as constructor.
+    ArrayNativeCode(masm, &generic_constructor);
+
+    // Jump to the generic construct code in case the specialized code cannot
+    // handle the construction.
+    __ bind(&generic_constructor);
+    Handle<Code> generic_construct_stub =
+        masm->isolate()->builtins()->JSConstructStubGeneric();
+    __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
+  }
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 2b04914..b9322b8 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -3013,7 +3013,7 @@
   // string "valueOf" the result is false.
   // The use of ip to store the valueOf string assumes that it is not otherwise
   // used in the loop below.
-  __ mov(ip, Operand(FACTORY->value_of_string()));
+  __ mov(ip, Operand(isolate()->factory()->value_of_string()));
   __ jmp(&entry);
   __ bind(&loop);
   __ ldr(r3, MemOperand(r4, 0));
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 14c4794..35a9e01 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -646,9 +646,6 @@
 }
 
 
-// Defined in ic.cc.
-Object* LoadIC_Miss(Arguments args);
-
 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- r2    : name
@@ -711,6 +708,21 @@
 }
 
 
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // ---------- S t a t e --------------
+  //  -- r2    : name
+  //  -- lr    : return address
+  //  -- r0    : receiver
+  //  -- sp[0] : receiver
+  // -----------------------------------
+
+  __ mov(r3, r0);
+  __ Push(r3, r2);
+
+  __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
+}
+
+
 static MemOperand GenerateMappedArgumentsLookup(MacroAssembler* masm,
                                                 Register object,
                                                 Register key,
@@ -878,9 +890,6 @@
 }
 
 
-Object* KeyedLoadIC_Miss(Arguments args);
-
-
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ---------- S t a t e --------------
   //  -- lr     : return address
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index c1f24c9..5463a9a 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -405,7 +405,14 @@
   } else {
     stream->Add("] <- ");
   }
-  value()->PrintTo(stream);
+
+  if (value() == NULL) {
+    ASSERT(hydrogen()->IsConstantHoleStore() &&
+           hydrogen()->value()->representation().IsDouble());
+    stream->Add("<the hole(nan)>");
+  } else {
+    value()->PrintTo(stream);
+  }
 }
 
 
@@ -698,6 +705,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
@@ -2388,14 +2401,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
-  info()->MarkAsDeferredCalling();
-  LAllocateObject* result =
-      new(zone()) LAllocateObject(TempRegister(), TempRegister());
-  return AssignPointerMap(DefineAsRegister(result));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* size = instr->size()->IsConstant()
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 6ae65e8..bec0463 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -49,7 +49,6 @@
 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V)    \
   V(AccessArgumentsAt)                          \
   V(AddI)                                       \
-  V(AllocateObject)                             \
   V(Allocate)                                   \
   V(ApplyArguments)                             \
   V(ArgumentsElements)                          \
@@ -2457,21 +2456,6 @@
 };
 
 
-class LAllocateObject: public LTemplateInstruction<1, 1, 2> {
- public:
-  LAllocateObject(LOperand* temp, LOperand* temp2) {
-    temps_[0] = temp;
-    temps_[1] = temp2;
-  }
-
-  LOperand* temp() { return temps_[0]; }
-  LOperand* temp2() { return temps_[1]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
-  DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
-};
-
-
 class LAllocate: public LTemplateInstruction<1, 2, 2> {
  public:
   LAllocate(LOperand* size, LOperand* temp1, LOperand* temp2) {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 2ef6951..d1be92f 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -4229,14 +4229,17 @@
   __ mov(r0, Operand(instr->arity()));
   __ mov(r2, Operand(instr->hydrogen()->property_cell()));
   ElementsKind kind = instr->hydrogen()->elements_kind();
+  bool disable_allocation_sites =
+      (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
+
   if (instr->arity() == 0) {
-    ArrayNoArgumentConstructorStub stub(kind);
+    ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else if (instr->arity() == 1) {
-    ArraySingleArgumentConstructorStub stub(kind);
+    ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else {
-    ArrayNArgumentsConstructorStub stub(kind);
+    ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   }
 }
@@ -5410,80 +5413,6 @@
 }
 
 
-void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
-  class DeferredAllocateObject: public LDeferredCode {
-   public:
-    DeferredAllocateObject(LCodeGen* codegen, LAllocateObject* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
-    virtual LInstruction* instr() { return instr_; }
-   private:
-    LAllocateObject* instr_;
-  };
-
-  DeferredAllocateObject* deferred =
-      new(zone()) DeferredAllocateObject(this, instr);
-
-  Register result = ToRegister(instr->result());
-  Register scratch = ToRegister(instr->temp());
-  Register scratch2 = ToRegister(instr->temp2());
-  Handle<JSFunction> constructor = instr->hydrogen()->constructor();
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-  ASSERT(initial_map->pre_allocated_property_fields() +
-         initial_map->unused_property_fields() -
-         initial_map->inobject_properties() == 0);
-
-  __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(),
-              TAG_OBJECT);
-
-  __ bind(deferred->exit());
-  if (FLAG_debug_code) {
-    Label is_in_new_space;
-    __ JumpIfInNewSpace(result, scratch, &is_in_new_space);
-    __ Abort("Allocated object is not in new-space");
-    __ bind(&is_in_new_space);
-  }
-
-  // Load the initial map.
-  Register map = scratch;
-  __ LoadHeapObject(map, constructor);
-  __ ldr(map, FieldMemOperand(map, JSFunction::kPrototypeOrInitialMapOffset));
-
-  // Initialize map and fields of the newly allocated object.
-  ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
-  __ str(map, FieldMemOperand(result, JSObject::kMapOffset));
-  __ LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
-  __ str(scratch, FieldMemOperand(result, JSObject::kElementsOffset));
-  __ str(scratch, FieldMemOperand(result, JSObject::kPropertiesOffset));
-  if (initial_map->inobject_properties() != 0) {
-    __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
-    for (int i = 0; i < initial_map->inobject_properties(); i++) {
-      int property_offset = JSObject::kHeaderSize + i * kPointerSize;
-      __ str(scratch, FieldMemOperand(result, property_offset));
-    }
-  }
-}
-
-
-void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
-  Register result = ToRegister(instr->result());
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-
-  // TODO(3095996): Get rid of this. For now, we need to make the
-  // result register contain a valid pointer because it is already
-  // contained in the register pointer map.
-  __ mov(result, Operand::Zero());
-
-  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
-  __ mov(r0, Operand(Smi::FromInt(instance_size)));
-  __ push(r0);
-  CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
-  __ StoreToSafepointRegisterSlot(r0, result);
-}
-
-
 void LCodeGen::DoAllocate(LAllocate* instr) {
   class DeferredAllocate: public LDeferredCode {
    public:
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index f282847..c7ccdfb 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -157,7 +157,6 @@
   void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
-  void DoDeferredAllocateObject(LAllocateObject* instr);
   void DoDeferredAllocate(LAllocate* instr);
   void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                                        Label* map_check);
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index da7afee..4241502 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -917,9 +917,8 @@
 
   CodeDesc code_desc;
   masm_->GetCode(&code_desc);
-  Handle<Code> code = FACTORY->NewCode(code_desc,
-                                       Code::ComputeFlags(Code::REGEXP),
-                                       masm_->CodeObject());
+  Handle<Code> code = isolate()->factory()->NewCode(
+      code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject());
   PROFILE(Isolate::Current(), RegExpCodeCreateEvent(*code, *source));
   return Handle<HeapObject>::cast(code);
 }
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 912caed..39300e3 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -3091,151 +3091,6 @@
 }
 
 
-Handle<Code> ConstructStubCompiler::CompileConstructStub(
-    Handle<JSFunction> function) {
-  // ----------- S t a t e -------------
-  //  -- r0    : argc
-  //  -- r1    : constructor
-  //  -- lr    : return address
-  //  -- [sp]  : last argument
-  // -----------------------------------
-  Label generic_stub_call;
-
-  // Use r7 for holding undefined which is used in several places below.
-  __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
-  // Check to see whether there are any break points in the function code. If
-  // there are jump to the generic constructor stub which calls the actual
-  // code for the function thereby hitting the break points.
-  __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
-  __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kDebugInfoOffset));
-  __ cmp(r2, r7);
-  __ b(ne, &generic_stub_call);
-#endif
-
-  // Load the initial map and verify that it is in fact a map.
-  // r1: constructor function
-  // r7: undefined
-  __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
-  __ JumpIfSmi(r2, &generic_stub_call);
-  __ CompareObjectType(r2, r3, r4, MAP_TYPE);
-  __ b(ne, &generic_stub_call);
-
-#ifdef DEBUG
-  // Cannot construct functions this way.
-  // r0: argc
-  // r1: constructor function
-  // r2: initial map
-  // r7: undefined
-  __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE);
-  __ Check(ne, "Function constructed by construct stub.");
-#endif
-
-  // Now allocate the JSObject in new space.
-  // r0: argc
-  // r1: constructor function
-  // r2: initial map
-  // r7: undefined
-  ASSERT(function->has_initial_map());
-  __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
-#ifdef DEBUG
-  int instance_size = function->initial_map()->instance_size();
-  __ cmp(r3, Operand(instance_size >> kPointerSizeLog2));
-  __ Check(eq, "Instance size of initial map changed.");
-#endif
-  __ Allocate(r3, r4, r5, r6, &generic_stub_call, SIZE_IN_WORDS);
-
-  // Allocated the JSObject, now initialize the fields. Map is set to initial
-  // map and properties and elements are set to empty fixed array.
-  // r0: argc
-  // r1: constructor function
-  // r2: initial map
-  // r3: object size (in words)
-  // r4: JSObject (not tagged)
-  // r7: undefined
-  __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
-  __ mov(r5, r4);
-  ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
-  __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
-  ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
-  __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
-  ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
-  __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
-
-  // Calculate the location of the first argument. The stack contains only the
-  // argc arguments.
-  __ add(r1, sp, Operand(r0, LSL, kPointerSizeLog2));
-
-  // Fill all the in-object properties with undefined.
-  // r0: argc
-  // r1: first argument
-  // r3: object size (in words)
-  // r4: JSObject (not tagged)
-  // r5: First in-object property of JSObject (not tagged)
-  // r7: undefined
-  // Fill the initialized properties with a constant value or a passed argument
-  // depending on the this.x = ...; assignment in the function.
-  Handle<SharedFunctionInfo> shared(function->shared());
-  for (int i = 0; i < shared->this_property_assignments_count(); i++) {
-    if (shared->IsThisPropertyAssignmentArgument(i)) {
-      Label not_passed, next;
-      // Check if the argument assigned to the property is actually passed.
-      int arg_number = shared->GetThisPropertyAssignmentArgument(i);
-      __ cmp(r0, Operand(arg_number));
-      __ b(le, &not_passed);
-      // Argument passed - find it on the stack.
-      __ ldr(r2, MemOperand(r1, (arg_number + 1) * -kPointerSize));
-      __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
-      __ b(&next);
-      __ bind(&not_passed);
-      // Set the property to undefined.
-      __ str(r7, MemOperand(r5, kPointerSize, PostIndex));
-      __ bind(&next);
-    } else {
-      // Set the property to the constant value.
-      Handle<Object> constant(shared->GetThisPropertyAssignmentConstant(i),
-                              isolate());
-      __ mov(r2, Operand(constant));
-      __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
-    }
-  }
-
-  // Fill the unused in-object property fields with undefined.
-  for (int i = shared->this_property_assignments_count();
-       i < function->initial_map()->inobject_properties();
-       i++) {
-      __ str(r7, MemOperand(r5, kPointerSize, PostIndex));
-  }
-
-  // r0: argc
-  // r4: JSObject (not tagged)
-  // Move argc to r1 and the JSObject to return to r0 and tag it.
-  __ mov(r1, r0);
-  __ mov(r0, r4);
-  __ orr(r0, r0, Operand(kHeapObjectTag));
-
-  // r0: JSObject
-  // r1: argc
-  // Remove caller arguments and receiver from the stack and return.
-  __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2));
-  __ add(sp, sp, Operand(kPointerSize));
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->constructed_objects(), 1, r1, r2);
-  __ IncrementCounter(counters->constructed_objects_stub(), 1, r1, r2);
-  __ Jump(lr);
-
-  // Jump to the generic stub in case the specialized code cannot handle the
-  // construction.
-  __ bind(&generic_stub_call);
-  Handle<Code> code = isolate()->builtins()->JSConstructStubGeneric();
-  __ Jump(code, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode();
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/src/assert-scope.h b/src/assert-scope.h
index d32d680..e2ec542 100644
--- a/src/assert-scope.h
+++ b/src/assert-scope.h
@@ -48,7 +48,7 @@
 #ifdef DEBUG
 class PerThreadAssertData {
  public:
-  PerThreadAssertData() {
+  PerThreadAssertData() : nesting_level_(0) {
     for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
       assert_states_[i] = true;
     }
@@ -62,8 +62,12 @@
     return assert_states_[type];
   }
 
+  void increment_level() { ++nesting_level_; }
+  bool decrement_level() { return --nesting_level_ == 0; }
+
  private:
   bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE];
+  int nesting_level_;
 
   DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData);
 };
@@ -72,7 +76,22 @@
 
 class PerThreadAssertScopeBase {
 #ifdef DEBUG
+
  protected:
+  PerThreadAssertScopeBase() {
+    data_ = AssertData();
+    data_->increment_level();
+  }
+
+  ~PerThreadAssertScopeBase() {
+    if (!data_->decrement_level()) return;
+    for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
+      ASSERT(data_->get(static_cast<PerThreadAssertType>(i)));
+    }
+    delete data_;
+    Thread::SetThreadLocal(thread_local_key, NULL);
+  }
+
   static PerThreadAssertData* AssertData() {
     PerThreadAssertData* data = reinterpret_cast<PerThreadAssertData*>(
             Thread::GetThreadLocal(thread_local_key));
@@ -84,6 +103,7 @@
   }
 
   static Thread::LocalStorageKey thread_local_key;
+  PerThreadAssertData* data_;
   friend class Isolate;
 #endif  // DEBUG
 };
@@ -98,12 +118,11 @@
   static void SetIsAllowed(bool is_allowed) { }
 #else
   PerThreadAssertScope() {
-    PerThreadAssertData* data = AssertData();
-    old_state_ = data->get(type);
-    data->set(type, allow);
+    old_state_ = data_->get(type);
+    data_->set(type, allow);
   }
 
-  ~PerThreadAssertScope() { AssertData()->set(type, old_state_); }
+  ~PerThreadAssertScope() { data_->set(type, old_state_); }
 
   static bool IsAllowed() { return AssertData()->get(type); }
 
diff --git a/src/ast.cc b/src/ast.cc
index e27feec..8c0351c 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -682,7 +682,8 @@
 
 
 void BinaryOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
-  oracle->BinaryType(this, &left_type_, &right_type_, &result_type_);
+  oracle->BinaryType(this, &left_type_, &right_type_, &result_type_,
+                     &has_fixed_right_arg_, &fixed_right_arg_value_);
 }
 
 
@@ -1183,6 +1184,7 @@
 
 Handle<String> Literal::ToString() {
   if (handle_->IsString()) return Handle<String>::cast(handle_);
+  Factory* factory = Isolate::Current()->factory();
   ASSERT(handle_->IsNumber());
   char arr[100];
   Vector<char> buffer(arr, ARRAY_SIZE(arr));
@@ -1194,7 +1196,7 @@
   } else {
     str = DoubleToCString(handle_->Number(), buffer);
   }
-  return FACTORY->NewStringFromAscii(CStrVector(str));
+  return factory->NewStringFromAscii(CStrVector(str));
 }
 
 
diff --git a/src/ast.h b/src/ast.h
index 4e851f2..41c910a 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1799,6 +1799,8 @@
   TypeInfo left_type() const { return left_type_; }
   TypeInfo right_type() const { return right_type_; }
   TypeInfo result_type() const { return result_type_; }
+  bool has_fixed_right_arg() const { return has_fixed_right_arg_; }
+  int fixed_right_arg_value() const { return fixed_right_arg_value_; }
 
  protected:
   BinaryOperation(Isolate* isolate,
@@ -1824,6 +1826,8 @@
   TypeInfo left_type_;
   TypeInfo right_type_;
   TypeInfo result_type_;
+  bool has_fixed_right_arg_;
+  int fixed_right_arg_value_;
 
   // The short-circuit logical operations need an AST ID for their
   // right-hand subexpression.
@@ -2157,12 +2161,6 @@
   int materialized_literal_count() { return materialized_literal_count_; }
   int expected_property_count() { return expected_property_count_; }
   int handler_count() { return handler_count_; }
-  bool has_only_simple_this_property_assignments() {
-    return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
-  }
-  Handle<FixedArray> this_property_assignments() {
-      return this_property_assignments_;
-  }
   int parameter_count() { return parameter_count_; }
 
   bool AllowsLazyCompilation();
@@ -2217,8 +2215,6 @@
                   int materialized_literal_count,
                   int expected_property_count,
                   int handler_count,
-                  bool has_only_simple_this_property_assignments,
-                  Handle<FixedArray> this_property_assignments,
                   int parameter_count,
                   Type type,
                   ParameterFlag has_duplicate_parameters,
@@ -2229,7 +2225,6 @@
         name_(name),
         scope_(scope),
         body_(body),
-        this_property_assignments_(this_property_assignments),
         inferred_name_(isolate->factory()->empty_string()),
         materialized_literal_count_(materialized_literal_count),
         expected_property_count_(expected_property_count),
@@ -2237,8 +2232,6 @@
         parameter_count_(parameter_count),
         function_token_position_(RelocInfo::kNoPosition) {
     bitfield_ =
-        HasOnlySimpleThisPropertyAssignments::encode(
-            has_only_simple_this_property_assignments) |
         IsExpression::encode(type != DECLARATION) |
         IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
         Pretenure::encode(false) |
@@ -2252,7 +2245,6 @@
   Handle<String> name_;
   Scope* scope_;
   ZoneList<Statement*>* body_;
-  Handle<FixedArray> this_property_assignments_;
   Handle<String> inferred_name_;
   AstProperties ast_properties_;
 
@@ -2263,14 +2255,13 @@
   int function_token_position_;
 
   unsigned bitfield_;
-  class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1> {};
-  class IsExpression: public BitField<bool, 1, 1> {};
-  class IsAnonymous: public BitField<bool, 2, 1> {};
-  class Pretenure: public BitField<bool, 3, 1> {};
-  class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
-  class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
-  class IsParenthesized: public BitField<IsParenthesizedFlag, 6, 1> {};
-  class IsGenerator: public BitField<IsGeneratorFlag, 7, 1> {};
+  class IsExpression: public BitField<bool, 0, 1> {};
+  class IsAnonymous: public BitField<bool, 1, 1> {};
+  class Pretenure: public BitField<bool, 2, 1> {};
+  class HasDuplicateParameters: public BitField<ParameterFlag, 3, 1> {};
+  class IsFunction: public BitField<IsFunctionFlag, 4, 1> {};
+  class IsParenthesized: public BitField<IsParenthesizedFlag, 5, 1> {};
+  class IsGenerator: public BitField<IsGeneratorFlag, 6, 1> {};
 };
 
 
@@ -3093,8 +3084,6 @@
       int materialized_literal_count,
       int expected_property_count,
       int handler_count,
-      bool has_only_simple_this_property_assignments,
-      Handle<FixedArray> this_property_assignments,
       int parameter_count,
       FunctionLiteral::ParameterFlag has_duplicate_parameters,
       FunctionLiteral::Type type,
@@ -3104,7 +3093,6 @@
     FunctionLiteral* lit = new(zone_) FunctionLiteral(
         isolate_, name, scope, body,
         materialized_literal_count, expected_property_count, handler_count,
-        has_only_simple_this_property_assignments, this_property_assignments,
         parameter_count, type, has_duplicate_parameters, is_function,
         is_parenthesized, is_generator);
     // Top-level literal doesn't count for the AST's properties.
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 9277719..5ef8d30 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1576,6 +1576,11 @@
   }
   if (FLAG_harmony_observation) {
     INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
+    INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice);
+    INSTALL_NATIVE(JSFunction, "BeginPerformSplice",
+                   observers_begin_perform_splice);
+    INSTALL_NATIVE(JSFunction, "EndPerformSplice",
+                   observers_end_perform_splice);
     INSTALL_NATIVE(JSFunction, "DeliverChangeRecords",
                    observers_deliver_changes);
   }
@@ -1606,8 +1611,14 @@
       factory()->NewJSObject(isolate()->object_function(), TENURED);
   SetPrototype(array_function, prototype);
 
-  array_function->shared()->set_construct_stub(
-      isolate()->builtins()->builtin(Builtins::kCommonArrayConstructCode));
+  if (FLAG_optimize_constructed_arrays) {
+    InternalArrayConstructorStub internal_array_constructor_stub(isolate());
+    Handle<Code> code = internal_array_constructor_stub.GetCode(isolate());
+    array_function->shared()->set_construct_stub(*code);
+  } else {
+    array_function->shared()->set_construct_stub(
+        isolate()->builtins()->builtin(Builtins::kCommonArrayConstructCode));
+  }
 
   array_function->shared()->DontAdaptArguments();
 
@@ -2126,7 +2137,8 @@
 #undef F
   ;
 
-  Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
+  Handle<FixedArray> caches =
+      factory()->NewFixedArray(kNumberOfCaches, TENURED);
 
   int index = 0;
 
@@ -2145,7 +2157,7 @@
 
 void Genesis::InitializeNormalizedMapCaches() {
   Handle<FixedArray> array(
-      FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
+      factory()->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
   native_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
 }
 
@@ -2505,14 +2517,13 @@
   // Cloning the elements array is sufficient.
   Handle<FixedArray> from_elements =
       Handle<FixedArray>(FixedArray::cast(from->elements()));
-  Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
+  Handle<FixedArray> to_elements = factory()->CopyFixedArray(from_elements);
   to->set_elements(*to_elements);
 }
 
 
 void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) {
   HandleScope outer(isolate());
-  Factory* factory = isolate()->factory();
 
   ASSERT(!from->IsJSArray());
   ASSERT(!to->IsJSArray());
@@ -2522,7 +2533,7 @@
 
   // Transfer the prototype (new map is needed).
   Handle<Map> old_to_map = Handle<Map>(to->map());
-  Handle<Map> new_to_map = factory->CopyMap(old_to_map);
+  Handle<Map> new_to_map = factory()->CopyMap(old_to_map);
   new_to_map->set_prototype(from->map()->prototype());
   to->set_map(*new_to_map);
 }
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index 476ac12..3097800 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -65,13 +65,14 @@
   }
 
   void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) {
-    HandleScope scope(shared->GetIsolate());
+    Isolate* isolate = shared->GetIsolate();
+    Factory* factory = isolate->factory();
+    HandleScope scope(isolate);
     int length = cache_->length();
-    Handle<FixedArray> new_array =
-        FACTORY->NewFixedArray(length + 2, TENURED);
+    Handle<FixedArray> new_array = factory->NewFixedArray(length + 2, TENURED);
     cache_->CopyTo(0, *new_array, 0, cache_->length());
     cache_ = *new_array;
-    Handle<String> str = FACTORY->NewStringFromAscii(name, TENURED);
+    Handle<String> str = factory->NewStringFromAscii(name, TENURED);
     cache_->set(length, *str);
     cache_->set(length + 1, *shared);
     Script::cast(shared->script())->set_type(Smi::FromInt(type_));
diff --git a/src/builtins-decls.h b/src/builtins-decls.h
index beb5dd1..8c038dc 100644
--- a/src/builtins-decls.h
+++ b/src/builtins-decls.h
@@ -33,7 +33,9 @@
 namespace v8 {
 namespace internal {
 
+// TODO(mvstanton): move these to runtime.h/.cc
 DECLARE_RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure);
+DECLARE_RUNTIME_FUNCTION(MaybeObject*, InternalArrayConstructor_StubFailure);
 
 } }  // namespace v8::internal
 
diff --git a/src/builtins.cc b/src/builtins.cc
index 37ba1e5..b42fd5a 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -194,20 +194,11 @@
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure) {
-  // If we get 2 arguments then they are the stub parameters (constructor, type
-  // info).  If we get 3, then the first one is a pointer to the arguments
-  // passed by the caller.
-  Arguments empty_args(0, NULL);
-  bool no_caller_args = args.length() == 2;
-  ASSERT(no_caller_args || args.length() == 3);
-  int parameters_start = no_caller_args ? 0 : 1;
-  Arguments* caller_args = no_caller_args
-      ? &empty_args
-      : reinterpret_cast<Arguments*>(args[0]);
-  Handle<JSFunction> constructor = args.at<JSFunction>(parameters_start);
-  Handle<Object> type_info = args.at<Object>(parameters_start + 1);
-
+static MaybeObject* ArrayConstructorStubFailureCommon(
+    Isolate* isolate,
+    Handle<JSFunction> constructor,
+    Handle<Object> type_info,
+    Arguments* caller_args) {
   bool holey = false;
   if (caller_args->length() == 1 && (*caller_args)[0]->IsSmi()) {
     int value = Smi::cast((*caller_args)[0])->value();
@@ -216,7 +207,8 @@
 
   JSArray* array;
   MaybeObject* maybe_array;
-  if (*type_info != isolate->heap()->undefined_value() &&
+  if (!type_info.is_null() &&
+      *type_info != isolate->heap()->undefined_value() &&
       JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi()) {
     JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
     Smi* smi = Smi::cast(cell->value());
@@ -231,12 +223,11 @@
         *constructor, type_info);
     if (!maybe_array->To(&array)) return maybe_array;
   } else {
-    ElementsKind kind = constructor->initial_map()->elements_kind();
-    ASSERT(kind == GetInitialFastElementsKind());
     maybe_array = isolate->heap()->AllocateJSObject(*constructor);
     if (!maybe_array->To(&array)) return maybe_array;
     // We might need to transition to holey
-    if (holey) {
+    ElementsKind kind = constructor->initial_map()->elements_kind();
+    if (holey && !IsFastHoleyElementsKind(kind)) {
       kind = GetHoleyElementsKind(kind);
       maybe_array = array->TransitionElementsKind(kind);
       if (maybe_array->IsFailure()) return maybe_array;
@@ -252,6 +243,44 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure) {
+  // If we get 2 arguments then they are the stub parameters (constructor, type
+  // info).  If we get 3, then the first one is a pointer to the arguments
+  // passed by the caller.
+  Arguments empty_args(0, NULL);
+  bool no_caller_args = args.length() == 2;
+  ASSERT(no_caller_args || args.length() == 3);
+  int parameters_start = no_caller_args ? 0 : 1;
+  Arguments* caller_args = no_caller_args
+      ? &empty_args
+      : reinterpret_cast<Arguments*>(args[0]);
+  Handle<JSFunction> constructor = args.at<JSFunction>(parameters_start);
+  Handle<Object> type_info = args.at<Object>(parameters_start + 1);
+
+  return ArrayConstructorStubFailureCommon(isolate,
+                                           constructor,
+                                           type_info,
+                                           caller_args);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, InternalArrayConstructor_StubFailure) {
+  Arguments empty_args(0, NULL);
+  bool no_caller_args = args.length() == 1;
+  ASSERT(no_caller_args || args.length() == 2);
+  int parameters_start = no_caller_args ? 0 : 1;
+  Arguments* caller_args = no_caller_args
+      ? &empty_args
+      : reinterpret_cast<Arguments*>(args[0]);
+  Handle<JSFunction> constructor = args.at<JSFunction>(parameters_start);
+
+  return ArrayConstructorStubFailureCommon(isolate,
+                                           constructor,
+                                           Handle<Object>::null(),
+                                           caller_args);
+}
+
+
 static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
                                            Isolate* isolate,
                                            JSFunction* constructor) {
@@ -1466,6 +1495,11 @@
 }
 
 
+static void Generate_LoadIC_Slow(MacroAssembler* masm) {
+  LoadIC::GenerateRuntimeGetProperty(masm);
+}
+
+
 static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
   KeyedLoadIC::GenerateInitialize(masm);
 }
diff --git a/src/builtins.h b/src/builtins.h
index 58d1a8b..c45fbfd 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -144,6 +144,8 @@
                                     Code::kNoExtraICState)              \
   V(LoadIC_Getter_ForDeopt,         LOAD_IC, MONOMORPHIC,               \
                                     Code::kNoExtraICState)              \
+  V(LoadIC_Slow,                    LOAD_IC, GENERIC,                   \
+                                    Code::kNoExtraICState)              \
                                                                         \
   V(KeyedLoadIC_Initialize,         KEYED_LOAD_IC, UNINITIALIZED,       \
                                     Code::kNoExtraICState)              \
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 4ec8654..4be21c3 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -99,7 +99,23 @@
     IfBuilder checker_;
   };
 
+  enum ArgumentClass {
+    NONE,
+    SINGLE,
+    MULTIPLE
+  };
+
+  HValue* BuildArrayConstructor(ElementsKind kind,
+                                bool disable_allocation_sites,
+                                ArgumentClass argument_class);
+  HValue* BuildInternalArrayConstructor(ElementsKind kind,
+                                        ArgumentClass argument_class);
+
  private:
+  HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
+  HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
+                                          ElementsKind kind);
+
   SmartArrayPointer<HParameter*> parameters_;
   HValue* arguments_length_;
   CompilationInfoWithZone info_;
@@ -520,40 +536,56 @@
   return DoGenerateCode(this);
 }
 
-
-template <>
-HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
-  // ----------- S t a t e -------------
-  //  -- Parameter 1 : type info cell
-  //  -- Parameter 0 : constructor
-  // -----------------------------------
+HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
+    ElementsKind kind, bool disable_allocation_sites,
+    ArgumentClass argument_class) {
+  HValue* constructor = GetParameter(ArrayConstructorStubBase::kConstructor);
+  HValue* property_cell = GetParameter(ArrayConstructorStubBase::kPropertyCell);
   HInstruction* array_function = BuildGetArrayFunction(context());
-  ArrayContextChecker(this,
-                      GetParameter(ArrayConstructorStubBase::kConstructor),
-                      array_function);
-  // Get the right map
-  // Should be a constant
-  JSArrayBuilder array_builder(
-      this,
-      casted_stub()->elements_kind(),
-      GetParameter(ArrayConstructorStubBase::kPropertyCell),
-      casted_stub()->mode());
-  return array_builder.AllocateEmptyArray();
+
+  ArrayContextChecker(this, constructor, array_function);
+  JSArrayBuilder array_builder(this, kind, property_cell,
+                               disable_allocation_sites);
+  HValue* result = NULL;
+  switch (argument_class) {
+    case NONE:
+      result = array_builder.AllocateEmptyArray();
+      break;
+    case SINGLE:
+      result = BuildArraySingleArgumentConstructor(&array_builder);
+      break;
+    case MULTIPLE:
+      result = BuildArrayNArgumentsConstructor(&array_builder, kind);
+      break;
+  }
+  return result;
 }
 
 
-Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
-  return DoGenerateCode(this);
+HValue* CodeStubGraphBuilderBase::BuildInternalArrayConstructor(
+    ElementsKind kind, ArgumentClass argument_class) {
+  HValue* constructor = GetParameter(
+      InternalArrayConstructorStubBase::kConstructor);
+  JSArrayBuilder array_builder(this, kind, constructor);
+
+  HValue* result = NULL;
+  switch (argument_class) {
+    case NONE:
+      result = array_builder.AllocateEmptyArray();
+      break;
+    case SINGLE:
+      result = BuildArraySingleArgumentConstructor(&array_builder);
+      break;
+    case MULTIPLE:
+      result = BuildArrayNArgumentsConstructor(&array_builder, kind);
+      break;
+  }
+  return result;
 }
 
 
-template <>
-HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
-    BuildCodeStub() {
-  HInstruction* array_function = BuildGetArrayFunction(context());
-  ArrayContextChecker(this,
-                      GetParameter(ArrayConstructorStubBase::kConstructor),
-                      array_function);
+HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
+    JSArrayBuilder* array_builder) {
   // Smi check and range check on the input arg.
   HValue* constant_one = graph()->GetConstant1();
   HValue* constant_zero = graph()->GetConstant0();
@@ -584,46 +616,23 @@
   // Figure out total size
   HValue* length = Pop();
   HValue* capacity = Pop();
-
-  JSArrayBuilder array_builder(
-      this,
-      casted_stub()->elements_kind(),
-      GetParameter(ArrayConstructorStubBase::kPropertyCell),
-      casted_stub()->mode());
-  return array_builder.AllocateArray(capacity, length, true);
+  return array_builder->AllocateArray(capacity, length, true);
 }
 
 
-Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
-  return DoGenerateCode(this);
-}
-
-
-template <>
-HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
-  HInstruction* array_function = BuildGetArrayFunction(context());
-  ArrayContextChecker(this,
-                      GetParameter(ArrayConstructorStubBase::kConstructor),
-                      array_function);
-  ElementsKind kind = casted_stub()->elements_kind();
-  HValue* length = GetArgumentsLength();
-
-  JSArrayBuilder array_builder(
-      this,
-      kind,
-      GetParameter(ArrayConstructorStubBase::kPropertyCell),
-      casted_stub()->mode());
-
+HValue* CodeStubGraphBuilderBase::BuildArrayNArgumentsConstructor(
+    JSArrayBuilder* array_builder, ElementsKind kind) {
   // We need to fill with the hole if it's a smi array in the multi-argument
   // case because we might have to bail out while copying arguments into
   // the array because they aren't compatible with a smi array.
   // If it's a double array, no problem, and if it's fast then no
   // problem either because doubles are boxed.
+  HValue* length = GetArgumentsLength();
   bool fill_with_hole = IsFastSmiElementsKind(kind);
-  HValue* new_object = array_builder.AllocateArray(length,
-                                                   length,
-                                                   fill_with_hole);
-  HValue* elements = array_builder.GetElementsLocation();
+  HValue* new_object = array_builder->AllocateArray(length,
+                                                    length,
+                                                    fill_with_hole);
+  HValue* elements = array_builder->GetElementsLocation();
   ASSERT(elements != NULL);
 
   // Now populate the elements correctly.
@@ -643,12 +652,86 @@
 }
 
 
+template <>
+HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
+  ElementsKind kind = casted_stub()->elements_kind();
+  bool disable_allocation_sites = casted_stub()->disable_allocation_sites();
+  return BuildArrayConstructor(kind, disable_allocation_sites, NONE);
+}
+
+
+Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
+HValue* CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::
+    BuildCodeStub() {
+  ElementsKind kind = casted_stub()->elements_kind();
+  bool disable_allocation_sites = casted_stub()->disable_allocation_sites();
+  return BuildArrayConstructor(kind, disable_allocation_sites, SINGLE);
+}
+
+
+Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
+HValue* CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() {
+  ElementsKind kind = casted_stub()->elements_kind();
+  bool disable_allocation_sites = casted_stub()->disable_allocation_sites();
+  return BuildArrayConstructor(kind, disable_allocation_sites, MULTIPLE);
+}
+
+
 Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() {
   return DoGenerateCode(this);
 }
 
 
 template <>
+HValue* CodeStubGraphBuilder<InternalArrayNoArgumentConstructorStub>::
+    BuildCodeStub() {
+  ElementsKind kind = casted_stub()->elements_kind();
+  return BuildInternalArrayConstructor(kind, NONE);
+}
+
+
+Handle<Code> InternalArrayNoArgumentConstructorStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
+HValue* CodeStubGraphBuilder<InternalArraySingleArgumentConstructorStub>::
+    BuildCodeStub() {
+  ElementsKind kind = casted_stub()->elements_kind();
+  return BuildInternalArrayConstructor(kind, SINGLE);
+}
+
+
+Handle<Code> InternalArraySingleArgumentConstructorStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
+HValue* CodeStubGraphBuilder<InternalArrayNArgumentsConstructorStub>::
+    BuildCodeStub() {
+  ElementsKind kind = casted_stub()->elements_kind();
+  return BuildInternalArrayConstructor(kind, MULTIPLE);
+}
+
+
+Handle<Code> InternalArrayNArgumentsConstructorStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
   CompareNilICStub* stub = casted_stub();
   HIfContinuation continuation;
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 882d743..4c6ee86 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -777,4 +777,19 @@
 }
 
 
+void InternalArrayConstructorStubBase::InstallDescriptors(Isolate* isolate) {
+  InternalArrayNoArgumentConstructorStub stub1(FAST_ELEMENTS);
+  InstallDescriptor(isolate, &stub1);
+  InternalArraySingleArgumentConstructorStub stub2(FAST_ELEMENTS);
+  InstallDescriptor(isolate, &stub2);
+  InternalArrayNArgumentsConstructorStub stub3(FAST_ELEMENTS);
+  InstallDescriptor(isolate, &stub3);
+}
+
+InternalArrayConstructorStub::InternalArrayConstructorStub(
+    Isolate* isolate) {
+  InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 513ad9a..ad1f09b 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -77,6 +77,9 @@
   V(ArrayNoArgumentConstructor)          \
   V(ArraySingleArgumentConstructor)      \
   V(ArrayNArgumentsConstructor)          \
+  V(InternalArrayNoArgumentConstructor)  \
+  V(InternalArraySingleArgumentConstructor)      \
+  V(InternalArrayNArgumentsConstructor)  \
   V(KeyedStoreElement)                   \
   V(DebuggerStatement)                   \
   V(NameDictionaryLookup)                \
@@ -85,6 +88,7 @@
   V(StoreArrayLiteralElement)            \
   V(StubFailureTrampoline)               \
   V(ArrayConstructor)                    \
+  V(InternalArrayConstructor)            \
   V(ProfileEntryHook)                    \
   /* IC Handler stubs */                 \
   V(LoadField)                           \
@@ -670,6 +674,20 @@
 };
 
 
+class InternalArrayConstructorStub: public PlatformCodeStub {
+ public:
+  explicit InternalArrayConstructorStub(Isolate* isolate);
+
+  void Generate(MacroAssembler* masm);
+
+ private:
+  virtual CodeStub::Major MajorKey() { return InternalArrayConstructor; }
+  virtual int MinorKey() { return 0; }
+
+  void GenerateCase(MacroAssembler* masm, ElementsKind kind);
+};
+
+
 class MathPowStub: public PlatformCodeStub {
  public:
   enum ExponentType { INTEGER, DOUBLE, TAGGED, ON_STACK };
@@ -885,7 +903,9 @@
         platform_specific_bit_(false),
         left_type_(BinaryOpIC::UNINITIALIZED),
         right_type_(BinaryOpIC::UNINITIALIZED),
-        result_type_(BinaryOpIC::UNINITIALIZED) {
+        result_type_(BinaryOpIC::UNINITIALIZED),
+        has_fixed_right_arg_(false),
+        encoded_right_arg_(encode_arg_value(1)) {
     Initialize();
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
@@ -894,13 +914,17 @@
       int key,
       BinaryOpIC::TypeInfo left_type,
       BinaryOpIC::TypeInfo right_type,
-      BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED)
+      BinaryOpIC::TypeInfo result_type,
+      bool has_fixed_right_arg,
+      int32_t fixed_right_arg_value)
       : op_(OpBits::decode(key)),
         mode_(ModeBits::decode(key)),
         platform_specific_bit_(PlatformSpecificBits::decode(key)),
         left_type_(left_type),
         right_type_(right_type),
-        result_type_(result_type) { }
+        result_type_(result_type),
+        has_fixed_right_arg_(has_fixed_right_arg),
+        encoded_right_arg_(encode_arg_value(fixed_right_arg_value)) { }
 
   static void decode_types_from_minor_key(int minor_key,
                                           BinaryOpIC::TypeInfo* left_type,
@@ -918,6 +942,24 @@
     return static_cast<Token::Value>(OpBits::decode(minor_key));
   }
 
+  static bool decode_has_fixed_right_arg_from_minor_key(int minor_key) {
+    return HasFixedRightArgBits::decode(minor_key);
+  }
+
+  static int decode_fixed_right_arg_value_from_minor_key(int minor_key) {
+    return decode_arg_value(FixedRightArgValueBits::decode(minor_key));
+  }
+
+  int fixed_right_arg_value() const {
+    return decode_arg_value(encoded_right_arg_);
+  }
+
+  static bool can_encode_arg_value(int32_t value) {
+    return value > 0 &&
+        IsPowerOf2(value) &&
+        FixedRightArgValueBits::is_valid(WhichPowerOf2(value));
+  }
+
   enum SmiCodeGenerateHeapNumberResults {
     ALLOW_HEAPNUMBER_RESULTS,
     NO_HEAPNUMBER_RESULTS
@@ -933,15 +975,31 @@
   BinaryOpIC::TypeInfo right_type_;
   BinaryOpIC::TypeInfo result_type_;
 
+  bool has_fixed_right_arg_;
+  int encoded_right_arg_;
+
+  static int encode_arg_value(int32_t value) {
+    ASSERT(can_encode_arg_value(value));
+    return WhichPowerOf2(value);
+  }
+
+  static int32_t decode_arg_value(int value) {
+    return 1 << value;
+  }
+
   virtual void PrintName(StringStream* stream);
 
-  // Minor key encoding in 19 bits TTTRRRLLLSOOOOOOOMM.
+  // Minor key encoding in all 25 bits FFFFFHTTTRRRLLLPOOOOOOOMM.
+  // Note: We actually do not need 7 bits for the operation, just 4 bits to
+  // encode ADD, SUB, MUL, DIV, MOD, BIT_OR, BIT_AND, BIT_XOR, SAR, SHL, SHR.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
   class OpBits: public BitField<Token::Value, 2, 7> {};
   class PlatformSpecificBits: public BitField<bool, 9, 1> {};
   class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
   class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
   class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {};
+  class HasFixedRightArgBits: public BitField<bool, 19, 1> {};
+  class FixedRightArgValueBits: public BitField<int, 20, 5> {};
 
   Major MajorKey() { return BinaryOp; }
   int MinorKey() {
@@ -950,7 +1008,9 @@
            | PlatformSpecificBits::encode(platform_specific_bit_)
            | LeftTypeBits::encode(left_type_)
            | RightTypeBits::encode(right_type_)
-           | ResultTypeBits::encode(result_type_);
+           | ResultTypeBits::encode(result_type_)
+           | HasFixedRightArgBits::encode(has_fixed_right_arg_)
+           | FixedRightArgValueBits::encode(encoded_right_arg_);
   }
 
 
@@ -1684,19 +1744,22 @@
 
 class ArrayConstructorStubBase : public HydrogenCodeStub {
  public:
-  ArrayConstructorStubBase(ElementsKind kind, AllocationSiteMode mode) {
+  ArrayConstructorStubBase(ElementsKind kind, bool disable_allocation_sites) {
+    // It only makes sense to override local allocation site behavior
+    // if there is a difference between the global allocation site policy
+    // for an ElementsKind and the desired usage of the stub.
+    ASSERT(!disable_allocation_sites ||
+           AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
     bit_field_ = ElementsKindBits::encode(kind) |
-        AllocationSiteModeBits::encode(mode == TRACK_ALLOCATION_SITE);
+        DisableAllocationSitesBits::encode(disable_allocation_sites);
   }
 
   ElementsKind elements_kind() const {
     return ElementsKindBits::decode(bit_field_);
   }
 
-  AllocationSiteMode mode() const {
-    return AllocationSiteModeBits::decode(bit_field_)
-        ? TRACK_ALLOCATION_SITE
-        : DONT_TRACK_ALLOCATION_SITE;
+  bool disable_allocation_sites() const {
+    return DisableAllocationSitesBits::decode(bit_field_);
   }
 
   virtual bool IsPregenerated() { return true; }
@@ -1711,7 +1774,7 @@
   int NotMissMinorKey() { return bit_field_; }
 
   class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
-  class AllocationSiteModeBits: public BitField<bool, 8, 1> {};
+  class DisableAllocationSitesBits: public BitField<bool, 8, 1> {};
   uint32_t bit_field_;
 
   DISALLOW_COPY_AND_ASSIGN(ArrayConstructorStubBase);
@@ -1722,8 +1785,8 @@
  public:
   ArrayNoArgumentConstructorStub(
       ElementsKind kind,
-      AllocationSiteMode mode = TRACK_ALLOCATION_SITE)
-      : ArrayConstructorStubBase(kind, mode) {
+      bool disable_allocation_sites = false)
+      : ArrayConstructorStubBase(kind, disable_allocation_sites) {
   }
 
   virtual Handle<Code> GenerateCode();
@@ -1743,8 +1806,8 @@
  public:
   ArraySingleArgumentConstructorStub(
       ElementsKind kind,
-      AllocationSiteMode mode = TRACK_ALLOCATION_SITE)
-      : ArrayConstructorStubBase(kind, mode) {
+      bool disable_allocation_sites = false)
+      : ArrayConstructorStubBase(kind, disable_allocation_sites) {
   }
 
   virtual Handle<Code> GenerateCode();
@@ -1764,8 +1827,8 @@
  public:
   ArrayNArgumentsConstructorStub(
       ElementsKind kind,
-      AllocationSiteMode mode = TRACK_ALLOCATION_SITE) :
-    ArrayConstructorStubBase(kind, mode) {
+      bool disable_allocation_sites = false)
+      : ArrayConstructorStubBase(kind, disable_allocation_sites) {
   }
 
   virtual Handle<Code> GenerateCode();
@@ -1781,6 +1844,87 @@
 };
 
 
+class InternalArrayConstructorStubBase : public HydrogenCodeStub {
+ public:
+  explicit InternalArrayConstructorStubBase(ElementsKind kind) {
+    kind_ = kind;
+  }
+
+  virtual bool IsPregenerated() { return true; }
+  static void GenerateStubsAheadOfTime(Isolate* isolate);
+  static void InstallDescriptors(Isolate* isolate);
+
+  // Parameters accessed via CodeStubGraphBuilder::GetParameter()
+  static const int kConstructor = 0;
+
+  ElementsKind elements_kind() const { return kind_; }
+
+ private:
+  int NotMissMinorKey() { return kind_; }
+
+  ElementsKind kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(InternalArrayConstructorStubBase);
+};
+
+
+class InternalArrayNoArgumentConstructorStub : public
+    InternalArrayConstructorStubBase {
+ public:
+  explicit InternalArrayNoArgumentConstructorStub(ElementsKind kind)
+      : InternalArrayConstructorStubBase(kind) { }
+
+  virtual Handle<Code> GenerateCode();
+
+  virtual void InitializeInterfaceDescriptor(
+      Isolate* isolate,
+      CodeStubInterfaceDescriptor* descriptor);
+
+ private:
+  Major MajorKey() { return InternalArrayNoArgumentConstructor; }
+
+  DISALLOW_COPY_AND_ASSIGN(InternalArrayNoArgumentConstructorStub);
+};
+
+
+class InternalArraySingleArgumentConstructorStub : public
+    InternalArrayConstructorStubBase {
+ public:
+  explicit InternalArraySingleArgumentConstructorStub(ElementsKind kind)
+      : InternalArrayConstructorStubBase(kind) { }
+
+  virtual Handle<Code> GenerateCode();
+
+  virtual void InitializeInterfaceDescriptor(
+      Isolate* isolate,
+      CodeStubInterfaceDescriptor* descriptor);
+
+ private:
+  Major MajorKey() { return InternalArraySingleArgumentConstructor; }
+
+  DISALLOW_COPY_AND_ASSIGN(InternalArraySingleArgumentConstructorStub);
+};
+
+
+class InternalArrayNArgumentsConstructorStub : public
+    InternalArrayConstructorStubBase {
+ public:
+  explicit InternalArrayNArgumentsConstructorStub(ElementsKind kind)
+      : InternalArrayConstructorStubBase(kind) { }
+
+  virtual Handle<Code> GenerateCode();
+
+  virtual void InitializeInterfaceDescriptor(
+      Isolate* isolate,
+      CodeStubInterfaceDescriptor* descriptor);
+
+ private:
+  Major MajorKey() { return InternalArrayNArgumentsConstructor; }
+
+  DISALLOW_COPY_AND_ASSIGN(InternalArrayNArgumentsConstructorStub);
+};
+
+
 class KeyedStoreElementStub : public PlatformCodeStub {
  public:
   KeyedStoreElementStub(bool is_js_array,
diff --git a/src/compiler.cc b/src/compiler.cc
index 9983b3d..5320fc9 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -649,7 +649,7 @@
     // in that case too.
 
     // Create a script object describing the script to be compiled.
-    Handle<Script> script = FACTORY->NewScript(source);
+    Handle<Script> script = isolate->factory()->NewScript(source);
     if (natives == NATIVES_CODE) {
       script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
     }
@@ -771,13 +771,6 @@
   int expected = lit->expected_property_count();
   SetExpectedNofPropertiesFromEstimate(shared, expected);
 
-  // Set the optimization hints after performing lazy compilation, as
-  // these are not set when the function is set up as a lazily
-  // compiled function.
-  shared->SetThisPropertyAssignmentsInfo(
-      lit->has_only_simple_this_property_assignments(),
-      *lit->this_property_assignments());
-
   // Check the function has compiled code.
   ASSERT(shared->is_compiled());
   shared->set_code_age(0);
@@ -1054,6 +1047,7 @@
   info.SetLanguageMode(literal->scope()->language_mode());
 
   Isolate* isolate = info.isolate();
+  Factory* factory = isolate->factory();
   LiveEditFunctionTracker live_edit_tracker(isolate, literal);
   // Determine if the function can be lazily compiled. This is necessary to
   // allow some of our builtin JS files to be lazily compiled. These
@@ -1083,7 +1077,7 @@
 
   // Create a shared function info object.
   Handle<SharedFunctionInfo> result =
-      FACTORY->NewSharedFunctionInfo(literal->name(),
+      factory->NewSharedFunctionInfo(literal->name(),
                                      literal->materialized_literal_count(),
                                      literal->is_generator(),
                                      info.code(),
@@ -1120,9 +1114,6 @@
   function_info->set_is_anonymous(lit->is_anonymous());
   function_info->set_is_toplevel(is_toplevel);
   function_info->set_inferred_name(*lit->inferred_name());
-  function_info->SetThisPropertyAssignmentsInfo(
-      lit->has_only_simple_this_property_assignments(),
-      *lit->this_property_assignments());
   function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
   function_info->set_allows_lazy_compilation_without_context(
       lit->AllowsLazyCompilationWithoutContext());
diff --git a/src/contexts.h b/src/contexts.h
index 86406e5..f04ccd1 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -172,6 +172,11 @@
   V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap) \
   V(PROXY_ENUMERATE_INDEX, JSFunction, proxy_enumerate) \
   V(OBSERVERS_NOTIFY_CHANGE_INDEX, JSFunction, observers_notify_change) \
+  V(OBSERVERS_ENQUEUE_SPLICE_INDEX, JSFunction, observers_enqueue_splice) \
+  V(OBSERVERS_BEGIN_SPLICE_INDEX, JSFunction, \
+    observers_begin_perform_splice) \
+  V(OBSERVERS_END_SPLICE_INDEX, JSFunction, \
+    observers_end_perform_splice) \
   V(OBSERVERS_DELIVER_CHANGES_INDEX, JSFunction, observers_deliver_changes) \
   V(GENERATOR_FUNCTION_MAP_INDEX, Map, generator_function_map) \
   V(STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX, Map, \
@@ -317,6 +322,9 @@
     DERIVED_SET_TRAP_INDEX,
     PROXY_ENUMERATE_INDEX,
     OBSERVERS_NOTIFY_CHANGE_INDEX,
+    OBSERVERS_ENQUEUE_SPLICE_INDEX,
+    OBSERVERS_BEGIN_SPLICE_INDEX,
+    OBSERVERS_END_SPLICE_INDEX,
     OBSERVERS_DELIVER_CHANGES_INDEX,
     GENERATOR_FUNCTION_MAP_INDEX,
     STRICT_MODE_GENERATOR_FUNCTION_MAP_INDEX,
diff --git a/src/d8-posix.cc b/src/d8-posix.cc
index 1be782a..424dbbb 100644
--- a/src/d8-posix.cc
+++ b/src/d8-posix.cc
@@ -238,7 +238,7 @@
 
 
 // Gets the optional timeouts from the arguments to the system() call.
-static bool GetTimeouts(const Arguments& args,
+static bool GetTimeouts(const v8::FunctionCallbackInfo<v8::Value>& args,
                         int* read_timeout,
                         int* total_timeout) {
   if (args.Length() > 3) {
@@ -448,25 +448,28 @@
 
 
 // Implementation of the system() function (see d8.h for details).
-Handle<Value> Shell::System(const Arguments& args) {
+void Shell::System(const v8::FunctionCallbackInfo<v8::Value>& args) {
   HandleScope scope(args.GetIsolate());
   int read_timeout = -1;
   int total_timeout = -1;
-  if (!GetTimeouts(args, &read_timeout, &total_timeout)) return v8::Undefined();
+  if (!GetTimeouts(args, &read_timeout, &total_timeout)) return;
   Handle<Array> command_args;
   if (args.Length() > 1) {
     if (!args[1]->IsArray()) {
-      return ThrowException(String::New("system: Argument 2 must be an array"));
+      ThrowException(String::New("system: Argument 2 must be an array"));
+      return;
     }
     command_args = Handle<Array>::Cast(args[1]);
   } else {
     command_args = Array::New(0);
   }
   if (command_args->Length() > ExecArgs::kMaxArgs) {
-    return ThrowException(String::New("Too many arguments to system()"));
+    ThrowException(String::New("Too many arguments to system()"));
+    return;
   }
   if (args.Length() < 1) {
-    return ThrowException(String::New("Too few arguments to system()"));
+    ThrowException(String::New("Too few arguments to system()"));
+    return;
   }
 
   struct timeval start_time;
@@ -474,16 +477,18 @@
 
   ExecArgs exec_args;
   if (!exec_args.Init(args[0], command_args)) {
-    return v8::Undefined();
+    return;
   }
   int exec_error_fds[2];
   int stdout_fds[2];
 
   if (pipe(exec_error_fds) != 0) {
-    return ThrowException(String::New("pipe syscall failed."));
+    ThrowException(String::New("pipe syscall failed."));
+    return;
   }
   if (pipe(stdout_fds) != 0) {
-    return ThrowException(String::New("pipe syscall failed."));
+    ThrowException(String::New("pipe syscall failed."));
+    return;
   }
 
   pid_t pid = fork();
@@ -499,7 +504,7 @@
   OpenFDCloser error_read_closer(exec_error_fds[kReadFD]);
   OpenFDCloser stdout_read_closer(stdout_fds[kReadFD]);
 
-  if (!ChildLaunchedOK(exec_error_fds)) return v8::Undefined();
+  if (!ChildLaunchedOK(exec_error_fds)) return;
 
   Handle<Value> accumulator = GetStdout(stdout_fds[kReadFD],
                                         start_time,
@@ -507,7 +512,8 @@
                                         total_timeout);
   if (accumulator->IsUndefined()) {
     kill(pid, SIGINT);  // On timeout, kill the subprocess.
-    return accumulator;
+    args.GetReturnValue().Set(accumulator);
+    return;
   }
 
   if (!WaitForChild(pid,
@@ -515,42 +521,47 @@
                     start_time,
                     read_timeout,
                     total_timeout)) {
-    return v8::Undefined();
+    return;
   }
 
-  return scope.Close(accumulator);
+  args.GetReturnValue().Set(accumulator);
 }
 
 
-Handle<Value> Shell::ChangeDirectory(const Arguments& args) {
+void Shell::ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "chdir() takes one argument";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   String::Utf8Value directory(args[0]);
   if (*directory == NULL) {
     const char* message = "os.chdir(): String conversion of argument failed.";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   if (chdir(*directory) != 0) {
-    return ThrowException(String::New(strerror(errno)));
+    ThrowException(String::New(strerror(errno)));
+    return;
   }
-  return v8::Undefined();
 }
 
 
-Handle<Value> Shell::SetUMask(const Arguments& args) {
+void Shell::SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "umask() takes one argument";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   if (args[0]->IsNumber()) {
     mode_t mask = args[0]->Int32Value();
     int previous = umask(mask);
-    return Number::New(previous);
+    args.GetReturnValue().Set(previous);
+    return;
   } else {
     const char* message = "umask() argument must be numeric";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
 }
 
@@ -598,79 +609,85 @@
 }
 
 
-Handle<Value> Shell::MakeDirectory(const Arguments& args) {
+void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
   mode_t mask = 0777;
   if (args.Length() == 2) {
     if (args[1]->IsNumber()) {
       mask = args[1]->Int32Value();
     } else {
       const char* message = "mkdirp() second argument must be numeric";
-      return ThrowException(String::New(message));
+      ThrowException(String::New(message));
+      return;
     }
   } else if (args.Length() != 1) {
     const char* message = "mkdirp() takes one or two arguments";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   String::Utf8Value directory(args[0]);
   if (*directory == NULL) {
     const char* message = "os.mkdirp(): String conversion of argument failed.";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   mkdirp(*directory, mask);
-  return v8::Undefined();
 }
 
 
-Handle<Value> Shell::RemoveDirectory(const Arguments& args) {
+void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "rmdir() takes one or two arguments";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   String::Utf8Value directory(args[0]);
   if (*directory == NULL) {
     const char* message = "os.rmdir(): String conversion of argument failed.";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   rmdir(*directory);
-  return v8::Undefined();
 }
 
 
-Handle<Value> Shell::SetEnvironment(const Arguments& args) {
+void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 2) {
     const char* message = "setenv() takes two arguments";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   String::Utf8Value var(args[0]);
   String::Utf8Value value(args[1]);
   if (*var == NULL) {
     const char* message =
         "os.setenv(): String conversion of variable name failed.";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   if (*value == NULL) {
     const char* message =
         "os.setenv(): String conversion of variable contents failed.";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   setenv(*var, *value, 1);
-  return v8::Undefined();
 }
 
 
-Handle<Value> Shell::UnsetEnvironment(const Arguments& args) {
+void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1) {
     const char* message = "unsetenv() takes one argument";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   String::Utf8Value var(args[0]);
   if (*var == NULL) {
     const char* message =
         "os.setenv(): String conversion of variable name failed.";
-    return ThrowException(String::New(message));
+    ThrowException(String::New(message));
+    return;
   }
   unsetenv(*var);
-  return v8::Undefined();
 }
 
 
diff --git a/src/d8.cc b/src/d8.cc
index 79244d7..57e0c04 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -287,46 +287,49 @@
 
 
 // Realm.current() returns the index of the currently active realm.
-Handle<Value> Shell::RealmCurrent(const Arguments& args) {
+void Shell::RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = args.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
   int index = data->RealmFind(Context::GetEntered());
-  if (index == -1) return Undefined(isolate);
-  return Number::New(index);
+  if (index == -1) return;
+  args.GetReturnValue().Set(index);
 }
 
 
 // Realm.owner(o) returns the index of the realm that created o.
-Handle<Value> Shell::RealmOwner(const Arguments& args) {
+void Shell::RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = args.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
   if (args.Length() < 1 || !args[0]->IsObject()) {
-    return Throw("Invalid argument");
+    Throw("Invalid argument");
+    return;
   }
   int index = data->RealmFind(args[0]->ToObject()->CreationContext());
-  if (index == -1) return Undefined(isolate);
-  return Number::New(index);
+  if (index == -1) return;
+  args.GetReturnValue().Set(index);
 }
 
 
 // Realm.global(i) returns the global object of realm i.
 // (Note that properties of global objects cannot be read/written cross-realm.)
-Handle<Value> Shell::RealmGlobal(const Arguments& args) {
+void Shell::RealmGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
   PerIsolateData* data = PerIsolateData::Get(args.GetIsolate());
   if (args.Length() < 1 || !args[0]->IsNumber()) {
-    return Throw("Invalid argument");
+    Throw("Invalid argument");
+    return;
   }
   int index = args[0]->Uint32Value();
   if (index >= data->realm_count_ || data->realms_[index].IsEmpty()) {
-    return Throw("Invalid realm index");
+    Throw("Invalid realm index");
+    return;
   }
-  return
-      Local<Context>::New(args.GetIsolate(), data->realms_[index])->Global();
+  args.GetReturnValue().Set(
+      Local<Context>::New(args.GetIsolate(), data->realms_[index])->Global());
 }
 
 
 // Realm.create() creates a new realm and returns its index.
-Handle<Value> Shell::RealmCreate(const Arguments& args) {
+void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = args.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
   Persistent<Context>* old_realms = data->realms_;
@@ -339,78 +342,82 @@
   Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
   data->realms_[index].Reset(
       isolate, Context::New(isolate, NULL, global_template));
-  return Number::New(index);
+  args.GetReturnValue().Set(index);
 }
 
 
 // Realm.dispose(i) disposes the reference to the realm i.
-Handle<Value> Shell::RealmDispose(const Arguments& args) {
+void Shell::RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = args.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
   if (args.Length() < 1 || !args[0]->IsNumber()) {
-    return Throw("Invalid argument");
+    Throw("Invalid argument");
+    return;
   }
   int index = args[0]->Uint32Value();
   if (index >= data->realm_count_ || data->realms_[index].IsEmpty() ||
       index == 0 ||
       index == data->realm_current_ || index == data->realm_switch_) {
-    return Throw("Invalid realm index");
+    Throw("Invalid realm index");
+    return;
   }
   data->realms_[index].Dispose(isolate);
   data->realms_[index].Clear();
-  return Undefined(isolate);
 }
 
 
 // Realm.switch(i) switches to the realm i for consecutive interactive inputs.
-Handle<Value> Shell::RealmSwitch(const Arguments& args) {
+void Shell::RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = args.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
   if (args.Length() < 1 || !args[0]->IsNumber()) {
-    return Throw("Invalid argument");
+    Throw("Invalid argument");
+    return;
   }
   int index = args[0]->Uint32Value();
   if (index >= data->realm_count_ || data->realms_[index].IsEmpty()) {
-    return Throw("Invalid realm index");
+    Throw("Invalid realm index");
+    return;
   }
   data->realm_switch_ = index;
-  return Undefined(isolate);
 }
 
 
 // Realm.eval(i, s) evaluates s in realm i and returns the result.
-Handle<Value> Shell::RealmEval(const Arguments& args) {
+void Shell::RealmEval(const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = args.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
   if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsString()) {
-    return Throw("Invalid argument");
+    Throw("Invalid argument");
+    return;
   }
   int index = args[0]->Uint32Value();
   if (index >= data->realm_count_ || data->realms_[index].IsEmpty()) {
-    return Throw("Invalid realm index");
+    Throw("Invalid realm index");
+    return;
   }
   Handle<Script> script = Script::New(args[1]->ToString());
-  if (script.IsEmpty()) return Undefined(isolate);
+  if (script.IsEmpty()) return;
   Local<Context> realm = Local<Context>::New(isolate, data->realms_[index]);
   realm->Enter();
   Handle<Value> result = script->Run();
   realm->Exit();
-  return result;
+  args.GetReturnValue().Set(result);
 }
 
 
 // Realm.shared is an accessor for a single shared value across realms.
-Handle<Value> Shell::RealmSharedGet(Local<String> property,
-                                    const AccessorInfo& info) {
+void Shell::RealmSharedGet(Local<String> property,
+                           const PropertyCallbackInfo<Value>& info) {
   Isolate* isolate = info.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
-  if (data->realm_shared_.IsEmpty()) return Undefined(isolate);
-  return Local<Value>::New(isolate, data->realm_shared_);
+  if (data->realm_shared_.IsEmpty()) return;
+  info.GetReturnValue().Set(data->realm_shared_);
 }
 
 void Shell::RealmSharedSet(Local<String> property,
                            Local<Value> value,
-                           const AccessorInfo& info) {
+                           const PropertyCallbackInfo<void>& info) {
   Isolate* isolate = info.GetIsolate();
   PerIsolateData* data = PerIsolateData::Get(isolate);
   if (!data->realm_shared_.IsEmpty()) data->realm_shared_.Dispose(isolate);
@@ -418,15 +425,14 @@
 }
 
 
-Handle<Value> Shell::Print(const Arguments& args) {
-  Handle<Value> val = Write(args);
+void Shell::Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  Write(args);
   printf("\n");
   fflush(stdout);
-  return val;
 }
 
 
-Handle<Value> Shell::Write(const Arguments& args) {
+void Shell::Write(const v8::FunctionCallbackInfo<v8::Value>& args) {
   for (int i = 0; i < args.Length(); i++) {
     HandleScope handle_scope(args.GetIsolate());
     if (i != 0) {
@@ -436,7 +442,10 @@
     // Explicitly catch potential exceptions in toString().
     v8::TryCatch try_catch;
     Handle<String> str_obj = args[i]->ToString();
-    if (try_catch.HasCaught()) return try_catch.ReThrow();
+    if (try_catch.HasCaught()) {
+      try_catch.ReThrow();
+      return;
+    }
 
     v8::String::Utf8Value str(str_obj);
     int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
@@ -445,32 +454,31 @@
       Exit(1);
     }
   }
-  return Undefined(args.GetIsolate());
 }
 
 
-Handle<Value> Shell::EnableProfiler(const Arguments& args) {
+void Shell::EnableProfiler(const v8::FunctionCallbackInfo<v8::Value>& args) {
   V8::ResumeProfiler();
-  return Undefined(args.GetIsolate());
 }
 
 
-Handle<Value> Shell::DisableProfiler(const Arguments& args) {
+void Shell::DisableProfiler(const v8::FunctionCallbackInfo<v8::Value>& args) {
   V8::PauseProfiler();
-  return Undefined(args.GetIsolate());
 }
 
 
-Handle<Value> Shell::Read(const Arguments& args) {
+void Shell::Read(const v8::FunctionCallbackInfo<v8::Value>& args) {
   String::Utf8Value file(args[0]);
   if (*file == NULL) {
-    return Throw("Error loading file");
+    Throw("Error loading file");
+    return;
   }
   Handle<String> source = ReadFile(args.GetIsolate(), *file);
   if (source.IsEmpty()) {
-    return Throw("Error loading file");
+    Throw("Error loading file");
+    return;
   }
-  return source;
+  args.GetReturnValue().Set(source);
 }
 
 
@@ -504,39 +512,40 @@
 }
 
 
-Handle<Value> Shell::Load(const Arguments& args) {
+void Shell::Load(const v8::FunctionCallbackInfo<v8::Value>& args) {
   for (int i = 0; i < args.Length(); i++) {
     HandleScope handle_scope(args.GetIsolate());
     String::Utf8Value file(args[i]);
     if (*file == NULL) {
-      return Throw("Error loading file");
+      Throw("Error loading file");
+      return;
     }
     Handle<String> source = ReadFile(args.GetIsolate(), *file);
     if (source.IsEmpty()) {
-      return Throw("Error loading file");
+      Throw("Error loading file");
+      return;
     }
     if (!ExecuteString(args.GetIsolate(),
                        source,
                        String::New(*file),
                        false,
                        true)) {
-      return Throw("Error executing file");
+      Throw("Error executing file");
+      return;
     }
   }
-  return Undefined(args.GetIsolate());
 }
 
 
-Handle<Value> Shell::Quit(const Arguments& args) {
+void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
   int exit_code = args[0]->Int32Value();
   OnExit();
   exit(exit_code);
-  return Undefined(args.GetIsolate());
 }
 
 
-Handle<Value> Shell::Version(const Arguments& args) {
-  return String::New(V8::GetVersion());
+void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  args.GetReturnValue().Set(String::New(V8::GetVersion()));
 }
 
 
@@ -940,16 +949,17 @@
   Context::Scope scope(context);
 
 #ifndef V8_SHARED
+  i::Factory* factory = i::Isolate::Current()->factory();
   i::JSArguments js_args = i::FLAG_js_arguments;
   i::Handle<i::FixedArray> arguments_array =
-      FACTORY->NewFixedArray(js_args.argc());
+      factory->NewFixedArray(js_args.argc());
   for (int j = 0; j < js_args.argc(); j++) {
     i::Handle<i::String> arg =
-        FACTORY->NewStringFromUtf8(i::CStrVector(js_args[j]));
+        factory->NewStringFromUtf8(i::CStrVector(js_args[j]));
     arguments_array->set(j, *arg);
   }
   i::Handle<i::JSArray> arguments_jsarray =
-      FACTORY->NewJSArrayWithElements(arguments_array);
+      factory->NewJSArrayWithElements(arguments_array);
   context->Global()->Set(String::New("arguments"),
                          Utils::ToLocal(arguments_jsarray));
 #endif  // V8_SHARED
@@ -1076,19 +1086,21 @@
   object->Dispose(isolate);
 }
 
-Handle<Value> Shell::ReadBuffer(const Arguments& args) {
+void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
   ASSERT(sizeof(char) == sizeof(uint8_t));  // NOLINT
   String::Utf8Value filename(args[0]);
   int length;
   if (*filename == NULL) {
-    return Throw("Error loading file");
+    Throw("Error loading file");
+    return;
   }
 
   Isolate* isolate = args.GetIsolate();
   uint8_t* data = reinterpret_cast<uint8_t*>(
       ReadChars(args.GetIsolate(), *filename, &length));
   if (data == NULL) {
-    return Throw("Error reading file");
+    Throw("Error reading file");
+    return;
   }
   Handle<v8::ArrayBuffer> buffer = ArrayBuffer::New(data, length);
   v8::Persistent<v8::Value> weak_handle(isolate, buffer);
@@ -1096,7 +1108,7 @@
   weak_handle.MarkIndependent();
   isolate->AdjustAmountOfExternalAllocatedMemory(length);
 
-  return buffer;
+  args.GetReturnValue().Set(buffer);
 }
 
 
diff --git a/src/d8.h b/src/d8.h
index c068dd9..804cc46 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -300,45 +300,46 @@
 #endif  // ENABLE_DEBUGGER_SUPPORT
 #endif  // V8_SHARED
 
-  static Handle<Value> RealmCurrent(const Arguments& args);
-  static Handle<Value> RealmOwner(const Arguments& args);
-  static Handle<Value> RealmGlobal(const Arguments& args);
-  static Handle<Value> RealmCreate(const Arguments& args);
-  static Handle<Value> RealmDispose(const Arguments& args);
-  static Handle<Value> RealmSwitch(const Arguments& args);
-  static Handle<Value> RealmEval(const Arguments& args);
-  static Handle<Value> RealmSharedGet(Local<String> property,
-                                      const AccessorInfo& info);
+  static void RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RealmGlobal(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RealmDispose(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RealmSwitch(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RealmEval(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RealmSharedGet(Local<String> property,
+                             const  PropertyCallbackInfo<Value>& info);
   static void RealmSharedSet(Local<String> property,
                              Local<Value> value,
-                             const AccessorInfo& info);
+                             const  PropertyCallbackInfo<void>& info);
 
-  static Handle<Value> Print(const Arguments& args);
-  static Handle<Value> Write(const Arguments& args);
-  static Handle<Value> Quit(const Arguments& args);
-  static Handle<Value> Version(const Arguments& args);
-  static Handle<Value> EnableProfiler(const Arguments& args);
-  static Handle<Value> DisableProfiler(const Arguments& args);
-  static Handle<Value> Read(const Arguments& args);
-  static Handle<Value> ReadBuffer(const Arguments& args);
+  static void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Write(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Version(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void EnableProfiler(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void DisableProfiler(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Read(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
   static Handle<String> ReadFromStdin(Isolate* isolate);
-  static Handle<Value> ReadLine(const Arguments& args) {
-    return ReadFromStdin(args.GetIsolate());
+  static void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    args.GetReturnValue().Set(ReadFromStdin(args.GetIsolate()));
   }
-  static Handle<Value> Load(const Arguments& args);
-  static Handle<Value> ArrayBuffer(const Arguments& args);
-  static Handle<Value> Int8Array(const Arguments& args);
-  static Handle<Value> Uint8Array(const Arguments& args);
-  static Handle<Value> Int16Array(const Arguments& args);
-  static Handle<Value> Uint16Array(const Arguments& args);
-  static Handle<Value> Int32Array(const Arguments& args);
-  static Handle<Value> Uint32Array(const Arguments& args);
-  static Handle<Value> Float32Array(const Arguments& args);
-  static Handle<Value> Float64Array(const Arguments& args);
-  static Handle<Value> Uint8ClampedArray(const Arguments& args);
-  static Handle<Value> ArrayBufferSlice(const Arguments& args);
-  static Handle<Value> ArraySubArray(const Arguments& args);
-  static Handle<Value> ArraySet(const Arguments& args);
+  static void Load(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void ArrayBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Int8Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Uint8Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Int16Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Uint16Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Int32Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Uint32Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Float32Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Float64Array(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void Uint8ClampedArray(
+      const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void ArrayBufferSlice(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void ArraySubArray(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void ArraySet(const v8::FunctionCallbackInfo<v8::Value>& args);
   // The OS object on the global object contains methods for performing
   // operating system calls:
   //
@@ -365,14 +366,14 @@
   // with the current umask.  Intermediate directories are created if necessary.
   // An exception is not thrown if the directory already exists.  Analogous to
   // the "mkdir -p" command.
-  static Handle<Value> OSObject(const Arguments& args);
-  static Handle<Value> System(const Arguments& args);
-  static Handle<Value> ChangeDirectory(const Arguments& args);
-  static Handle<Value> SetEnvironment(const Arguments& args);
-  static Handle<Value> UnsetEnvironment(const Arguments& args);
-  static Handle<Value> SetUMask(const Arguments& args);
-  static Handle<Value> MakeDirectory(const Arguments& args);
-  static Handle<Value> RemoveDirectory(const Arguments& args);
+  static void OSObject(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void System(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
 
   static void AddOSMethods(Handle<ObjectTemplate> os_template);
 
@@ -412,9 +413,10 @@
                                             int32_t byteLength,
                                             int32_t byteOffset,
                                             int32_t element_size);
-  static Handle<Value> CreateExternalArray(const Arguments& args,
-                                           ExternalArrayType type,
-                                           int32_t element_size);
+  static void CreateExternalArray(
+      const v8::FunctionCallbackInfo<v8::Value>& args,
+      ExternalArrayType type,
+      int32_t element_size);
   static void ExternalArrayWeakCallback(Isolate* isolate,
                                         Persistent<Object>* object,
                                         uint8_t* data);
diff --git a/src/debug.cc b/src/debug.cc
index 7d02252..95226c7 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -625,7 +625,8 @@
 
 
 Handle<FixedArray> ScriptCache::GetScripts() {
-  Handle<FixedArray> instances = FACTORY->NewFixedArray(occupancy());
+  Factory* factory = Isolate::Current()->factory();
+  Handle<FixedArray> instances = factory->NewFixedArray(occupancy());
   int count = 0;
   for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
     ASSERT(entry->value != NULL);
@@ -787,7 +788,7 @@
     MessageLocation computed_location;
     isolate->ComputeLocation(&computed_location);
     Handle<Object> message = MessageHandler::MakeMessageObject(
-        "error_loading_debugger", &computed_location,
+        isolate, "error_loading_debugger", &computed_location,
         Vector<Handle<Object> >::empty(), Handle<String>(), Handle<JSArray>());
     ASSERT(!isolate->has_pending_exception());
     if (!exception.is_null()) {
@@ -2226,6 +2227,8 @@
 // Ensures the debug information is present for shared.
 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared,
                             Handle<JSFunction> function) {
+  Isolate* isolate = shared->GetIsolate();
+
   // Return if we already have the debug info for shared.
   if (HasDebugInfo(shared)) {
     ASSERT(shared->is_compiled());
@@ -2242,7 +2245,7 @@
   }
 
   // Create the debug info object.
-  Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared);
+  Handle<DebugInfo> debug_info = isolate->factory()->NewDebugInfo(shared);
 
   // Add debug info to the list.
   DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 0f894a8..723d3f6 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -1986,56 +1986,6 @@
 }
 
 
-static bool ObjectToInt32(Object* obj, int32_t* value) {
-  if (obj->IsSmi()) {
-    *value = Smi::cast(obj)->value();
-    return true;
-  }
-
-  if (obj->IsHeapNumber()) {
-    double num = HeapNumber::cast(obj)->value();
-    if (FastI2D(FastD2I(num)) != num) {
-      if (FLAG_trace_osr) {
-        PrintF("**** %g could not be converted to int32 ****\n",
-               HeapNumber::cast(obj)->value());
-      }
-      return false;
-    }
-
-    *value = FastD2I(num);
-    return true;
-  }
-
-  return false;
-}
-
-
-static bool ObjectToUint32(Object* obj, uint32_t* value) {
-  if (obj->IsSmi()) {
-    if (Smi::cast(obj)->value() < 0) return false;
-
-    *value = static_cast<uint32_t>(Smi::cast(obj)->value());
-    return true;
-  }
-
-  if (obj->IsHeapNumber()) {
-    double num = HeapNumber::cast(obj)->value();
-    if ((num < 0) || (FastUI2D(FastD2UI(num)) != num)) {
-      if (FLAG_trace_osr) {
-        PrintF("**** %g could not be converted to uint32 ****\n",
-               HeapNumber::cast(obj)->value());
-      }
-      return false;
-    }
-
-    *value = FastD2UI(num);
-    return true;
-  }
-
-  return false;
-}
-
-
 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
                                         int* input_offset) {
   disasm::NameConverter converter;
@@ -2079,7 +2029,7 @@
 
     case Translation::INT32_REGISTER: {
       int32_t int32_value = 0;
-      if (!ObjectToInt32(input_object, &int32_value)) return false;
+      if (!input_object->ToInt32(&int32_value)) return false;
 
       int output_reg = iterator->Next();
       if (FLAG_trace_osr) {
@@ -2094,7 +2044,7 @@
 
     case Translation::UINT32_REGISTER: {
       uint32_t uint32_value = 0;
-      if (!ObjectToUint32(input_object, &uint32_value)) return false;
+      if (!input_object->ToUint32(&uint32_value)) return false;
 
       int output_reg = iterator->Next();
       if (FLAG_trace_osr) {
@@ -2141,7 +2091,7 @@
 
     case Translation::INT32_STACK_SLOT: {
       int32_t int32_value = 0;
-      if (!ObjectToInt32(input_object, &int32_value)) return false;
+      if (!input_object->ToInt32(&int32_value)) return false;
 
       int output_index = iterator->Next();
       unsigned output_offset =
@@ -2158,7 +2108,7 @@
 
     case Translation::UINT32_STACK_SLOT: {
       uint32_t uint32_value = 0;
-      if (!ObjectToUint32(input_object, &uint32_value)) return false;
+      if (!input_object->ToUint32(&uint32_value)) return false;
 
       int output_index = iterator->Next();
       unsigned output_offset =
diff --git a/src/execution.cc b/src/execution.cc
index ebf8e2c..38e7a3b 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -641,7 +641,8 @@
 
 
 Handle<Object> Execution::NewDate(double time, bool* exc) {
-  Handle<Object> time_obj = FACTORY->NewNumber(time);
+  Isolate* isolate = Isolate::Current();
+  Handle<Object> time_obj = isolate->factory()->NewNumber(time);
   RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
 }
 
diff --git a/src/extensions/externalize-string-extension.cc b/src/extensions/externalize-string-extension.cc
index 0f6b639..a3630fb 100644
--- a/src/extensions/externalize-string-extension.cc
+++ b/src/extensions/externalize-string-extension.cc
@@ -72,26 +72,29 @@
 }
 
 
-v8::Handle<v8::Value> ExternalizeStringExtension::Externalize(
-    const v8::Arguments& args) {
+void ExternalizeStringExtension::Externalize(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() < 1 || !args[0]->IsString()) {
-    return v8::ThrowException(v8::String::New(
+    v8::ThrowException(v8::String::New(
         "First parameter to externalizeString() must be a string."));
+    return;
   }
   bool force_two_byte = false;
   if (args.Length() >= 2) {
     if (args[1]->IsBoolean()) {
       force_two_byte = args[1]->BooleanValue();
     } else {
-      return v8::ThrowException(v8::String::New(
-          "Second parameter to externalizeString() must be a boolean."));
+      v8::ThrowException(v8::String::New(
+        "Second parameter to externalizeString() must be a boolean."));
+      return;
     }
   }
   bool result = false;
   Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>());
   if (string->IsExternalString()) {
-    return v8::ThrowException(v8::String::New(
+    v8::ThrowException(v8::String::New(
         "externalizeString() can't externalize twice."));
+    return;
   }
   if (string->IsOneByteRepresentation() && !force_two_byte) {
     uint8_t* data = new uint8_t[string->length()];
@@ -115,21 +118,22 @@
     if (!result) delete resource;
   }
   if (!result) {
-    return v8::ThrowException(v8::String::New("externalizeString() failed."));
+    v8::ThrowException(v8::String::New("externalizeString() failed."));
+    return;
   }
-  return v8::Undefined();
 }
 
 
-v8::Handle<v8::Value> ExternalizeStringExtension::IsAscii(
-    const v8::Arguments& args) {
+void ExternalizeStringExtension::IsAscii(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 1 || !args[0]->IsString()) {
-    return v8::ThrowException(v8::String::New(
+    v8::ThrowException(v8::String::New(
         "isAsciiString() requires a single string argument."));
+    return;
   }
-  return
-      Utils::OpenHandle(*args[0].As<v8::String>())->IsOneByteRepresentation() ?
-      v8::True() : v8::False();
+  bool is_one_byte =
+      Utils::OpenHandle(*args[0].As<v8::String>())->IsOneByteRepresentation();
+  args.GetReturnValue().Set(is_one_byte);
 }
 
 
diff --git a/src/extensions/externalize-string-extension.h b/src/extensions/externalize-string-extension.h
index b97b496..ecbc1cf 100644
--- a/src/extensions/externalize-string-extension.h
+++ b/src/extensions/externalize-string-extension.h
@@ -38,8 +38,8 @@
   ExternalizeStringExtension() : v8::Extension("v8/externalize", kSource) {}
   virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
       v8::Handle<v8::String> name);
-  static v8::Handle<v8::Value> Externalize(const v8::Arguments& args);
-  static v8::Handle<v8::Value> IsAscii(const v8::Arguments& args);
+  static void Externalize(const v8::FunctionCallbackInfo<v8::Value>& args);
+  static void IsAscii(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void Register();
  private:
   static const char* const kSource;
diff --git a/src/extensions/gc-extension.cc b/src/extensions/gc-extension.cc
index 1a2fe8f..036b60c 100644
--- a/src/extensions/gc-extension.cc
+++ b/src/extensions/gc-extension.cc
@@ -38,13 +38,12 @@
 }
 
 
-v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) {
+void GCExtension::GC(const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args[0]->BooleanValue()) {
     HEAP->CollectGarbage(NEW_SPACE, "gc extension");
   } else {
     HEAP->CollectAllGarbage(Heap::kNoGCFlags, "gc extension");
   }
-  return v8::Undefined();
 }
 
 
diff --git a/src/extensions/gc-extension.h b/src/extensions/gc-extension.h
index 54b865a..e412b92a 100644
--- a/src/extensions/gc-extension.h
+++ b/src/extensions/gc-extension.h
@@ -38,7 +38,7 @@
   explicit GCExtension(const char* source) : v8::Extension("v8/gc", source) {}
   virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
       v8::Handle<v8::String> name);
-  static v8::Handle<v8::Value> GC(const v8::Arguments& args);
+  static void GC(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void Register();
 };
 
diff --git a/src/extensions/statistics-extension.cc b/src/extensions/statistics-extension.cc
index 71b70a5..e5a3009 100644
--- a/src/extensions/statistics-extension.cc
+++ b/src/extensions/statistics-extension.cc
@@ -58,8 +58,8 @@
 }
 
 
-v8::Handle<v8::Value> StatisticsExtension::GetCounters(
-    const v8::Arguments& args) {
+void StatisticsExtension::GetCounters(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
 
@@ -141,7 +141,7 @@
             "lo_space_commited_bytes");
   AddNumber(result, heap->amount_of_external_allocated_memory(),
             "amount_of_external_allocated_memory");
-  return result;
+  args.GetReturnValue().Set(result);
 }
 
 
diff --git a/src/extensions/statistics-extension.h b/src/extensions/statistics-extension.h
index 433c4cf..bfd9c41 100644
--- a/src/extensions/statistics-extension.h
+++ b/src/extensions/statistics-extension.h
@@ -38,7 +38,7 @@
   StatisticsExtension() : v8::Extension("v8/statistics", kSource) {}
   virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
       v8::Handle<v8::String> name);
-  static v8::Handle<v8::Value> GetCounters(const v8::Arguments& args);
+  static void GetCounters(const v8::FunctionCallbackInfo<v8::Value>& args);
   static void Register();
  private:
   static const char* const kSource;
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 8fe6778..0a6e576 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -193,6 +193,9 @@
             true,
             "Optimize object size, Array shift, DOM strings and string +")
 DEFINE_bool(pretenuring, true, "allocate objects in old space")
+// TODO(hpayer): We will remove this flag as soon as we have pretenuring
+// support for specific allocation sites.
+DEFINE_bool(pretenuring_call_new, false, "pretenure call new")
 DEFINE_bool(track_fields, true, "track fields with only smi values")
 DEFINE_bool(track_double_fields, true, "track fields with double values")
 DEFINE_bool(track_heap_object_fields, true, "track fields with heap values")
@@ -251,6 +254,8 @@
             "perform array bounds checks elimination")
 DEFINE_bool(array_index_dehoisting, true,
             "perform array index dehoisting")
+DEFINE_bool(analyze_environment_liveness, true,
+            "analyze liveness of environment slots and zap dead values")
 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")
diff --git a/src/handles-inl.h b/src/handles-inl.h
index 8f001af..9d38f38 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -185,8 +185,8 @@
       isolate_->handle_scope_data();
   // Shrink the current handle scope to make it impossible to do
   // handle allocations without an explicit handle scope.
+  limit_ = current->limit;
   current->limit = current->next;
-
   level_ = current->level;
   current->level = 0;
 }
@@ -195,10 +195,12 @@
 inline SealHandleScope::~SealHandleScope() {
   // Restore state in current handle scope to re-enable handle
   // allocations.
-  v8::ImplementationUtilities::HandleScopeData* data =
+  v8::ImplementationUtilities::HandleScopeData* current =
       isolate_->handle_scope_data();
-  ASSERT_EQ(0, data->level);
-  data->level = level_;
+  ASSERT_EQ(0, current->level);
+  current->level = level_;
+  ASSERT_EQ(current->next, current->limit);
+  current->limit = limit_;
 }
 
 #endif
diff --git a/src/handles.h b/src/handles.h
index 46dd1fd..573298a 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -345,7 +345,6 @@
   Isolate* isolate_;
   Object** limit_;
   int level_;
-  bool active_;
 #endif
 };
 
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index c4da47c..b8237a6 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -1210,10 +1210,6 @@
   SetInternalReference(obj, entry,
                        "inferred_name", shared->inferred_name(),
                        SharedFunctionInfo::kInferredNameOffset);
-  SetInternalReference(obj, entry,
-                       "this_property_assignments",
-                       shared->this_property_assignments(),
-                       SharedFunctionInfo::kThisPropertyAssignmentsOffset);
   SetWeakReference(obj, entry,
                    1, shared->initial_map(),
                    SharedFunctionInfo::kInitialMapOffset);
diff --git a/src/heap.cc b/src/heap.cc
index 9bfca64..5e88aca 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2973,7 +2973,7 @@
   SeededNumberDictionary::cast(obj)->set_requires_slow_elements();
   set_empty_slow_element_dictionary(SeededNumberDictionary::cast(obj));
 
-  // Handling of script id generation is in FACTORY->NewScript.
+  // Handling of script id generation is in Factory::NewScript.
   set_last_script_id(undefined_value());
 
   // Initialize keyed lookup cache.
@@ -3377,7 +3377,6 @@
   share->set_debug_info(undefined_value(), SKIP_WRITE_BARRIER);
   share->set_inferred_name(empty_string(), SKIP_WRITE_BARRIER);
   share->set_initial_map(undefined_value(), SKIP_WRITE_BARRIER);
-  share->set_this_property_assignments(undefined_value(), SKIP_WRITE_BARRIER);
   share->set_ast_node_count(0);
   share->set_stress_deopt_counter(FLAG_deopt_every_n_times);
   share->set_counters(0);
@@ -3392,7 +3391,6 @@
   share->set_function_token_position(0);
   // All compiler hints default to false or 0.
   share->set_compiler_hints(0);
-  share->set_this_property_assignments_count(0);
   share->set_opt_count(0);
 
   return share;
@@ -4161,20 +4159,6 @@
 }
 
 
-static bool HasDuplicates(DescriptorArray* descriptors) {
-  int count = descriptors->number_of_descriptors();
-  if (count > 1) {
-    Name* prev_key = descriptors->GetKey(0);
-    for (int i = 1; i != count; i++) {
-      Name* current_key = descriptors->GetKey(i);
-      if (prev_key == current_key) return true;
-      prev_key = current_key;
-    }
-  }
-  return false;
-}
-
-
 MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
   ASSERT(!fun->has_initial_map());
 
@@ -4209,48 +4193,6 @@
   map->set_prototype(prototype);
   ASSERT(map->has_fast_object_elements());
 
-  // If the function has only simple this property assignments add
-  // field descriptors for these to the initial map as the object
-  // cannot be constructed without having these properties.  Guard by
-  // the inline_new flag so we only change the map if we generate a
-  // specialized construct stub.
-  ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields);
-  if (!fun->shared()->is_generator() &&
-      fun->shared()->CanGenerateInlineConstructor(prototype)) {
-    int count = fun->shared()->this_property_assignments_count();
-    if (count > in_object_properties) {
-      // Inline constructor can only handle inobject properties.
-      fun->shared()->ForbidInlineConstructor();
-    } else {
-      DescriptorArray* descriptors;
-      MaybeObject* maybe_descriptors = DescriptorArray::Allocate(count);
-      if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
-
-      DescriptorArray::WhitenessWitness witness(descriptors);
-      for (int i = 0; i < count; i++) {
-        String* name = fun->shared()->GetThisPropertyAssignmentName(i);
-        ASSERT(name->IsInternalizedString());
-        // TODO(verwaest): Since we cannot update the boilerplate's map yet,
-        // initialize to the worst case.
-        FieldDescriptor field(name, i, NONE, Representation::Tagged());
-        descriptors->Set(i, &field, witness);
-      }
-      descriptors->Sort();
-
-      // The descriptors may contain duplicates because the compiler does not
-      // guarantee the uniqueness of property names (it would have required
-      // quadratic time). Once the descriptors are sorted we can check for
-      // duplicates in linear time.
-      if (HasDuplicates(descriptors)) {
-        fun->shared()->ForbidInlineConstructor();
-      } else {
-        map->InitializeDescriptors(descriptors);
-        map->set_pre_allocated_property_fields(count);
-        map->set_unused_property_fields(in_object_properties - count);
-      }
-    }
-  }
-
   if (!fun->shared()->is_generator()) {
     fun->shared()->StartInobjectSlackTracking(map);
   }
@@ -4302,10 +4244,7 @@
   ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
 
   // Allocate the backing storage for the properties.
-  int prop_size =
-      map->pre_allocated_property_fields() +
-      map->unused_property_fields() -
-      map->inobject_properties();
+  int prop_size = map->InitialPropertiesLength();
   ASSERT(prop_size >= 0);
   Object* properties;
   { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure);
@@ -4342,10 +4281,7 @@
   ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
 
   // Allocate the backing storage for the properties.
-  int prop_size =
-      map->pre_allocated_property_fields() +
-      map->unused_property_fields() -
-      map->inobject_properties();
+  int prop_size = map->InitialPropertiesLength();
   ASSERT(prop_size >= 0);
   Object* properties;
   { MaybeObject* maybe_properties = AllocateFixedArray(prop_size);
@@ -7518,6 +7454,8 @@
     PrintF("intracompaction_ptrs=%.1f ",
         scopes_[Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED]);
     PrintF("misc_compaction=%.1f ", scopes_[Scope::MC_UPDATE_MISC_POINTERS]);
+    PrintF("weakmap_process=%.1f ", scopes_[Scope::MC_WEAKMAP_PROCESS]);
+    PrintF("weakmap_clear=%.1f ", scopes_[Scope::MC_WEAKMAP_CLEAR]);
 
     PrintF("total_size_before=%" V8_PTR_PREFIX "d ", start_object_size_);
     PrintF("total_size_after=%" V8_PTR_PREFIX "d ", heap_->SizeOfObjects());
diff --git a/src/heap.h b/src/heap.h
index 5a93981..394a02a 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -2711,6 +2711,8 @@
       MC_UPDATE_POINTERS_TO_EVACUATED,
       MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
       MC_UPDATE_MISC_POINTERS,
+      MC_WEAKMAP_PROCESS,
+      MC_WEAKMAP_CLEAR,
       MC_FLUSH_CODE,
       kNumberOfScopes
     };
diff --git a/src/hydrogen-environment-liveness.cc b/src/hydrogen-environment-liveness.cc
new file mode 100644
index 0000000..8c66059
--- /dev/null
+++ b/src/hydrogen-environment-liveness.cc
@@ -0,0 +1,267 @@
+// 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-environment-liveness.h"
+
+
+namespace v8 {
+namespace internal {
+
+
+EnvironmentSlotLivenessAnalyzer::EnvironmentSlotLivenessAnalyzer(
+    HGraph* graph)
+    : graph_(graph),
+      zone_(graph->isolate()),
+      zone_scope_(&zone_, DELETE_ON_EXIT),
+      block_count_(graph->blocks()->length()),
+      maximum_environment_size_(graph->maximum_environment_size()),
+      collect_markers_(true),
+      last_simulate_(NULL) {
+  if (maximum_environment_size_ == 0) return;
+
+  live_at_block_start_ =
+      new(zone()) ZoneList<BitVector*>(block_count_, zone());
+  first_simulate_ = new(zone()) ZoneList<HSimulate*>(block_count_, zone());
+  first_simulate_invalid_for_index_ =
+      new(zone()) ZoneList<BitVector*>(block_count_, zone());
+  markers_ = new(zone())
+      ZoneList<HEnvironmentMarker*>(maximum_environment_size_, zone());
+  went_live_since_last_simulate_ =
+      new(zone()) BitVector(maximum_environment_size_, zone());
+
+  for (int i = 0; i < block_count_; ++i) {
+    live_at_block_start_->Add(
+        new(zone()) BitVector(maximum_environment_size_, zone()), zone());
+    first_simulate_->Add(NULL, zone());
+    first_simulate_invalid_for_index_->Add(
+        new(zone()) BitVector(maximum_environment_size_, zone()), zone());
+  }
+}
+
+
+void EnvironmentSlotLivenessAnalyzer::ZapEnvironmentSlot(int index,
+                                                         HSimulate* simulate) {
+  int operand_index = simulate->ToOperandIndex(index);
+  if (operand_index == -1) {
+    simulate->AddAssignedValue(index, graph_->GetConstantUndefined());
+  } else {
+    simulate->SetOperandAt(operand_index, graph_->GetConstantUndefined());
+  }
+}
+
+
+void EnvironmentSlotLivenessAnalyzer::ZapEnvironmentSlotsInSuccessors(
+    HBasicBlock* block,
+    BitVector* live) {
+  // When a value is live in successor A but dead in B, we must
+  // explicitly zap it in B.
+  for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
+    HBasicBlock* successor = it.Current();
+    int successor_id = successor->block_id();
+    BitVector* live_in_successor = live_at_block_start_->at(successor_id);
+    if (live_in_successor->Equals(*live)) continue;
+    for (int i = 0; i < live->length(); ++i) {
+      if (!live->Contains(i)) continue;
+      if (live_in_successor->Contains(i)) continue;
+      if (first_simulate_invalid_for_index_->at(successor_id)->Contains(i)) {
+        continue;
+      }
+      HSimulate* simulate = first_simulate_->at(successor_id);
+      if (simulate == NULL) continue;
+      ASSERT(simulate->closure().is_identical_to(
+                 block->last_environment()->closure()));
+      ZapEnvironmentSlot(i, simulate);
+    }
+  }
+}
+
+
+void EnvironmentSlotLivenessAnalyzer::ZapEnvironmentSlotsForInstruction(
+    HEnvironmentMarker* marker) {
+  if (!marker->CheckFlag(HValue::kEndsLiveRange)) return;
+  HSimulate* simulate = marker->next_simulate();
+  if (simulate != NULL) {
+    ASSERT(simulate->closure().is_identical_to(marker->closure()));
+    ZapEnvironmentSlot(marker->index(), simulate);
+  }
+}
+
+
+void EnvironmentSlotLivenessAnalyzer::UpdateLivenessAtBlockEnd(
+    HBasicBlock* block,
+    BitVector* live) {
+  // Liveness at the end of each block: union of liveness in successors.
+  live->Clear();
+  for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
+    live->Union(*live_at_block_start_->at(it.Current()->block_id()));
+  }
+}
+
+
+void EnvironmentSlotLivenessAnalyzer::UpdateLivenessAtInstruction(
+    HInstruction* instr,
+    BitVector* live) {
+  switch (instr->opcode()) {
+    case HValue::kEnvironmentMarker: {
+      HEnvironmentMarker* marker = HEnvironmentMarker::cast(instr);
+      int index = marker->index();
+      if (!live->Contains(index)) {
+        marker->SetFlag(HValue::kEndsLiveRange);
+      } else {
+        marker->ClearFlag(HValue::kEndsLiveRange);
+      }
+      if (!went_live_since_last_simulate_->Contains(index)) {
+        marker->set_next_simulate(last_simulate_);
+      }
+      if (marker->kind() == HEnvironmentMarker::LOOKUP) {
+        live->Add(index);
+      } else {
+        ASSERT(marker->kind() == HEnvironmentMarker::BIND);
+        live->Remove(index);
+        went_live_since_last_simulate_->Add(index);
+      }
+      if (collect_markers_) {
+        // Populate |markers_| list during the first pass.
+        markers_->Add(marker, &zone_);
+      }
+      break;
+    }
+    case HValue::kLeaveInlined:
+      // No environment values are live at the end of an inlined section.
+      live->Clear();
+      last_simulate_ = NULL;
+
+      // The following ASSERTs guard the assumption used in case
+      // kEnterInlined below:
+      ASSERT(instr->next()->IsSimulate());
+      ASSERT(instr->next()->next()->IsGoto());
+
+      break;
+    case HValue::kEnterInlined: {
+      // Those environment values are live that are live at any return
+      // target block. Here we make use of the fact that the end of an
+      // inline sequence always looks like this: HLeaveInlined, HSimulate,
+      // HGoto (to return_target block), with no environment lookups in
+      // between (see ASSERTs above).
+      HEnterInlined* enter = HEnterInlined::cast(instr);
+      live->Clear();
+      for (int i = 0; i < enter->return_targets()->length(); ++i) {
+        int return_id = enter->return_targets()->at(i)->block_id();
+        // When an AbnormalExit is involved, it can happen that the return
+        // target block doesn't actually exist.
+        if (return_id < live_at_block_start_->length()) {
+          live->Union(*live_at_block_start_->at(return_id));
+        }
+      }
+      last_simulate_ = NULL;
+      break;
+    }
+    case HValue::kDeoptimize: {
+      // Keep all environment slots alive.
+      HDeoptimize* deopt = HDeoptimize::cast(instr);
+      for (int i = deopt->first_local_index();
+           i < deopt->first_expression_index(); ++i) {
+        live->Add(i);
+      }
+      break;
+    }
+    case HValue::kSimulate:
+      last_simulate_ = HSimulate::cast(instr);
+      went_live_since_last_simulate_->Clear();
+      break;
+    default:
+      break;
+  }
+}
+
+
+void EnvironmentSlotLivenessAnalyzer::AnalyzeAndTrim() {
+  HPhase phase("H_EnvironmentLivenessAnalysis", graph_);
+  if (maximum_environment_size_ == 0) return;
+
+  // Main iteration. Compute liveness of environment slots, and store it
+  // for each block until it doesn't change any more. For efficiency, visit
+  // blocks in reverse order and walk backwards through each block. We
+  // need several iterations to propagate liveness through nested loops.
+  BitVector* live = new(zone()) BitVector(maximum_environment_size_, zone());
+  BitVector* worklist = new(zone()) BitVector(block_count_, zone());
+  for (int i = 0; i < block_count_; ++i) {
+    worklist->Add(i);
+  }
+  while (!worklist->IsEmpty()) {
+    for (int block_id = block_count_ - 1; block_id >= 0; --block_id) {
+      if (!worklist->Contains(block_id)) {
+        continue;
+      }
+      worklist->Remove(block_id);
+      last_simulate_ = NULL;
+
+      HBasicBlock* block = graph_->blocks()->at(block_id);
+      UpdateLivenessAtBlockEnd(block, live);
+
+      for (HInstruction* instr = block->last(); instr != NULL;
+           instr = instr->previous()) {
+        UpdateLivenessAtInstruction(instr, live);
+      }
+
+      // Reached the start of the block, do necessary bookkeeping:
+      // store computed information for this block and add predecessors
+      // to the work list as necessary.
+      first_simulate_->Set(block_id, last_simulate_);
+      first_simulate_invalid_for_index_->at(block_id)->CopyFrom(
+          *went_live_since_last_simulate_);
+      if (live_at_block_start_->at(block_id)->UnionIsChanged(*live)) {
+        for (int i = 0; i < block->predecessors()->length(); ++i) {
+          worklist->Add(block->predecessors()->at(i)->block_id());
+        }
+        if (block->IsInlineReturnTarget()) {
+          worklist->Add(block->inlined_entry_block()->block_id());
+        }
+      }
+    }
+    // Only collect bind/lookup instructions during the first pass.
+    collect_markers_ = false;
+  }
+
+  // Analysis finished. Zap dead environment slots.
+  for (int i = 0; i < markers_->length(); ++i) {
+    ZapEnvironmentSlotsForInstruction(markers_->at(i));
+  }
+  for (int block_id = block_count_ - 1; block_id >= 0; --block_id) {
+    HBasicBlock* block = graph_->blocks()->at(block_id);
+    UpdateLivenessAtBlockEnd(block, live);
+    ZapEnvironmentSlotsInSuccessors(block, live);
+  }
+
+  // Finally, remove the HEnvironment{Bind,Lookup} markers.
+  for (int i = 0; i < markers_->length(); ++i) {
+    markers_->at(i)->DeleteAndReplaceWith(NULL);
+  }
+}
+
+} }  // namespace v8::internal
diff --git a/src/hydrogen-environment-liveness.h b/src/hydrogen-environment-liveness.h
new file mode 100644
index 0000000..484e56d
--- /dev/null
+++ b/src/hydrogen-environment-liveness.h
@@ -0,0 +1,94 @@
+// 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_ENVIRONMENT_LIVENESS_H_
+#define V8_HYDROGEN_ENVIRONMENT_LIVENESS_H_
+
+
+#include "hydrogen.h"
+
+namespace v8 {
+namespace internal {
+
+
+// Trims live ranges of environment slots by doing explicit liveness analysis.
+// Values in the environment are kept alive by every subsequent LInstruction
+// that is assigned an LEnvironment, which creates register pressure and
+// unnecessary spill slot moves. Therefore it is beneficial to trim the
+// live ranges of environment slots by zapping them with a constant after
+// the last lookup that refers to them.
+// Slots are identified by their index and only affected if whitelisted in
+// HOptimizedGraphBuilder::IsEligibleForEnvironmentLivenessAnalysis().
+class EnvironmentSlotLivenessAnalyzer {
+ public:
+  explicit EnvironmentSlotLivenessAnalyzer(HGraph* graph);
+
+  void AnalyzeAndTrim();
+
+ private:
+  void ZapEnvironmentSlot(int index, HSimulate* simulate);
+  void ZapEnvironmentSlotsInSuccessors(HBasicBlock* block, BitVector* live);
+  void ZapEnvironmentSlotsForInstruction(HEnvironmentMarker* marker);
+  void UpdateLivenessAtBlockEnd(HBasicBlock* block, BitVector* live);
+  void UpdateLivenessAtInstruction(HInstruction* instr, BitVector* live);
+
+  Zone* zone() { return &zone_; }
+
+  HGraph* graph_;
+  // Use a dedicated Zone for this phase, with a ZoneScope to ensure it
+  // gets freed.
+  Zone zone_;
+  ZoneScope zone_scope_;
+
+  int block_count_;
+
+  // Largest number of local variables in any environment in the graph
+  // (including inlined environments).
+  int maximum_environment_size_;
+
+  // Per-block data. All these lists are indexed by block_id.
+  ZoneList<BitVector*>* live_at_block_start_;
+  ZoneList<HSimulate*>* first_simulate_;
+  ZoneList<BitVector*>* first_simulate_invalid_for_index_;
+
+  // List of all HEnvironmentMarker instructions for quick iteration/deletion.
+  // It is populated during the first pass over the graph, controlled by
+  // |collect_markers_|.
+  ZoneList<HEnvironmentMarker*>* markers_;
+  bool collect_markers_;
+
+  // Keeps track of the last simulate seen, as well as the environment slots
+  // for which a new live range has started since (so they must not be zapped
+  // in that simulate when the end of another live range of theirs is found).
+  HSimulate* last_simulate_;
+  BitVector* went_live_since_last_simulate_;
+};
+
+
+} }  // namespace v8::internal
+
+#endif /* V8_HYDROGEN_ENVIRONMENT_LIVENESS_H_ */
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index d4938e5..5fae5f7 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -124,20 +124,9 @@
                                   const char* reason) {
   Representation r = representation();
   if (new_rep.is_more_general_than(r)) {
-    // When an HConstant is marked "not convertible to integer", then
-    // never try to represent it as an integer.
-    if (new_rep.IsInteger32() && !IsConvertibleToInteger()) {
-      new_rep = Representation::Tagged();
-      if (FLAG_trace_representation) {
-        PrintF("Changing #%d %s representation %s -> %s because it's NCTI"
-               " (%s want i)\n",
-               id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
-      }
-    } else {
-      if (FLAG_trace_representation) {
-        PrintF("Changing #%d %s representation %s -> %s based on %s\n",
-               id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
-      }
+    if (FLAG_trace_representation) {
+      PrintF("Changing #%d %s representation %s -> %s based on %s\n",
+             id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
     }
     ChangeRepresentation(new_rep);
     AddDependantsToWorklist(h_infer);
@@ -989,6 +978,11 @@
 }
 
 
+void HEnvironmentMarker::PrintDataTo(StringStream* stream) {
+  stream->Add("%s var[%d]", kind() == BIND ? "bind" : "lookup", index());
+}
+
+
 void HUnaryCall::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
   stream->Add(" ");
@@ -1926,7 +1920,6 @@
               int32_non_phi_uses() + int32_indirect_uses(),
               double_non_phi_uses() + double_indirect_uses(),
               tagged_non_phi_uses() + tagged_indirect_uses());
-  if (!IsConvertibleToInteger()) stream->Add("_ncti");
   PrintRangeTo(stream);
   PrintTypeTo(stream);
   stream->Add("]");
@@ -2073,6 +2066,13 @@
 }
 
 
+void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target,
+                                         Zone* zone) {
+  ASSERT(return_target->IsInlineReturnTarget());
+  return_targets_.Add(return_target, zone);
+}
+
+
 void HEnterInlined::PrintDataTo(StringStream* stream) {
   SmartArrayPointer<char> name = function()->debug_name()->ToCString();
   stream->Add("%s, id=%d", *name, function()->id().ToInt());
@@ -2322,7 +2322,37 @@
 
 
 Range* HBitwise::InferRange(Zone* zone) {
-  if (op() == Token::BIT_XOR) return HValue::InferRange(zone);
+  if (op() == Token::BIT_XOR) {
+    if (left()->HasRange() && right()->HasRange()) {
+      // The maximum value has the high bit, and all bits below, set:
+      // (1 << high) - 1.
+      // If the range can be negative, the minimum int is a negative number with
+      // the high bit, and all bits below, unset:
+      // -(1 << high).
+      // If it cannot be negative, conservatively choose 0 as minimum int.
+      int64_t left_upper = left()->range()->upper();
+      int64_t left_lower = left()->range()->lower();
+      int64_t right_upper = right()->range()->upper();
+      int64_t right_lower = right()->range()->lower();
+
+      if (left_upper < 0) left_upper = ~left_upper;
+      if (left_lower < 0) left_lower = ~left_lower;
+      if (right_upper < 0) right_upper = ~right_upper;
+      if (right_lower < 0) right_lower = ~right_lower;
+
+      int high = MostSignificantBit(
+          static_cast<uint32_t>(
+              left_upper | left_lower | right_upper | right_lower));
+
+      int64_t limit = 1;
+      limit <<= high;
+      int32_t min = (left()->range()->CanBeNegative() ||
+                     right()->range()->CanBeNegative())
+                    ? static_cast<int32_t>(-limit) : 0;
+      return new(zone) Range(min, static_cast<int32_t>(limit - 1));
+    }
+    return HValue::InferRange(zone);
+  }
   const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff);
   int32_t left_mask = (left()->range() != NULL)
       ? left()->range()->Mask()
@@ -3041,11 +3071,6 @@
 }
 
 
-HType HAllocateObject::CalculateInferredType() {
-  return HType::JSObject();
-}
-
-
 HType HAllocate::CalculateInferredType() {
   return type_;
 }
@@ -3226,7 +3251,8 @@
     HConstant* c_right = HConstant::cast(right);
     HConstant* c_left = HConstant::cast(left);
     if (c_left->HasStringValue() && c_right->HasStringValue()) {
-      return new(zone) HConstant(FACTORY->NewConsString(c_left->StringValue(),
+      Factory* factory = Isolate::Current()->factory();
+      return new(zone) HConstant(factory->NewConsString(c_left->StringValue(),
                                                         c_right->StringValue()),
                                  Representation::Tagged());
     }
@@ -3381,8 +3407,12 @@
 }
 
 
-HInstruction* HMod::New(
-    Zone* zone, HValue* context, HValue* left, HValue* right) {
+HInstruction* HMod::New(Zone* zone,
+                        HValue* context,
+                        HValue* left,
+                        HValue* right,
+                        bool has_fixed_right_arg,
+                        int fixed_right_arg_value) {
   if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
     HConstant* c_left = HConstant::cast(left);
     HConstant* c_right = HConstant::cast(right);
@@ -3401,7 +3431,11 @@
       }
     }
   }
-  return new(zone) HMod(context, left, right);
+  return new(zone) HMod(context,
+                        left,
+                        right,
+                        has_fixed_right_arg,
+                        fixed_right_arg_value);
 }
 
 
@@ -3565,48 +3599,11 @@
 
 
 Representation HPhi::RepresentationFromInputs() {
-  bool double_occurred = false;
-  bool int32_occurred = false;
-  bool smi_occurred = false;
+  Representation r = Representation::None();
   for (int i = 0; i < OperandCount(); ++i) {
-    HValue* value = OperandAt(i);
-    if (value->IsUnknownOSRValue()) {
-      HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value();
-      if (hint_value != NULL) {
-        Representation hint = hint_value->representation();
-        if (hint.IsTagged()) return hint;
-        if (hint.IsDouble()) double_occurred = true;
-        if (hint.IsInteger32()) int32_occurred = true;
-        if (hint.IsSmi()) smi_occurred = true;
-      }
-      continue;
-    }
-    if (value->representation().IsDouble()) double_occurred = true;
-    if (value->representation().IsInteger32()) int32_occurred = true;
-    if (value->representation().IsSmi()) smi_occurred = true;
-    if (value->representation().IsTagged()) {
-      if (value->IsConstant()) {
-        HConstant* constant = HConstant::cast(value);
-        if (constant->IsConvertibleToInteger()) {
-          int32_occurred = true;
-        } else if (constant->HasNumberValue()) {
-          double_occurred = true;
-        } else {
-          return Representation::Tagged();
-        }
-      } else {
-        if (value->IsPhi() && !IsConvertibleToInteger()) {
-          return Representation::Tagged();
-        }
-      }
-    }
+    r = r.generalize(OperandAt(i)->KnownOptimalRepresentation());
   }
-
-  if (double_occurred) return Representation::Double();
-  if (int32_occurred) return Representation::Integer32();
-  if (smi_occurred) return Representation::Smi();
-
-  return Representation::None();
+  return r;
 }
 
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index cd5b271..4a8a406 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -65,7 +65,6 @@
   V(AccessArgumentsAt)                         \
   V(Add)                                       \
   V(Allocate)                                  \
-  V(AllocateObject)                            \
   V(ApplyArguments)                            \
   V(ArgumentsElements)                         \
   V(ArgumentsLength)                           \
@@ -109,6 +108,7 @@
   V(DummyUse)                                  \
   V(ElementsKind)                              \
   V(EnterInlined)                              \
+  V(EnvironmentMarker)                         \
   V(FixedArrayBaseLength)                      \
   V(ForceRepresentation)                       \
   V(FunctionLiteral)                           \
@@ -811,7 +811,13 @@
     kHasNoObservableSideEffects,
     // Indicates the instruction is live during dead code elimination.
     kIsLive,
-    kLastFlag = kIDefsProcessingDone
+
+    // HEnvironmentMarkers are deleted before dead code
+    // elimination takes place, so they can repurpose the kIsLive flag:
+    kEndsLiveRange = kIsLive,
+
+    // TODO(everyone): Don't forget to update this!
+    kLastFlag = kIsLive
   };
 
   STATIC_ASSERT(kLastFlag < kBitsPerInt);
@@ -885,7 +891,17 @@
   }
   virtual void AssumeRepresentation(Representation r);
 
-  virtual bool IsConvertibleToInteger() const { return true; }
+  virtual Representation KnownOptimalRepresentation() {
+    Representation r = representation();
+    if (r.IsTagged()) {
+      HType t = type();
+      if (t.IsSmi()) return Representation::Smi();
+      if (t.IsHeapNumber()) return Representation::Double();
+      if (t.IsHeapObject()) return r;
+      return Representation::None();
+    }
+    return r;
+  }
 
   HType type() const { return type_; }
   void set_type(HType new_type) {
@@ -1476,8 +1492,13 @@
 
 class HDeoptimize: public HControlInstruction {
  public:
-  HDeoptimize(int environment_length, Zone* zone)
-      : values_(environment_length, zone) { }
+  HDeoptimize(int environment_length,
+              int first_local_index,
+              int first_expression_index,
+              Zone* zone)
+      : values_(environment_length, zone),
+        first_local_index_(first_local_index),
+        first_expression_index_(first_expression_index) { }
 
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::None();
@@ -1500,6 +1521,8 @@
     values_.Add(NULL, zone);
     SetOperandAt(values_.length() - 1, value);
   }
+  int first_local_index() { return first_local_index_; }
+  int first_expression_index() { return first_expression_index_; }
 
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
 
@@ -1515,6 +1538,8 @@
 
  private:
   ZoneList<HValue*> values_;
+  int first_local_index_;
+  int first_expression_index_;
 };
 
 
@@ -1831,6 +1856,12 @@
   void AddPushedValue(HValue* value) {
     AddValue(kNoIndex, value);
   }
+  int ToOperandIndex(int environment_index) {
+    for (int i = 0; i < assigned_indexes_.length(); ++i) {
+      if (assigned_indexes_[i] == environment_index) return i;
+    }
+    return -1;
+  }
   virtual int OperandCount() { return values_.length(); }
   virtual HValue* OperandAt(int index) const { return values_[index]; }
 
@@ -1845,6 +1876,8 @@
 
 #ifdef DEBUG
   virtual void Verify();
+  void set_closure(Handle<JSFunction> closure) { closure_ = closure; }
+  Handle<JSFunction> closure() const { return closure_; }
 #endif
 
  protected:
@@ -1874,6 +1907,52 @@
   ZoneList<int> assigned_indexes_;
   Zone* zone_;
   RemovableSimulate removable_;
+
+#ifdef DEBUG
+  Handle<JSFunction> closure_;
+#endif
+};
+
+
+class HEnvironmentMarker: public HTemplateInstruction<1> {
+ public:
+  enum Kind { BIND, LOOKUP };
+
+  HEnvironmentMarker(Kind kind, int index)
+      : kind_(kind), index_(index), next_simulate_(NULL) { }
+
+  Kind kind() { return kind_; }
+  int index() { return index_; }
+  HSimulate* next_simulate() { return next_simulate_; }
+  void set_next_simulate(HSimulate* simulate) {
+    next_simulate_ = simulate;
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) {
+    return Representation::None();
+  }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+#ifdef DEBUG
+  void set_closure(Handle<JSFunction> closure) {
+    ASSERT(closure_.is_null());
+    ASSERT(!closure.is_null());
+    closure_ = closure;
+  }
+  Handle<JSFunction> closure() const { return closure_; }
+#endif
+
+  DECLARE_CONCRETE_INSTRUCTION(EnvironmentMarker);
+
+ private:
+  Kind kind_;
+  int index_;
+  HSimulate* next_simulate_;
+
+#ifdef DEBUG
+  Handle<JSFunction> closure_;
+#endif
 };
 
 
@@ -1930,7 +2009,8 @@
                 InliningKind inlining_kind,
                 Variable* arguments_var,
                 ZoneList<HValue*>* arguments_values,
-                bool undefined_receiver)
+                bool undefined_receiver,
+                Zone* zone)
       : closure_(closure),
         arguments_count_(arguments_count),
         arguments_pushed_(false),
@@ -1938,9 +2018,13 @@
         inlining_kind_(inlining_kind),
         arguments_var_(arguments_var),
         arguments_values_(arguments_values),
-        undefined_receiver_(undefined_receiver) {
+        undefined_receiver_(undefined_receiver),
+        return_targets_(2, zone) {
   }
 
+  void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
+  ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; }
+
   virtual void PrintDataTo(StringStream* stream);
 
   Handle<JSFunction> closure() const { return closure_; }
@@ -1969,6 +2053,7 @@
   Variable* arguments_var_;
   ZoneList<HValue*>* arguments_values_;
   bool undefined_receiver_;
+  ZoneList<HBasicBlock*> return_targets_;
 };
 
 
@@ -2449,7 +2534,7 @@
  public:
   explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) {
     set_type(HType::Smi());
-    set_representation(Representation::Tagged());
+    set_representation(Representation::Smi());
     SetFlag(kUseGVN);
     SetGVNFlag(kDependsOnMaps);
   }
@@ -2940,8 +3025,7 @@
   HPhi(int merged_index, Zone* zone)
       : inputs_(2, zone),
         merged_index_(merged_index),
-        phi_id_(-1),
-        is_convertible_to_integer_(true) {
+        phi_id_(-1) {
     for (int i = 0; i < Representation::kNumRepresentations; i++) {
       non_phi_uses_[i] = 0;
       indirect_uses_[i] = 0;
@@ -2959,6 +3043,9 @@
   virtual Representation RequiredInputRepresentation(int index) {
     return representation();
   }
+  virtual Representation KnownOptimalRepresentation() {
+    return representation();
+  }
   virtual HType CalculateInferredType();
   virtual int OperandCount() { return inputs_.length(); }
   virtual HValue* OperandAt(int index) const { return inputs_[index]; }
@@ -3014,28 +3101,6 @@
   }
   virtual Opcode opcode() const { return HValue::kPhi; }
 
-  virtual bool IsConvertibleToInteger() const {
-    return is_convertible_to_integer_;
-  }
-
-  void set_is_convertible_to_integer(bool b) {
-    is_convertible_to_integer_ = b;
-  }
-
-  bool AllOperandsConvertibleToInteger() {
-    for (int i = 0; i < OperandCount(); ++i) {
-      if (!OperandAt(i)->IsConvertibleToInteger()) {
-        if (FLAG_trace_representation) {
-          HValue* input = OperandAt(i);
-          PrintF("#%d %s: Input #%d %s at %d is NCTI\n",
-                 id(), Mnemonic(), input->id(), input->Mnemonic(), i);
-        }
-        return false;
-      }
-    }
-    return true;
-  }
-
   void SimplifyConstantInputs();
 
   // TODO(titzer): we can't eliminate the receiver for generating backtraces
@@ -3059,7 +3124,6 @@
   int non_phi_uses_[Representation::kNumRepresentations];
   int indirect_uses_[Representation::kNumRepresentations];
   int phi_id_;
-  bool is_convertible_to_integer_;
 };
 
 
@@ -3149,9 +3213,10 @@
 
   Handle<Object> handle() {
     if (handle_.is_null()) {
+      Factory* factory = Isolate::Current()->factory();
       // Default arguments to is_not_in_new_space depend on this heap number
       // to be tenured so that it's guaranteed not be be located in new space.
-      handle_ = FACTORY->NewNumber(double_value_, TENURED);
+      handle_ = factory->NewNumber(double_value_, TENURED);
     }
     AllowDeferredHandleDereference smi_check;
     ASSERT(has_int32_value_ || !handle_->IsSmi());
@@ -3196,8 +3261,11 @@
     return Representation::None();
   }
 
-  virtual bool IsConvertibleToInteger() const {
-    return has_int32_value_;
+  virtual Representation KnownOptimalRepresentation() {
+    if (HasSmiValue()) return Representation::Smi();
+    if (HasInteger32Value()) return Representation::Integer32();
+    if (HasNumberValue()) return Representation::Double();
+    return Representation::Tagged();
   }
 
   virtual bool EmitAtUses() { return !representation().IsDouble(); }
@@ -3211,9 +3279,7 @@
     ASSERT(HasInteger32Value());
     return int32_value_;
   }
-  bool HasSmiValue() const {
-    return has_smi_value_;
-  }
+  bool HasSmiValue() const { return has_smi_value_; }
   bool HasDoubleValue() const { return has_double_value_; }
   double DoubleValue() const {
     ASSERT(HasDoubleValue());
@@ -4350,7 +4416,12 @@
   static HInstruction* New(Zone* zone,
                            HValue* context,
                            HValue* left,
-                           HValue* right);
+                           HValue* right,
+                           bool has_fixed_right_arg,
+                           int fixed_right_arg_value);
+
+  bool has_fixed_right_arg() const { return has_fixed_right_arg_; }
+  int fixed_right_arg_value() const { return fixed_right_arg_value_; }
 
   bool HasPowerOf2Divisor() {
     if (right()->IsConstant() &&
@@ -4374,11 +4445,20 @@
   virtual Range* InferRange(Zone* zone);
 
  private:
-  HMod(HValue* context, HValue* left, HValue* right)
-      : HArithmeticBinaryOperation(context, left, right) {
+  HMod(HValue* context,
+       HValue* left,
+       HValue* right,
+       bool has_fixed_right_arg,
+       int fixed_right_arg_value)
+      : HArithmeticBinaryOperation(context, left, right),
+        has_fixed_right_arg_(has_fixed_right_arg),
+        fixed_right_arg_value_(fixed_right_arg_value) {
     SetFlag(kCanBeDivByZero);
     SetFlag(kCanOverflow);
   }
+
+  const bool has_fixed_right_arg_;
+  const int fixed_right_arg_value_;
 };
 
 
@@ -4716,6 +4796,11 @@
     return incoming_value_;
   }
 
+  virtual Representation KnownOptimalRepresentation() {
+    if (incoming_value_ == NULL) return Representation::None();
+    return incoming_value_->KnownOptimalRepresentation();
+  }
+
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
 
  private:
@@ -4799,48 +4884,6 @@
 };
 
 
-class HAllocateObject: public HTemplateInstruction<1> {
- public:
-  HAllocateObject(HValue* context, Handle<JSFunction> constructor)
-      : constructor_(constructor) {
-    SetOperandAt(0, context);
-    set_representation(Representation::Tagged());
-    SetGVNFlag(kChangesNewSpacePromotion);
-    constructor_initial_map_ = constructor->has_initial_map()
-        ? Handle<Map>(constructor->initial_map())
-        : Handle<Map>::null();
-    // If slack tracking finished, the instance size and property counts
-    // remain unchanged so that we can allocate memory for the object.
-    ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress());
-  }
-
-  // Maximum instance size for which allocations will be inlined.
-  static const int kMaxSize = 64 * kPointerSize;
-
-  HValue* context() { return OperandAt(0); }
-  Handle<JSFunction> constructor() { return constructor_; }
-  Handle<Map> constructor_initial_map() { return constructor_initial_map_; }
-
-  virtual Representation RequiredInputRepresentation(int index) {
-    return Representation::Tagged();
-  }
-  virtual Handle<Map> GetMonomorphicJSObjectMap() {
-    ASSERT(!constructor_initial_map_.is_null());
-    return constructor_initial_map_;
-  }
-  virtual HType CalculateInferredType();
-
-  DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
-
- private:
-  // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
-  //  virtual bool IsDeletable() const { return true; }
-
-  Handle<JSFunction> constructor_;
-  Handle<Map> constructor_initial_map_;
-};
-
-
 class HAllocate: public HTemplateInstruction<2> {
  public:
   enum Flags {
@@ -4859,6 +4902,9 @@
     SetGVNFlag(kChangesNewSpacePromotion);
   }
 
+  // Maximum instance size for which allocations will be inlined.
+  static const int kMaxInlineSize = 64 * kPointerSize;
+
   static Flags DefaultFlags() {
     return CAN_ALLOCATE_IN_NEW_SPACE;
   }
@@ -4883,6 +4929,14 @@
     }
   }
 
+  virtual Handle<Map> GetMonomorphicJSObjectMap() {
+    return known_initial_map_;
+  }
+
+  void set_known_initial_map(Handle<Map> known_initial_map) {
+    known_initial_map_ = known_initial_map;
+  }
+
   virtual HType CalculateInferredType();
 
   bool CanAllocateInNewSpace() const {
@@ -4917,6 +4971,7 @@
  private:
   HType type_;
   Flags flags_;
+  Handle<Map> known_initial_map_;
 };
 
 
@@ -4960,7 +5015,6 @@
         new_space_dominator);
   }
   if (object != new_space_dominator) return true;
-  if (object->IsAllocateObject()) return false;
   if (object->IsAllocate()) {
     return !HAllocate::cast(object)->GuaranteedInNewSpace();
   }
@@ -5192,6 +5246,10 @@
     return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
   }
 
+  static HObjectAccess ForPrototypeOrInitialMap() {
+    return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
+  }
+
   static HObjectAccess ForMap() {
     return HObjectAccess(kMaps, JSObject::kMapOffset);
   }
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index f543d4e..5da6d52 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -34,6 +34,7 @@
 #include "codegen.h"
 #include "full-codegen.h"
 #include "hashmap.h"
+#include "hydrogen-environment-liveness.h"
 #include "lithium-allocator.h"
 #include "parser.h"
 #include "scopeinfo.h"
@@ -73,6 +74,7 @@
       last_instruction_index_(-1),
       deleted_phis_(4, graph->zone()),
       parent_loop_header_(NULL),
+      inlined_entry_block_(NULL),
       is_inline_return_target_(false),
       is_deoptimizing_(false),
       dominates_loop_successors_(false),
@@ -132,10 +134,13 @@
     HDeoptimize::UseEnvironment has_uses) {
   ASSERT(HasEnvironment());
   if (has_uses == HDeoptimize::kNoUses)
-    return new(zone()) HDeoptimize(0, zone());
+    return new(zone()) HDeoptimize(0, 0, 0, zone());
 
   HEnvironment* environment = last_environment();
-  HDeoptimize* instr = new(zone()) HDeoptimize(environment->length(), zone());
+  int first_local_index = environment->first_local_index();
+  int first_expression_index = environment->first_expression_index();
+  HDeoptimize* instr = new(zone()) HDeoptimize(
+      environment->length(), first_local_index, first_expression_index, zone());
   for (int i = 0; i < environment->length(); i++) {
     HValue* val = environment->values()->at(i);
     instr->AddEnvironmentValue(val, zone());
@@ -158,6 +163,9 @@
 
   HSimulate* instr =
       new(zone()) HSimulate(ast_id, pop_count, zone(), removable);
+#ifdef DEBUG
+  instr->set_closure(environment->closure());
+#endif
   // Order of pushed values: newest (top of stack) first. This allows
   // HSimulate::MergeWith() to easily append additional pushed values
   // that are older (from further down the stack).
@@ -194,7 +202,7 @@
 
   if (block->IsInlineReturnTarget()) {
     AddInstruction(new(zone()) HLeaveInlined());
-    last_environment_ = last_environment()->DiscardInlined(drop_extra);
+    UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
   }
 
   if (add_simulate) AddSimulate(BailoutId::None());
@@ -211,7 +219,7 @@
   ASSERT(target->IsInlineReturnTarget());
   ASSERT(return_value != NULL);
   AddInstruction(new(zone()) HLeaveInlined());
-  last_environment_ = last_environment()->DiscardInlined(drop_extra);
+  UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
   last_environment()->Push(return_value);
   AddSimulate(BailoutId::None());
   HGoto* instr = new(zone()) HGoto(target);
@@ -226,6 +234,12 @@
 }
 
 
+void HBasicBlock::UpdateEnvironment(HEnvironment* env) {
+  last_environment_ = env;
+  graph()->update_maximum_environment_size(env->first_expression_index());
+}
+
+
 void HBasicBlock::SetJoinId(BailoutId ast_id) {
   int length = predecessors_.length();
   ASSERT(length > 0);
@@ -709,8 +723,7 @@
 HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left,
                                                      Handle<Map> map) {
   HCompareMap* compare =
-      new(zone()) HCompareMap(left, map,
-                              first_true_block_, first_false_block_);
+      new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_);
   AddCompare(compare);
   return compare;
 }
@@ -789,9 +802,16 @@
   did_then_ = true;
   if (needs_compare_) {
     // Handle if's without any expressions, they jump directly to the "else"
-    // branch.
-    builder_->current_block()->GotoNoSimulate(first_false_block_);
-    first_true_block_ = NULL;
+    // branch. However, we must pretend that the "then" branch is reachable,
+    // so that the graph builder visits it and sees any live range extending
+    // constructs within it.
+    HConstant* constant_false = builder_->graph()->GetConstantFalse();
+    ToBooleanStub::Types boolean_type = ToBooleanStub::no_types();
+    boolean_type.Add(ToBooleanStub::BOOLEAN);
+    HBranch* branch =
+        new(zone()) HBranch(constant_false, first_true_block_,
+                            first_false_block_, boolean_type);
+    builder_->current_block()->Finish(branch);
   }
   builder_->set_current_block(first_true_block_);
 }
@@ -1766,15 +1786,25 @@
 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
                                               ElementsKind kind,
                                               HValue* allocation_site_payload,
-                                              AllocationSiteMode mode) :
+                                              bool disable_allocation_sites) :
         builder_(builder),
         kind_(kind),
-        allocation_site_payload_(allocation_site_payload) {
-  if (mode == DONT_TRACK_ALLOCATION_SITE) {
-    mode_ = mode;
-  } else {
-    mode_ = AllocationSiteInfo::GetMode(kind);
-  }
+        allocation_site_payload_(allocation_site_payload),
+        constructor_function_(NULL) {
+  mode_ = disable_allocation_sites
+      ? DONT_TRACK_ALLOCATION_SITE
+      : AllocationSiteInfo::GetMode(kind);
+}
+
+
+HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
+                                              ElementsKind kind,
+                                              HValue* constructor_function) :
+    builder_(builder),
+    kind_(kind),
+    mode_(DONT_TRACK_ALLOCATION_SITE),
+    allocation_site_payload_(NULL),
+    constructor_function_(constructor_function) {
 }
 
 
@@ -1795,6 +1825,16 @@
 }
 
 
+HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
+  // Find the map near the constructor function
+  HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
+  return AddInstruction(
+      builder()->BuildLoadNamedField(constructor_function_,
+                                     access,
+                                     Representation::Tagged()));
+}
+
+
 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
     HValue* length_node) {
   HValue* context = builder()->environment()->LookupContext();
@@ -1881,7 +1921,12 @@
   AddInstruction(new_object);
 
   // Fill in the fields: map, properties, length
-  HValue* map = EmitMapCode(context);
+  HValue* map;
+  if (constructor_function_ != NULL) {
+    map = EmitInternalMapCode();
+  } else {
+    map = EmitMapCode(context);
+  }
   elements_location_ = builder()->BuildJSArrayHeader(new_object,
                                                      map,
                                                      mode_,
@@ -2015,7 +2060,8 @@
       use_optimistic_licm_(false),
       has_soft_deoptimize_(false),
       depends_on_empty_array_proto_elements_(false),
-      type_change_checksum_(0) {
+      type_change_checksum_(0),
+      maximum_environment_size_(0) {
   if (info->IsStub()) {
     HydrogenCodeStub* stub = info->code_stub();
     CodeStubInterfaceDescriptor* descriptor =
@@ -2880,23 +2926,6 @@
   }
 
   // Use the phi reachability information from step 2 to
-  // push information about values which can't be converted to integer
-  // without deoptimization through the phi use-def chains, avoiding
-  // unnecessary deoptimizations later.
-  for (int i = 0; i < phi_count; ++i) {
-    HPhi* phi = phi_list->at(i);
-    bool cti = phi->AllOperandsConvertibleToInteger();
-    if (cti) continue;
-
-    for (BitVector::Iterator it(connected_phis.at(i));
-         !it.Done();
-         it.Advance()) {
-      HPhi* phi = phi_list->at(it.Current());
-      phi->set_is_convertible_to_integer(false);
-    }
-  }
-
-  // Use the phi reachability information from step 2 to
   // sum up the non-phi use counts of all connected phis.
   for (int i = 0; i < phi_count; ++i) {
     HPhi* phi = phi_list->at(i);
@@ -3522,8 +3551,8 @@
     if (owner->ast_context()->IsTest()) {
       HBasicBlock* if_true = owner->graph()->CreateBasicBlock();
       HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
-      if_true->MarkAsInlineReturnTarget();
-      if_false->MarkAsInlineReturnTarget();
+      if_true->MarkAsInlineReturnTarget(owner->current_block());
+      if_false->MarkAsInlineReturnTarget(owner->current_block());
       TestContext* outer_test_context = TestContext::cast(owner->ast_context());
       Expression* cond = outer_test_context->condition();
       // The AstContext constructor pushed on the context stack.  This newed
@@ -3531,7 +3560,7 @@
       test_context_ = new TestContext(owner, cond, if_true, if_false);
     } else {
       function_return_ = owner->graph()->CreateBasicBlock();
-      function_return()->MarkAsInlineReturnTarget();
+      function_return()->MarkAsInlineReturnTarget(owner->current_block());
     }
     // Set this after possibly allocating a new TestContext above.
     call_context_ = owner->ast_context();
@@ -3950,6 +3979,11 @@
   Verify(true);
 #endif
 
+  if (FLAG_analyze_environment_liveness) {
+    EnvironmentSlotLivenessAnalyzer esla(this);
+    esla.AnalyzeAndTrim();
+  }
+
   PropagateDeoptimizingMark();
   if (!CheckConstPhiUses()) {
     *bailout_reason = SmartArrayPointer<char>(StrDup(
@@ -4989,11 +5023,7 @@
 
     if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
       if (!clause->IsSmiCompare()) {
-        // Finish with deoptimize and add uses of enviroment values to
-        // account for invisible uses.
-        current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
-        set_current_block(NULL);
-        break;
+        AddSoftDeoptimize();
       }
 
       HCompareIDAndBranch* compare_ =
@@ -5017,7 +5047,7 @@
   }
 
   // Save the current block to use for the default or to join with the
-  // exit.  This block is NULL if we deoptimized.
+  // exit.
   HBasicBlock* last_block = current_block();
 
   if (not_string_block != NULL) {
@@ -5616,7 +5646,7 @@
 
     case Variable::PARAMETER:
     case Variable::LOCAL: {
-      HValue* value = environment()->Lookup(variable);
+      HValue* value = LookupAndMakeLive(variable);
       if (value == graph()->GetConstantHole()) {
         ASSERT(IsDeclaredVariableMode(variable->mode()) &&
                variable->mode() != VAR);
@@ -6583,7 +6613,7 @@
         if (var->mode() == CONST)  {
           return Bailout("unsupported const compound assignment");
         }
-        Bind(var, Top());
+        BindIfLive(var, Top());
         break;
 
       case Variable::CONTEXT: {
@@ -6808,7 +6838,7 @@
         // permitted.
         CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
         HValue* value = Pop();
-        Bind(var, value);
+        BindIfLive(var, value);
         return ast_context()->ReturnValue(value);
       }
 
@@ -8008,7 +8038,8 @@
                                 function_state()->inlining_kind(),
                                 function->scope()->arguments(),
                                 arguments_values,
-                                undefined_receiver);
+                                undefined_receiver,
+                                zone());
   function_state()->set_entry(enter_inlined);
   AddInstruction(enter_inlined);
 
@@ -8088,6 +8119,8 @@
     HBasicBlock* if_true = inlined_test_context()->if_true();
     HBasicBlock* if_false = inlined_test_context()->if_false();
 
+    HEnterInlined* entry = function_state()->entry();
+
     // Pop the return test context from the expression context stack.
     ASSERT(ast_context() == inlined_test_context());
     ClearInlinedTestContext();
@@ -8095,11 +8128,13 @@
 
     // Forward to the real test context.
     if (if_true->HasPredecessor()) {
+      entry->RegisterReturnTarget(if_true, zone());
       if_true->SetJoinId(ast_id);
       HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
       if_true->Goto(true_target, function_state());
     }
     if (if_false->HasPredecessor()) {
+      entry->RegisterReturnTarget(if_false, zone());
       if_false->SetJoinId(ast_id);
       HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
       if_false->Goto(false_target, function_state());
@@ -8108,6 +8143,7 @@
     return true;
 
   } else if (function_return()->HasPredecessor()) {
+    function_state()->entry()->RegisterReturnTarget(function_return(), zone());
     function_return()->SetJoinId(ast_id);
     set_current_block(function_return());
   } else {
@@ -8413,7 +8449,7 @@
 
   VariableProxy* arg_two = args->at(1)->AsVariableProxy();
   if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
-  HValue* arg_two_value = environment()->Lookup(arg_two->var());
+  HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
   if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
 
   // Found pattern f.apply(receiver, arguments).
@@ -8758,7 +8794,8 @@
 static bool IsAllocationInlineable(Handle<JSFunction> constructor) {
   return constructor->has_initial_map() &&
       constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
-      constructor->initial_map()->instance_size() < HAllocateObject::kMaxSize;
+      constructor->initial_map()->instance_size() < HAllocate::kMaxInlineSize &&
+      constructor->initial_map()->InitialPropertiesLength() == 0;
 }
 
 
@@ -8768,6 +8805,7 @@
   ASSERT(current_block()->HasPredecessor());
   int argument_count = expr->arguments()->length() + 1;  // Plus constructor.
   HValue* context = environment()->LookupContext();
+  Factory* factory = isolate()->factory();
 
   if (FLAG_inline_construct &&
       expr->IsMonomorphic() &&
@@ -8787,20 +8825,84 @@
       constructor->shared()->CompleteInobjectSlackTracking();
     }
 
-    // Replace the constructor function with a newly allocated receiver.
-    HInstruction* receiver = new(zone()) HAllocateObject(context, constructor);
-    // Index of the receiver from the top of the expression stack.
+    // Calculate instance size from initial map of constructor.
+    ASSERT(constructor->has_initial_map());
+    Handle<Map> initial_map(constructor->initial_map());
+    int instance_size = initial_map->instance_size();
+    ASSERT(initial_map->InitialPropertiesLength() == 0);
+
+    // Allocate an instance of the implicit receiver object.
+    HValue* size_in_bytes =
+        AddInstruction(new(zone()) HConstant(instance_size,
+            Representation::Integer32()));
+
+    HAllocate::Flags flags = HAllocate::DefaultFlags();
+    if (FLAG_pretenuring_call_new &&
+        isolate()->heap()->ShouldGloballyPretenure()) {
+      flags = static_cast<HAllocate::Flags>(
+          flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
+    }
+
+    HInstruction* receiver =
+        AddInstruction(new(zone()) HAllocate(context,
+                                             size_in_bytes,
+                                             HType::JSObject(),
+                                             flags));
+    HAllocate::cast(receiver)->set_known_initial_map(initial_map);
+
+    // Load the initial map from the constructor.
+    HValue* constructor_value =
+        AddInstruction(new(zone()) HConstant(constructor,
+            Representation::Tagged()));
+    HValue* initial_map_value =
+        AddLoad(constructor_value, HObjectAccess::ForJSObjectOffset(
+            JSFunction::kPrototypeOrInitialMapOffset));
+
+    // Initialize map and fields of the newly allocated object.
+    { NoObservableSideEffectsScope no_effects(this);
+      ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
+      AddStore(receiver,
+               HObjectAccess::ForJSObjectOffset(JSObject::kMapOffset),
+               initial_map_value);
+      HValue* empty_fixed_array =
+          AddInstruction(new(zone()) HConstant(factory->empty_fixed_array(),
+              Representation::Tagged()));
+      AddStore(receiver,
+               HObjectAccess::ForJSObjectOffset(JSObject::kPropertiesOffset),
+               empty_fixed_array);
+      AddStore(receiver,
+               HObjectAccess::ForJSObjectOffset(JSObject::kElementsOffset),
+               empty_fixed_array);
+      if (initial_map->inobject_properties() != 0) {
+        HConstant* undefined = graph()->GetConstantUndefined();
+        for (int i = 0; i < initial_map->inobject_properties(); i++) {
+          int property_offset = JSObject::kHeaderSize + i * kPointerSize;
+          AddStore(receiver,
+                   HObjectAccess::ForJSObjectOffset(property_offset),
+                   undefined);
+        }
+      }
+    }
+
+    // Replace the constructor function with a newly allocated receiver using
+    // the index of the receiver from the top of the expression stack.
     const int receiver_index = argument_count - 1;
-    AddInstruction(receiver);
     ASSERT(environment()->ExpressionStackAt(receiver_index) == function);
     environment()->SetExpressionStackAt(receiver_index, receiver);
 
     if (TryInlineConstruct(expr, receiver)) return;
 
-    // TODO(mstarzinger): For now we remove the previous HAllocateObject and
-    // add HPushArgument for the arguments in case inlining failed.  What we
-    // actually should do is emit HInvokeFunction on the constructor instead
-    // of using HCallNew as a fallback.
+    // TODO(mstarzinger): For now we remove the previous HAllocate and all
+    // corresponding instructions and instead add HPushArgument for the
+    // arguments in case inlining failed.  What we actually should do is for
+    // inlining to try to build a subgraph without mutating the parent graph.
+    HInstruction* instr = current_block()->last();
+    while (instr != initial_map_value) {
+      HInstruction* prev_instr = instr->previous();
+      instr->DeleteAndReplaceWith(NULL);
+      instr = prev_instr;
+    }
+    initial_map_value->DeleteAndReplaceWith(NULL);
     receiver->DeleteAndReplaceWith(NULL);
     check->DeleteAndReplaceWith(NULL);
     environment()->SetExpressionStackAt(receiver_index, function);
@@ -9120,7 +9222,7 @@
 
       case Variable::PARAMETER:
       case Variable::LOCAL:
-        Bind(var, after);
+        BindIfLive(var, after);
         break;
 
       case Variable::CONTEXT: {
@@ -9351,7 +9453,8 @@
   TypeInfo left_info = expr->left_type();
   TypeInfo right_info = expr->right_type();
   TypeInfo result_info = expr->result_type();
-  TypeInfo combined_info;
+  bool has_fixed_right_arg = expr->has_fixed_right_arg();
+  int fixed_right_arg_value = expr->fixed_right_arg_value();
   Representation left_rep = ToRepresentation(left_info);
   Representation right_rep = ToRepresentation(right_info);
   Representation result_rep = ToRepresentation(result_info);
@@ -9381,7 +9484,12 @@
       instr = HMul::New(zone(), context, left, right);
       break;
     case Token::MOD:
-      instr = HMod::New(zone(), context, left, right);
+      instr = HMod::New(zone(),
+                        context,
+                        left,
+                        right,
+                        has_fixed_right_arg,
+                        fixed_right_arg_value);
       break;
     case Token::DIV:
       instr = HDiv::New(zone(), context, left, right);
@@ -10236,7 +10344,7 @@
     case Variable::LOCAL: {
       CHECK_ALIVE(VisitForValue(declaration->fun()));
       HValue* value = Pop();
-      environment()->Bind(variable, value);
+      BindIfLive(variable, value);
       break;
     }
     case Variable::CONTEXT: {
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 7a57448..db607d5 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -66,7 +66,6 @@
   HInstruction* first() const { return first_; }
   HInstruction* last() const { return last_; }
   void set_last(HInstruction* instr) { last_ = instr; }
-  HInstruction* GetLastInstruction();
   HControlInstruction* end() const { return end_; }
   HLoopInformation* loop_information() const { return loop_information_; }
   const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; }
@@ -109,9 +108,13 @@
   int LoopNestingDepth() const;
 
   void SetInitialEnvironment(HEnvironment* env);
-  void ClearEnvironment() { last_environment_ = NULL; }
+  void ClearEnvironment() {
+    ASSERT(IsFinished());
+    ASSERT(end()->SuccessorCount() == 0);
+    last_environment_ = NULL;
+  }
   bool HasEnvironment() const { return last_environment_ != NULL; }
-  void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; }
+  void UpdateEnvironment(HEnvironment* env);
   HBasicBlock* parent_loop_header() const { return parent_loop_header_; }
 
   void set_parent_loop_header(HBasicBlock* block) {
@@ -155,7 +158,11 @@
   // Simulate (caller's environment)
   // Goto (target block)
   bool IsInlineReturnTarget() const { return is_inline_return_target_; }
-  void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; }
+  void MarkAsInlineReturnTarget(HBasicBlock* inlined_entry_block) {
+    is_inline_return_target_ = true;
+    inlined_entry_block_ = inlined_entry_block;
+  }
+  HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
 
   bool IsDeoptimizing() const { return is_deoptimizing_; }
   void MarkAsDeoptimizing() { is_deoptimizing_ = true; }
@@ -198,10 +205,12 @@
   int last_instruction_index_;
   ZoneList<int> deleted_phis_;
   HBasicBlock* parent_loop_header_;
-  bool is_inline_return_target_;
-  bool is_deoptimizing_;
-  bool dominates_loop_successors_;
-  bool is_osr_entry_;
+  // For blocks marked as inline return target: the block with HEnterInlined.
+  HBasicBlock* inlined_entry_block_;
+  bool is_inline_return_target_ : 1;
+  bool is_deoptimizing_ : 1;
+  bool dominates_loop_successors_ : 1;
+  bool is_osr_entry_ : 1;
 };
 
 
@@ -285,6 +294,7 @@
   void RestoreActualValues();
   void DeadCodeElimination(const char *phase_name);
   void PropagateDeoptimizingMark();
+  void AnalyzeAndPruneEnvironmentLiveness();
 
   // Returns false if there are phi-uses of the arguments-object
   // which are not supported by the optimizing compiler.
@@ -360,6 +370,13 @@
     return type_change_checksum_;
   }
 
+  void update_maximum_environment_size(int environment_size) {
+    if (environment_size > maximum_environment_size_) {
+      maximum_environment_size_ = environment_size;
+    }
+  }
+  int maximum_environment_size() { return maximum_environment_size_; }
+
   bool use_optimistic_licm() {
     return use_optimistic_licm_;
   }
@@ -453,6 +470,7 @@
   bool has_soft_deoptimize_;
   bool depends_on_empty_array_proto_elements_;
   int type_change_checksum_;
+  int maximum_environment_size_;
 
   DISALLOW_COPY_AND_ASSIGN(HGraph);
 };
@@ -514,6 +532,10 @@
     return parameter_count() + specials_count() + local_count();
   }
 
+  int first_local_index() const {
+    return parameter_count() + specials_count();
+  }
+
   void Bind(Variable* variable, HValue* value) {
     Bind(IndexFor(variable), value);
   }
@@ -611,6 +633,22 @@
     values_[index] = value;
   }
 
+  // Map a variable to an environment index.  Parameter indices are shifted
+  // by 1 (receiver is parameter index -1 but environment index 0).
+  // Stack-allocated local indices are shifted by the number of parameters.
+  int IndexFor(Variable* variable) const {
+    ASSERT(variable->IsStackAllocated());
+    int shift = variable->IsParameter()
+        ? 1
+        : parameter_count_ + specials_count_;
+    return variable->index() + shift;
+  }
+
+  bool is_local_index(int i) const {
+    return i >= first_local_index() &&
+           i < first_expression_index();
+  }
+
   void PrintTo(StringStream* stream);
   void PrintToStd();
 
@@ -638,17 +676,6 @@
   void Initialize(int parameter_count, int local_count, int stack_height);
   void Initialize(const HEnvironment* other);
 
-  // Map a variable to an environment index.  Parameter indices are shifted
-  // by 1 (receiver is parameter index -1 but environment index 0).
-  // Stack-allocated local indices are shifted by the number of parameters.
-  int IndexFor(Variable* variable) const {
-    ASSERT(variable->IsStackAllocated());
-    int shift = variable->IsParameter()
-        ? 1
-        : parameter_count_ + specials_count_;
-    return variable->index() + shift;
-  }
-
   Handle<JSFunction> closure_;
   // Value array [parameters] [specials] [locals] [temporaries].
   ZoneList<HValue*> values_;
@@ -1233,7 +1260,11 @@
     JSArrayBuilder(HGraphBuilder* builder,
                    ElementsKind kind,
                    HValue* allocation_site_payload,
-                   AllocationSiteMode mode);
+                   bool disable_allocation_sites);
+
+    JSArrayBuilder(HGraphBuilder* builder,
+                   ElementsKind kind,
+                   HValue* constructor_function);
 
     HValue* AllocateEmptyArray();
     HValue* AllocateArray(HValue* capacity, HValue* length_field,
@@ -1256,6 +1287,7 @@
     }
 
     HValue* EmitMapCode(HValue* context);
+    HValue* EmitInternalMapCode();
     HValue* EstablishEmptyArrayAllocationSize();
     HValue* EstablishAllocationSize(HValue* length_node);
     HValue* AllocateArray(HValue* size_in_bytes, HValue* capacity,
@@ -1265,6 +1297,7 @@
     ElementsKind kind_;
     AllocationSiteMode mode_;
     HValue* allocation_site_payload_;
+    HValue* constructor_function_;
     HInnerAllocatedObject* elements_location_;
   };
 
@@ -1523,6 +1556,45 @@
   HValue* Top() const { return environment()->Top(); }
   void Drop(int n) { environment()->Drop(n); }
   void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
+  bool IsEligibleForEnvironmentLivenessAnalysis(Variable* var,
+                                                int index,
+                                                HValue* value,
+                                                HEnvironment* env) {
+    if (!FLAG_analyze_environment_liveness) return false;
+    // |this| and |arguments| are always live; zapping parameters isn't
+    // safe because function.arguments can inspect them at any time.
+    return !var->is_this() &&
+           !var->is_arguments() &&
+           !value->IsArgumentsObject() &&
+           env->is_local_index(index);
+  }
+  void BindIfLive(Variable* var, HValue* value) {
+    HEnvironment* env = environment();
+    int index = env->IndexFor(var);
+    env->Bind(index, value);
+    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
+      HEnvironmentMarker* bind =
+          new(zone()) HEnvironmentMarker(HEnvironmentMarker::BIND, index);
+      AddInstruction(bind);
+#ifdef DEBUG
+      bind->set_closure(env->closure());
+#endif
+    }
+  }
+  HValue* LookupAndMakeLive(Variable* var) {
+    HEnvironment* env = environment();
+    int index = env->IndexFor(var);
+    HValue* value = env->Lookup(index);
+    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
+      HEnvironmentMarker* lookup =
+          new(zone()) HEnvironmentMarker(HEnvironmentMarker::LOOKUP, index);
+      AddInstruction(lookup);
+#ifdef DEBUG
+      lookup->set_closure(env->closure());
+#endif
+    }
+    return value;
+  }
 
   // The value of the arguments object is allowed in some but not most value
   // contexts.  (It's allowed in all effect contexts and disallowed in all
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 4420102..bf4ee94 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -1459,14 +1459,20 @@
 
   // Run the native code for the InternalArray function called as a normal
   // function.
-  ArrayNativeCode(masm, false, &generic_array_code);
+  if (FLAG_optimize_constructed_arrays) {
+    // tail call a stub
+    InternalArrayConstructorStub stub(masm->isolate());
+    __ TailCallStub(&stub);
+  } else {
+    ArrayNativeCode(masm, false, &generic_array_code);
 
-  // Jump to the generic internal array code in case the specialized code cannot
-  // handle the construction.
-  __ bind(&generic_array_code);
-  Handle<Code> array_code =
-      masm->isolate()->builtins()->InternalArrayCodeGeneric();
-  __ jmp(array_code, RelocInfo::CODE_TARGET);
+    // Jump to the generic internal array code in case the specialized code
+    // cannot handle the construction.
+    __ bind(&generic_array_code);
+    Handle<Code> array_code =
+        masm->isolate()->builtins()->InternalArrayCodeGeneric();
+    __ jmp(array_code, RelocInfo::CODE_TARGET);
+  }
 }
 
 
@@ -1492,14 +1498,24 @@
   }
 
   // Run the native code for the Array function called as a normal function.
-  ArrayNativeCode(masm, false, &generic_array_code);
+  if (FLAG_optimize_constructed_arrays) {
+    // tail call a stub
+    Handle<Object> undefined_sentinel(
+        masm->isolate()->heap()->undefined_value(),
+        masm->isolate());
+    __ mov(ebx, Immediate(undefined_sentinel));
+    ArrayConstructorStub stub(masm->isolate());
+    __ TailCallStub(&stub);
+  } else {
+    ArrayNativeCode(masm, false, &generic_array_code);
 
-  // Jump to the generic array code in case the specialized code cannot handle
-  // the construction.
-  __ bind(&generic_array_code);
-  Handle<Code> array_code =
-      masm->isolate()->builtins()->ArrayCodeGeneric();
-  __ jmp(array_code, RelocInfo::CODE_TARGET);
+    // Jump to the generic internal array code in case the specialized code
+    // cannot handle the construction.
+    __ bind(&generic_array_code);
+    Handle<Code> array_code =
+        masm->isolate()->builtins()->ArrayCodeGeneric();
+    __ jmp(array_code, RelocInfo::CODE_TARGET);
+  }
 }
 
 
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index aa533bf..8cb4725 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -142,6 +142,28 @@
 }
 
 
+static void InitializeInternalArrayConstructorDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor,
+    int constant_stack_parameter_count) {
+  // register state
+  // eax -- number of arguments
+  // edi -- constructor function
+  static Register registers[] = { edi };
+  descriptor->register_param_count_ = 1;
+
+  if (constant_stack_parameter_count != 0) {
+    // stack param count needs (constructor pointer, and single argument)
+    descriptor->stack_parameter_count_ = &eax;
+  }
+  descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
+  descriptor->register_params_ = registers;
+  descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
+  descriptor->deoptimization_handler_ =
+      FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
+}
+
+
 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -163,6 +185,27 @@
 }
 
 
+void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+}
+
+
+void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+}
+
+
+void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+}
+
+
 void CompareNilICStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -566,12 +609,6 @@
   // Expects operands in edx, eax.
   static void LoadSSE2Smis(MacroAssembler* masm, Register scratch);
 
-  // Checks that the two floating point numbers loaded into xmm0 and xmm1
-  // have int32 values.
-  static void CheckSSE2OperandsAreInt32(MacroAssembler* masm,
-                                        Label* non_int32,
-                                        Register scratch);
-
   // Checks that |operand| has an int32 value. If |int32_result| is different
   // from |scratch|, it will contain that int32 value.
   static void CheckSSE2OperandIsInt32(MacroAssembler* masm,
@@ -1470,7 +1507,7 @@
 
 
 void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
-  Label call_runtime;
+  Label right_arg_changed, call_runtime;
 
   switch (op_) {
     case Token::ADD:
@@ -1491,6 +1528,13 @@
       UNREACHABLE();
   }
 
+  if (op_ == Token::MOD && has_fixed_right_arg_) {
+    // It is guaranteed that the value will fit into a Smi, because if it
+    // didn't, we wouldn't be here, see BinaryOp_Patch.
+    __ cmp(eax, Immediate(Smi::FromInt(fixed_right_arg_value())));
+    __ j(not_equal, &right_arg_changed);
+  }
+
   if (result_type_ == BinaryOpIC::UNINITIALIZED ||
       result_type_ == BinaryOpIC::SMI) {
     BinaryOpStub_GenerateSmiCode(
@@ -1502,6 +1546,7 @@
 
   // Code falls through if the result is not returned as either a smi or heap
   // number.
+  __ bind(&right_arg_changed);
   switch (op_) {
     case Token::ADD:
     case Token::SUB:
@@ -1604,8 +1649,7 @@
     case Token::MUL:
     case Token::DIV:
     case Token::MOD: {
-      Label not_floats;
-      Label not_int32;
+      Label not_floats, not_int32, right_arg_changed;
       if (CpuFeatures::IsSupported(SSE2)) {
         CpuFeatureScope use_sse2(masm, SSE2);
         // It could be that only SMIs have been seen at either the left
@@ -1621,8 +1665,15 @@
           __ JumpIfNotSmi(eax, &not_int32);
         }
         FloatingPointHelper::LoadSSE2Operands(masm, &not_floats);
-        FloatingPointHelper::CheckSSE2OperandsAreInt32(masm, &not_int32, ecx);
+        FloatingPointHelper::CheckSSE2OperandIsInt32(
+            masm, &not_int32, xmm0, ebx, ecx, xmm2);
+        FloatingPointHelper::CheckSSE2OperandIsInt32(
+            masm, &not_int32, xmm1, edi, ecx, xmm2);
         if (op_ == Token::MOD) {
+          if (has_fixed_right_arg_) {
+            __ cmp(edi, Immediate(fixed_right_arg_value()));
+            __ j(not_equal, &right_arg_changed);
+          }
           GenerateRegisterArgsPush(masm);
           __ InvokeBuiltin(Builtins::MOD, JUMP_FUNCTION);
         } else {
@@ -1675,6 +1726,7 @@
 
       __ bind(&not_floats);
       __ bind(&not_int32);
+      __ bind(&right_arg_changed);
       GenerateTypeTransition(masm);
       break;
     }
@@ -2766,14 +2818,6 @@
 }
 
 
-void FloatingPointHelper::CheckSSE2OperandsAreInt32(MacroAssembler* masm,
-                                                    Label* non_int32,
-                                                    Register scratch) {
-  CheckSSE2OperandIsInt32(masm, non_int32, xmm0, scratch, scratch, xmm2);
-  CheckSSE2OperandIsInt32(masm, non_int32, xmm1, scratch, scratch, xmm2);
-}
-
-
 void FloatingPointHelper::CheckSSE2OperandIsInt32(MacroAssembler* masm,
                                                   Label* non_int32,
                                                   XMMRegister operand,
@@ -3327,6 +3371,8 @@
 
 
 void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
+  Isolate* isolate = masm->isolate();
+
   // esp[0] : return address
   // esp[4] : number of parameters (tagged)
   // esp[8] : receiver displacement
@@ -3458,7 +3504,7 @@
   __ j(zero, &skip_parameter_map);
 
   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
-         Immediate(FACTORY->non_strict_arguments_elements_map()));
+         Immediate(isolate->factory()->non_strict_arguments_elements_map()));
   __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2))));
   __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax);
   __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi);
@@ -3479,7 +3525,7 @@
   __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS)));
   __ add(ebx, Operand(esp, 4 * kPointerSize));
   __ sub(ebx, eax);
-  __ mov(ecx, FACTORY->the_hole_value());
+  __ mov(ecx, isolate->factory()->the_hole_value());
   __ mov(edx, edi);
   __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize));
   // eax = loop variable (tagged)
@@ -3514,7 +3560,7 @@
   // esp[16] = address of receiver argument
   // Copy arguments header and remaining slots (if there are any).
   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
-         Immediate(FACTORY->fixed_array_map()));
+         Immediate(isolate->factory()->fixed_array_map()));
   __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
 
   Label arguments_loop, arguments_test;
@@ -3550,6 +3596,8 @@
 
 
 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
+  Isolate* isolate = masm->isolate();
+
   // esp[0] : return address
   // esp[4] : number of parameters
   // esp[8] : receiver displacement
@@ -3620,7 +3668,7 @@
   __ lea(edi, Operand(eax, Heap::kArgumentsObjectSizeStrict));
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
-         Immediate(FACTORY->fixed_array_map()));
+         Immediate(isolate->factory()->fixed_array_map()));
 
   __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
   // Untag the length for the loop below.
@@ -4777,7 +4825,11 @@
   __ j(not_equal, &slow);
 
   if (RecordCallTarget()) {
-    GenerateRecordCallTargetNoArray(masm);
+    if (FLAG_optimize_constructed_arrays) {
+      GenerateRecordCallTarget(masm);
+    } else {
+      GenerateRecordCallTargetNoArray(masm);
+    }
   }
 
   // Fast-case: Just invoke the function.
@@ -7818,8 +7870,12 @@
       TERMINAL_FAST_ELEMENTS_KIND);
   for (int i = 0; i <= to_index; ++i) {
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
-    T stub(kind);
+    T stub(kind, false);
     stub.GetCode(isolate)->set_is_pregenerated(true);
+    if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+      T stub1(kind, true);
+      stub1.GetCode(isolate)->set_is_pregenerated(true);
+    }
   }
 }
 
@@ -7834,6 +7890,21 @@
 }
 
 
+void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
+    Isolate* isolate) {
+  ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
+  for (int i = 0; i < 2; i++) {
+    // For internal arrays we only need a few things
+    InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
+    stubh1.GetCode(isolate)->set_is_pregenerated(true);
+    InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
+    stubh2.GetCode(isolate)->set_is_pregenerated(true);
+    InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
+    stubh3.GetCode(isolate)->set_is_pregenerated(true);
+  }
+}
+
+
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax : argc (only if argument_count_ == ANY)
@@ -7919,6 +7990,107 @@
 }
 
 
+void InternalArrayConstructorStub::GenerateCase(
+    MacroAssembler* masm, ElementsKind kind) {
+  Label not_zero_case, not_one_case;
+  Label normal_sequence;
+
+  __ test(eax, eax);
+  __ j(not_zero, &not_zero_case);
+  InternalArrayNoArgumentConstructorStub stub0(kind);
+  __ TailCallStub(&stub0);
+
+  __ bind(&not_zero_case);
+  __ cmp(eax, 1);
+  __ j(greater, &not_one_case);
+
+  if (IsFastPackedElementsKind(kind)) {
+    // We might need to create a holey array
+    // look at the first argument
+    __ mov(ecx, Operand(esp, kPointerSize));
+    __ test(ecx, ecx);
+    __ j(zero, &normal_sequence);
+
+    InternalArraySingleArgumentConstructorStub
+        stub1_holey(GetHoleyElementsKind(kind));
+    __ TailCallStub(&stub1_holey);
+  }
+
+  __ bind(&normal_sequence);
+  InternalArraySingleArgumentConstructorStub stub1(kind);
+  __ TailCallStub(&stub1);
+
+  __ bind(&not_one_case);
+  InternalArrayNArgumentsConstructorStub stubN(kind);
+  __ TailCallStub(&stubN);
+}
+
+
+void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax : argc
+  //  -- ebx : type info cell
+  //  -- edi : constructor
+  //  -- esp[0] : return address
+  //  -- esp[4] : last argument
+  // -----------------------------------
+
+  if (FLAG_debug_code) {
+    // The array construct code is only set for the global and natives
+    // builtin Array functions which always have maps.
+
+    // Initial map for the builtin Array function should be a map.
+    __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
+    // Will both indicate a NULL and a Smi.
+    __ test(ecx, Immediate(kSmiTagMask));
+    __ Assert(not_zero, "Unexpected initial map for Array function");
+    __ CmpObjectType(ecx, MAP_TYPE, ecx);
+    __ Assert(equal, "Unexpected initial map for Array function");
+  }
+
+  if (FLAG_optimize_constructed_arrays) {
+    // Figure out the right elements kind
+    __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
+
+    // Load the map's "bit field 2" into |result|. We only need the first byte,
+    // but the following masking takes care of that anyway.
+    __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
+    // Retrieve elements_kind from bit field 2.
+    __ and_(ecx, Map::kElementsKindMask);
+    __ shr(ecx, Map::kElementsKindShift);
+
+    if (FLAG_debug_code) {
+      Label done;
+      __ cmp(ecx, Immediate(FAST_ELEMENTS));
+      __ j(equal, &done);
+      __ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS));
+      __ Assert(equal,
+          "Invalid ElementsKind for InternalArray or InternalPackedArray");
+      __ bind(&done);
+    }
+
+    Label fast_elements_case;
+    __ cmp(ecx, Immediate(FAST_ELEMENTS));
+    __ j(equal, &fast_elements_case);
+    GenerateCase(masm, FAST_HOLEY_ELEMENTS);
+
+    __ bind(&fast_elements_case);
+    GenerateCase(masm, FAST_ELEMENTS);
+  } else {
+    Label generic_constructor;
+    // Run the native code for the Array function called as constructor.
+    ArrayNativeCode(masm, true, &generic_constructor);
+
+    // Jump to the generic construct code in case the specialized code cannot
+    // handle the construction.
+    __ bind(&generic_constructor);
+    Handle<Code> generic_construct_stub =
+        masm->isolate()->builtins()->JSConstructStubGeneric();
+    __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
+  }
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 9c08ef3..58ddbad 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -2923,7 +2923,7 @@
   // Check for fast case object. Return false for slow case objects.
   __ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset));
   __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
-  __ cmp(ecx, FACTORY->hash_table_map());
+  __ cmp(ecx, isolate()->factory()->hash_table_map());
   __ j(equal, if_false);
 
   // Look for valueOf string in the descriptor array, and indicate false if
@@ -2952,7 +2952,7 @@
   __ jmp(&entry);
   __ bind(&loop);
   __ mov(edx, FieldOperand(ebx, 0));
-  __ cmp(edx, FACTORY->value_of_string());
+  __ cmp(edx, isolate()->factory()->value_of_string());
   __ j(equal, if_false);
   __ add(ebx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize));
   __ bind(&entry);
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index e05031b..95c7c02 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -92,7 +92,8 @@
   __ j(not_zero, miss);
 
   __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset));
-  __ CheckMap(r0, FACTORY->hash_table_map(), miss, DONT_DO_SMI_CHECK);
+  __ CheckMap(r0, masm->isolate()->factory()->hash_table_map(), miss,
+              DONT_DO_SMI_CHECK);
 }
 
 
@@ -270,7 +271,7 @@
   if (not_fast_array != NULL) {
     // Check that the object is in fast mode and writable.
     __ CheckMap(scratch,
-                FACTORY->fixed_array_map(),
+                masm->isolate()->factory()->fixed_array_map(),
                 not_fast_array,
                 DONT_DO_SMI_CHECK);
   } else {
@@ -282,7 +283,7 @@
   // Fast case: Do the load.
   STATIC_ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0));
   __ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize));
-  __ cmp(scratch, Immediate(FACTORY->the_hole_value()));
+  __ cmp(scratch, Immediate(masm->isolate()->factory()->the_hole_value()));
   // In case the loaded value is the_hole we have to consult GetProperty
   // to ensure the prototype chain is searched.
   __ j(equal, out_of_range);
@@ -1353,6 +1354,23 @@
 }
 
 
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- ecx    : key
+  //  -- edx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+
+  __ pop(ebx);
+  __ push(edx);  // receiver
+  __ push(ecx);  // name
+  __ push(ebx);  // return address
+
+  // Perform tail call to the entry.
+  __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
+}
+
+
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ----------- S t a t e -------------
   //  -- ecx    : key
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 911a64c..98f1e8b 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4238,14 +4238,17 @@
   __ Set(eax, Immediate(instr->arity()));
   __ mov(ebx, instr->hydrogen()->property_cell());
   ElementsKind kind = instr->hydrogen()->elements_kind();
+  bool disable_allocation_sites =
+      (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
+
   if (instr->arity() == 0) {
-    ArrayNoArgumentConstructorStub stub(kind);
+    ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else if (instr->arity() == 1) {
-    ArraySingleArgumentConstructorStub stub(kind);
+    ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else {
-    ArrayNArgumentsConstructorStub stub(kind);
+    ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   }
 }
@@ -5998,95 +6001,6 @@
 }
 
 
-void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
-  class DeferredAllocateObject: public LDeferredCode {
-   public:
-    DeferredAllocateObject(LCodeGen* codegen, LAllocateObject* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
-    virtual LInstruction* instr() { return instr_; }
-   private:
-    LAllocateObject* instr_;
-  };
-
-  DeferredAllocateObject* deferred =
-      new(zone()) DeferredAllocateObject(this, instr);
-
-  Register result = ToRegister(instr->result());
-  Register scratch = ToRegister(instr->temp());
-  Handle<JSFunction> constructor = instr->hydrogen()->constructor();
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-  ASSERT(initial_map->pre_allocated_property_fields() +
-         initial_map->unused_property_fields() -
-         initial_map->inobject_properties() == 0);
-
-  __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(),
-              TAG_OBJECT);
-
-  __ bind(deferred->exit());
-  if (FLAG_debug_code) {
-    Label is_in_new_space;
-    __ JumpIfInNewSpace(result, scratch, &is_in_new_space);
-    __ Abort("Allocated object is not in new-space");
-    __ bind(&is_in_new_space);
-  }
-
-  // Load the initial map.
-  Register map = scratch;
-  __ LoadHeapObject(scratch, constructor);
-  __ mov(map, FieldOperand(scratch, JSFunction::kPrototypeOrInitialMapOffset));
-
-  if (FLAG_debug_code) {
-    __ AssertNotSmi(map);
-    __ cmpb(FieldOperand(map, Map::kInstanceSizeOffset),
-            instance_size >> kPointerSizeLog2);
-    __ Assert(equal, "Unexpected instance size");
-    __ cmpb(FieldOperand(map, Map::kPreAllocatedPropertyFieldsOffset),
-            initial_map->pre_allocated_property_fields());
-    __ Assert(equal, "Unexpected pre-allocated property fields count");
-    __ cmpb(FieldOperand(map, Map::kUnusedPropertyFieldsOffset),
-            initial_map->unused_property_fields());
-    __ Assert(equal, "Unexpected unused property fields count");
-    __ cmpb(FieldOperand(map, Map::kInObjectPropertiesOffset),
-            initial_map->inobject_properties());
-    __ Assert(equal, "Unexpected in-object property fields count");
-  }
-
-  // Initialize map and fields of the newly allocated object.
-  ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
-  __ mov(FieldOperand(result, JSObject::kMapOffset), map);
-  __ mov(scratch, factory()->empty_fixed_array());
-  __ mov(FieldOperand(result, JSObject::kElementsOffset), scratch);
-  __ mov(FieldOperand(result, JSObject::kPropertiesOffset), scratch);
-  if (initial_map->inobject_properties() != 0) {
-    __ mov(scratch, factory()->undefined_value());
-    for (int i = 0; i < initial_map->inobject_properties(); i++) {
-      int property_offset = JSObject::kHeaderSize + i * kPointerSize;
-      __ mov(FieldOperand(result, property_offset), scratch);
-    }
-  }
-}
-
-
-void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
-  Register result = ToRegister(instr->result());
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-
-  // TODO(3095996): Get rid of this. For now, we need to make the
-  // result register contain a valid pointer because it is already
-  // contained in the register pointer map.
-  __ Set(result, Immediate(0));
-
-  PushSafepointRegistersScope scope(this);
-  __ push(Immediate(Smi::FromInt(instance_size)));
-  CallRuntimeFromDeferred(
-      Runtime::kAllocateInNewSpace, 1, instr, instr->context());
-  __ StoreToSafepointRegisterSlot(result, eax);
-}
-
-
 void LCodeGen::DoAllocate(LAllocate* instr) {
   class DeferredAllocate: public LDeferredCode {
    public:
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index dec768b..647dd0e 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -159,7 +159,6 @@
   void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
-  void DoDeferredAllocateObject(LAllocateObject* instr);
   void DoDeferredAllocate(LAllocate* instr);
   void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                                        Label* map_check);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 28c4d2c..c5c7755 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -452,7 +452,14 @@
   } else {
     stream->Add("] <- ");
   }
-  value()->PrintTo(stream);
+
+  if (value() == NULL) {
+    ASSERT(hydrogen()->IsConstantHoleStore() &&
+           hydrogen()->value()->representation().IsDouble());
+    stream->Add("<the hole(nan)>");
+  } else {
+    value()->PrintTo(stream);
+  }
 }
 
 
@@ -757,6 +764,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
@@ -2519,15 +2532,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
-  info()->MarkAsDeferredCalling();
-  LOperand* context = UseAny(instr->context());
-  LOperand* temp = TempRegister();
-  LAllocateObject* result = new(zone()) LAllocateObject(context, temp);
-  return AssignPointerMap(DefineAsRegister(result));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* context = UseAny(instr->context());
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 568ef87..e43672c 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -44,7 +44,6 @@
   V(AccessArgumentsAt)                          \
   V(AddI)                                       \
   V(Allocate)                                   \
-  V(AllocateObject)                             \
   V(ApplyArguments)                             \
   V(ArgumentsElements)                          \
   V(ArgumentsLength)                            \
@@ -2552,21 +2551,6 @@
 };
 
 
-class LAllocateObject: public LTemplateInstruction<1, 1, 1> {
- public:
-  LAllocateObject(LOperand* context, LOperand* temp) {
-    inputs_[0] = context;
-    temps_[0] = temp;
-  }
-
-  LOperand* context() { return inputs_[0]; }
-  LOperand* temp() { return temps_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
-  DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
-};
-
-
 class LAllocate: public LTemplateInstruction<1, 2, 1> {
  public:
   LAllocate(LOperand* context, LOperand* size, LOperand* temp) {
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 3a68487..38b02a5 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -3027,7 +3027,7 @@
 
   // Check for heap-number
   mov(map, FieldOperand(value, HeapObject::kMapOffset));
-  cmp(map, FACTORY->heap_number_map());
+  cmp(map, isolate()->factory()->heap_number_map());
   j(not_equal, &not_heap_number, Label::kNear);
   mov(length, Immediate(HeapNumber::kSize));
   jmp(&is_data_object, Label::kNear);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 7cb7811..691e9a6 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -3178,145 +3178,6 @@
 }
 
 
-// Specialized stub for constructing objects from functions which only have only
-// simple assignments of the form this.x = ...; in their body.
-Handle<Code> ConstructStubCompiler::CompileConstructStub(
-    Handle<JSFunction> function) {
-  // ----------- S t a t e -------------
-  //  -- eax : argc
-  //  -- edi : constructor
-  //  -- esp[0] : return address
-  //  -- esp[4] : last argument
-  // -----------------------------------
-  Label generic_stub_call;
-#ifdef ENABLE_DEBUGGER_SUPPORT
-  // Check to see whether there are any break points in the function code. If
-  // there are jump to the generic constructor stub which calls the actual
-  // code for the function thereby hitting the break points.
-  __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
-  __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset));
-  __ cmp(ebx, factory()->undefined_value());
-  __ j(not_equal, &generic_stub_call);
-#endif
-
-  // Load the initial map and verify that it is in fact a map.
-  // edi: constructor
-  __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
-  // Will both indicate a NULL and a Smi.
-  __ JumpIfSmi(ebx, &generic_stub_call);
-  __ CmpObjectType(ebx, MAP_TYPE, ecx);
-  __ j(not_equal, &generic_stub_call);
-
-#ifdef DEBUG
-  // Cannot construct functions this way.
-  // ebx: initial map
-  __ CmpInstanceType(ebx, JS_FUNCTION_TYPE);
-  __ Check(not_equal, "Function constructed by construct stub.");
-#endif
-
-  // Now allocate the JSObject on the heap by moving the new space allocation
-  // top forward.
-  // ebx: initial map
-  ASSERT(function->has_initial_map());
-  int instance_size = function->initial_map()->instance_size();
-#ifdef DEBUG
-  __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
-  __ shl(ecx, kPointerSizeLog2);
-  __ cmp(ecx, Immediate(instance_size));
-  __ Check(equal, "Instance size of initial map changed.");
-#endif
-  __ Allocate(instance_size, edx, ecx, no_reg, &generic_stub_call,
-              NO_ALLOCATION_FLAGS);
-
-  // Allocated the JSObject, now initialize the fields and add the heap tag.
-  // ebx: initial map
-  // edx: JSObject (untagged)
-  __ mov(Operand(edx, JSObject::kMapOffset), ebx);
-  __ mov(ebx, factory()->empty_fixed_array());
-  __ mov(Operand(edx, JSObject::kPropertiesOffset), ebx);
-  __ mov(Operand(edx, JSObject::kElementsOffset), ebx);
-
-  // Push the allocated object to the stack. This is the object that will be
-  // returned (after it is tagged).
-  __ push(edx);
-
-  // eax: argc
-  // edx: JSObject (untagged)
-  // Load the address of the first in-object property into edx.
-  __ lea(edx, Operand(edx, JSObject::kHeaderSize));
-  // Calculate the location of the first argument. The stack contains the
-  // allocated object and the return address on top of the argc arguments.
-  __ lea(ecx, Operand(esp, eax, times_4, 1 * kPointerSize));
-
-  // Use edi for holding undefined which is used in several places below.
-  __ mov(edi, factory()->undefined_value());
-
-  // eax: argc
-  // ecx: first argument
-  // edx: first in-object property of the JSObject
-  // edi: undefined
-  // Fill the initialized properties with a constant value or a passed argument
-  // depending on the this.x = ...; assignment in the function.
-  Handle<SharedFunctionInfo> shared(function->shared());
-  for (int i = 0; i < shared->this_property_assignments_count(); i++) {
-    if (shared->IsThisPropertyAssignmentArgument(i)) {
-      // Check if the argument assigned to the property is actually passed.
-      // If argument is not passed the property is set to undefined,
-      // otherwise find it on the stack.
-      int arg_number = shared->GetThisPropertyAssignmentArgument(i);
-      __ mov(ebx, edi);
-      __ cmp(eax, arg_number);
-      if (CpuFeatures::IsSupported(CMOV)) {
-        CpuFeatureScope use_cmov(masm(), CMOV);
-        __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
-      } else {
-        Label not_passed;
-        __ j(below_equal, &not_passed);
-        __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
-        __ bind(&not_passed);
-      }
-      // Store value in the property.
-      __ mov(Operand(edx, i * kPointerSize), ebx);
-    } else {
-      // Set the property to the constant value.
-      Handle<Object> constant(shared->GetThisPropertyAssignmentConstant(i),
-                              isolate());
-      __ mov(Operand(edx, i * kPointerSize), Immediate(constant));
-    }
-  }
-
-  // Fill the unused in-object property fields with undefined.
-  for (int i = shared->this_property_assignments_count();
-       i < function->initial_map()->inobject_properties();
-       i++) {
-    __ mov(Operand(edx, i * kPointerSize), edi);
-  }
-
-  // Move argc to ebx and retrieve and tag the JSObject to return.
-  __ mov(ebx, eax);
-  __ pop(eax);
-  __ or_(eax, Immediate(kHeapObjectTag));
-
-  // Remove caller arguments and receiver from the stack and return.
-  __ pop(ecx);
-  __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
-  __ push(ecx);
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->constructed_objects(), 1);
-  __ IncrementCounter(counters->constructed_objects_stub(), 1);
-  __ ret(0);
-
-  // Jump to the generic stub in case the specialized code cannot handle the
-  // construction.
-  __ bind(&generic_stub_call);
-  Handle<Code> code = isolate()->builtins()->JSConstructStubGeneric();
-  __ jmp(code, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode();
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/src/ic.cc b/src/ic.cc
index f4aca22..ef8ab8a 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -937,7 +937,13 @@
 
   // Update inline cache and stub cache.
   if (FLAG_use_ic) {
-    UpdateCaches(&lookup, state, object, name);
+    if (!object->IsJSObject()) {
+      // TODO(jkummerow): It would be nice to support non-JSObjects in
+      // UpdateCaches, then we wouldn't need to go generic here.
+      set_target(*generic_stub());
+    } else {
+      UpdateCaches(&lookup, state, object, name);
+    }
   }
 
   PropertyAttributes attr;
@@ -2498,7 +2504,7 @@
     if (FLAG_trace_ic) {
       PrintF("[UnaryOpIC in ");
       JavaScriptFrame::PrintTop(isolate, stdout, false, true);
-      PrintF(" (%s->%s)#%s @ %p]\n",
+      PrintF(" %s => %s #%s @ %p]\n",
              UnaryOpIC::GetName(previous_type),
              UnaryOpIC::GetName(type),
              Token::Name(op),
@@ -2572,6 +2578,19 @@
 }
 
 
+#ifdef DEBUG
+static void TraceBinaryOp(BinaryOpIC::TypeInfo left,
+                          BinaryOpIC::TypeInfo right,
+                          bool has_fixed_right_arg,
+                          int32_t fixed_right_arg_value,
+                          BinaryOpIC::TypeInfo result) {
+  PrintF("%s*%s", BinaryOpIC::GetName(left), BinaryOpIC::GetName(right));
+  if (has_fixed_right_arg) PrintF("{%d}", fixed_right_arg_value);
+  PrintF("->%s", BinaryOpIC::GetName(result));
+}
+#endif
+
+
 RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
   ASSERT(args.length() == 3);
 
@@ -2580,9 +2599,10 @@
   Handle<Object> right = args.at<Object>(1);
   int key = args.smi_at(2);
   Token::Value op = BinaryOpStub::decode_op_from_minor_key(key);
-  BinaryOpIC::TypeInfo previous_left, previous_right, unused_previous_result;
+
+  BinaryOpIC::TypeInfo previous_left, previous_right, previous_result;
   BinaryOpStub::decode_types_from_minor_key(
-      key, &previous_left, &previous_right, &unused_previous_result);
+      key, &previous_left, &previous_right, &previous_result);
 
   BinaryOpIC::TypeInfo new_left = InputState(previous_left, left, op);
   BinaryOpIC::TypeInfo new_right = InputState(previous_right, right, op);
@@ -2597,43 +2617,60 @@
   BinaryOpIC::TypeInfo new_overall = Max(new_left, new_right);
   BinaryOpIC::TypeInfo previous_overall = Max(previous_left, previous_right);
 
-  if (new_overall == BinaryOpIC::SMI && previous_overall == BinaryOpIC::SMI) {
-    if (op == Token::DIV ||
-        op == Token::MUL ||
-        op == Token::SHR ||
-        kSmiValueSize == 32) {
-      // Arithmetic on two Smi inputs has yielded a heap number.
-      // That is the only way to get here from the Smi stub.
-      // With 32-bit Smis, all overflows give heap numbers, but with
-      // 31-bit Smis, most operations overflow to int32 results.
-      result_type = BinaryOpIC::NUMBER;
-    } else {
-      // Other operations on SMIs that overflow yield int32s.
-      result_type = BinaryOpIC::INT32;
+  bool previous_has_fixed_right_arg =
+      BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(key);
+  int previous_fixed_right_arg_value =
+      BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(key);
+
+  int32_t value;
+  bool new_has_fixed_right_arg =
+      op == Token::MOD &&
+      right->ToInt32(&value) &&
+      BinaryOpStub::can_encode_arg_value(value) &&
+      (previous_overall == BinaryOpIC::UNINITIALIZED ||
+       (previous_has_fixed_right_arg &&
+        previous_fixed_right_arg_value == value));
+  int32_t new_fixed_right_arg_value = new_has_fixed_right_arg ? value : 1;
+
+  if (previous_has_fixed_right_arg == new_has_fixed_right_arg) {
+    if (new_overall == BinaryOpIC::SMI && previous_overall == BinaryOpIC::SMI) {
+      if (op == Token::DIV ||
+          op == Token::MUL ||
+          op == Token::SHR ||
+          kSmiValueSize == 32) {
+        // Arithmetic on two Smi inputs has yielded a heap number.
+        // That is the only way to get here from the Smi stub.
+        // With 32-bit Smis, all overflows give heap numbers, but with
+        // 31-bit Smis, most operations overflow to int32 results.
+        result_type = BinaryOpIC::NUMBER;
+      } else {
+        // Other operations on SMIs that overflow yield int32s.
+        result_type = BinaryOpIC::INT32;
+      }
     }
-  }
-  if (new_overall == BinaryOpIC::INT32 &&
-      previous_overall == BinaryOpIC::INT32) {
-    if (new_left == previous_left && new_right == previous_right) {
-      result_type = BinaryOpIC::NUMBER;
+    if (new_overall == BinaryOpIC::INT32 &&
+        previous_overall == BinaryOpIC::INT32) {
+      if (new_left == previous_left && new_right == previous_right) {
+        result_type = BinaryOpIC::NUMBER;
+      }
     }
   }
 
-  BinaryOpStub stub(key, new_left, new_right, result_type);
+  BinaryOpStub stub(key, new_left, new_right, result_type,
+                    new_has_fixed_right_arg, new_fixed_right_arg_value);
   Handle<Code> code = stub.GetCode(isolate);
   if (!code.is_null()) {
 #ifdef DEBUG
     if (FLAG_trace_ic) {
       PrintF("[BinaryOpIC in ");
       JavaScriptFrame::PrintTop(isolate, stdout, false, true);
-      PrintF(" ((%s+%s)->((%s+%s)->%s))#%s @ %p]\n",
-             BinaryOpIC::GetName(previous_left),
-             BinaryOpIC::GetName(previous_right),
-             BinaryOpIC::GetName(new_left),
-             BinaryOpIC::GetName(new_right),
-             BinaryOpIC::GetName(result_type),
-             Token::Name(op),
-             static_cast<void*>(*code));
+      PrintF(" ");
+      TraceBinaryOp(previous_left, previous_right, previous_has_fixed_right_arg,
+                    previous_fixed_right_arg_value, previous_result);
+      PrintF(" => ");
+      TraceBinaryOp(new_left, new_right, new_has_fixed_right_arg,
+                    new_fixed_right_arg_value, result_type);
+      PrintF(" #%s @ %p]\n", Token::Name(op), static_cast<void*>(*code));
     }
 #endif
     BinaryOpIC ic(isolate);
diff --git a/src/ic.h b/src/ic.h
index 4715f0e..dadb743 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -369,6 +369,7 @@
   static void GenerateMiss(MacroAssembler* masm);
   static void GenerateMegamorphic(MacroAssembler* masm);
   static void GenerateNormal(MacroAssembler* masm);
+  static void GenerateRuntimeGetProperty(MacroAssembler* masm);
 
   MUST_USE_RESULT MaybeObject* Load(State state,
                                     Handle<Object> object,
@@ -378,8 +379,7 @@
   virtual Code::Kind kind() const { return Code::LOAD_IC; }
 
   virtual Handle<Code> generic_stub() const {
-    UNREACHABLE();
-    return Handle<Code>::null();
+    return isolate()->builtins()->LoadIC_Slow();
   }
 
   virtual Handle<Code> megamorphic_stub() {
diff --git a/src/isolate.cc b/src/isolate.cc
index 59f8b2e..7cce14a 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1338,6 +1338,7 @@
         }
       }
       Handle<Object> message_obj = MessageHandler::MakeMessageObject(
+          this,
           "uncaught_exception",
           location,
           HandleVector<Object>(&exception_arg, 1),
@@ -2250,6 +2251,7 @@
     CompareNilICStub::InitializeForIsolate(this);
     ToBooleanStub::InitializeForIsolate(this);
     ArrayConstructorStubBase::InstallDescriptors(this);
+    InternalArrayConstructorStubBase::InstallDescriptors(this);
   }
 
   if (FLAG_parallel_recompilation) optimizing_compiler_thread_.Start();
diff --git a/src/isolate.h b/src/isolate.h
index 5a06baa..76a5a41 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1480,7 +1480,6 @@
 // Temporary macros for accessing current isolate and its subobjects.
 // They provide better readability, especially when used a lot in the code.
 #define HEAP (v8::internal::Isolate::Current()->heap())
-#define FACTORY (v8::internal::Isolate::Current()->factory())
 #define ISOLATE (v8::internal::Isolate::Current())
 
 
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 03ccc67..f32ab13 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -1873,8 +1873,9 @@
   for (int i = j; i < kSize; i++) {
     templ[i] = bit;
   }
+  Factory* factory = Isolate::Current()->factory();
   // TODO(erikcorry): Cache these.
-  Handle<ByteArray> ba = FACTORY->NewByteArray(kSize, TENURED);
+  Handle<ByteArray> ba = factory->NewByteArray(kSize, TENURED);
   for (int i = 0; i < kSize; i++) {
     ba->set(i, templ[i]);
   }
@@ -3827,8 +3828,8 @@
     return true;
   }
 
-  Handle<ByteArray> boolean_skip_table =
-      FACTORY->NewByteArray(kSize, TENURED);
+  Factory* factory = Isolate::Current()->factory();
+  Handle<ByteArray> boolean_skip_table = factory->NewByteArray(kSize, TENURED);
   int skip_distance = GetSkipTable(
       min_lookahead, max_lookahead, boolean_skip_table);
   ASSERT(skip_distance != 0);
diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
index 04113e1..9defc5e 100644
--- a/src/lithium-allocator.cc
+++ b/src/lithium-allocator.cc
@@ -1057,7 +1057,7 @@
       LInstruction* branch =
           InstructionAt(cur_block->last_instruction_index());
       if (branch->HasPointerMap()) {
-        if (phi->representation().IsSmiOrTagged()) {
+        if (phi->representation().IsTagged() && !phi->type().IsSmi()) {
           branch->pointer_map()->RecordPointer(phi_operand, zone());
         } else if (!phi->representation().IsDouble()) {
           branch->pointer_map()->RecordUntagged(phi_operand, zone());
@@ -1640,7 +1640,7 @@
 bool LAllocator::HasTaggedValue(int virtual_register) const {
   HValue* value = graph_->LookupValue(virtual_register);
   if (value == NULL) return false;
-  return value->representation().IsSmiOrTagged();
+  return value->representation().IsTagged() && !value->type().IsSmi();
 }
 
 
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 67db2ab..a01e502 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -631,10 +631,10 @@
 // Wraps any object into a OpaqueReference, that will hide the object
 // from JavaScript.
 static Handle<JSValue> WrapInJSValue(Handle<Object> object) {
-  Handle<JSFunction> constructor =
-      Isolate::Current()->opaque_reference_function();
+  Isolate* isolate = Isolate::Current();
+  Handle<JSFunction> constructor = isolate->opaque_reference_function();
   Handle<JSValue> result =
-      Handle<JSValue>::cast(FACTORY->NewJSObject(constructor));
+      Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
   result->set_value(*object);
   return result;
 }
@@ -662,7 +662,8 @@
 class JSArrayBasedStruct {
  public:
   static S Create() {
-    Handle<JSArray> array = FACTORY->NewJSArray(S::kSize_);
+    Factory* factory = Isolate::Current()->factory();
+    Handle<JSArray> array = factory->NewJSArray(S::kSize_);
     return S(array);
   }
   static S cast(Object* object) {
@@ -1293,7 +1294,7 @@
   if (shared_info->debug_info()->IsDebugInfo()) {
     Handle<DebugInfo> debug_info(DebugInfo::cast(shared_info->debug_info()));
     Handle<Code> new_original_code =
-        FACTORY->CopyCode(compile_info_wrapper.GetFunctionCode());
+        isolate->factory()->CopyCode(compile_info_wrapper.GetFunctionCode());
     debug_info->set_original_code(*new_original_code);
   }
 
@@ -1460,6 +1461,7 @@
 static Handle<Code> PatchPositionsInCode(
     Handle<Code> code,
     Handle<JSArray> position_change_array) {
+  Isolate* isolate = code->GetIsolate();
 
   RelocInfoBuffer buffer_writer(code->relocation_size(),
                                 code->instruction_start());
@@ -1494,7 +1496,7 @@
     // Relocation info section now has different size. We cannot simply
     // rewrite it inside code object. Instead we have to create a new
     // code object.
-    Handle<Code> result(FACTORY->CopyCode(code, buffer));
+    Handle<Code> result(isolate->factory()->CopyCode(code, buffer));
     return result;
   }
 }
@@ -1542,9 +1544,10 @@
 
 
 static Handle<Script> CreateScriptCopy(Handle<Script> original) {
-  Handle<String> original_source(String::cast(original->source()));
+  Isolate* isolate = original->GetIsolate();
 
-  Handle<Script> copy = FACTORY->NewScript(original_source);
+  Handle<String> original_source(String::cast(original->source()));
+  Handle<Script> copy = isolate->factory()->NewScript(original_source);
 
   copy->set_name(original->name());
   copy->set_line_offset(original->line_offset());
@@ -2007,7 +2010,7 @@
   if (error_message != NULL) {
     // Add error message as an array extra element.
     Vector<const char> vector_message(error_message, StrLength(error_message));
-    Handle<String> str = FACTORY->NewStringFromAscii(vector_message);
+    Handle<String> str = isolate->factory()->NewStringFromAscii(vector_message);
     SetElementNonStrict(result, len, str);
   }
   return result;
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 4001501..a07b468 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -2074,22 +2074,16 @@
 // marking stack have been marked, or are overflowed in the heap.
 void MarkCompactCollector::EmptyMarkingDeque() {
   while (!marking_deque_.IsEmpty()) {
-    while (!marking_deque_.IsEmpty()) {
-      HeapObject* object = marking_deque_.Pop();
-      ASSERT(object->IsHeapObject());
-      ASSERT(heap()->Contains(object));
-      ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
+    HeapObject* object = marking_deque_.Pop();
+    ASSERT(object->IsHeapObject());
+    ASSERT(heap()->Contains(object));
+    ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
 
-      Map* map = object->map();
-      MarkBit map_mark = Marking::MarkBitFrom(map);
-      MarkObject(map, map_mark);
+    Map* map = object->map();
+    MarkBit map_mark = Marking::MarkBitFrom(map);
+    MarkObject(map, map_mark);
 
-      MarkCompactMarkingVisitor::IterateBody(map, object);
-    }
-
-    // Process encountered weak maps, mark objects only reachable by those
-    // weak maps and repeat until fix-point is reached.
-    ProcessWeakMaps();
+    MarkCompactMarkingVisitor::IterateBody(map, object);
   }
 }
 
@@ -2154,13 +2148,16 @@
 }
 
 
-void MarkCompactCollector::ProcessExternalMarking(RootMarkingVisitor* visitor) {
+// Mark all objects reachable (transitively) from objects on the marking
+// stack including references only considered in the atomic marking pause.
+void MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) {
   bool work_to_do = true;
   ASSERT(marking_deque_.IsEmpty());
   while (work_to_do) {
     isolate()->global_handles()->IterateObjectGroups(
         visitor, &IsUnmarkedHeapObjectWithHeap);
     MarkImplicitRefGroups();
+    ProcessWeakMaps();
     work_to_do = !marking_deque_.IsEmpty();
     ProcessMarkingDeque();
   }
@@ -2237,12 +2234,12 @@
 
   // The objects reachable from the roots are marked, yet unreachable
   // objects are unmarked.  Mark objects reachable due to host
-  // application specific logic.
-  ProcessExternalMarking(&root_visitor);
+  // application specific logic or through Harmony weak maps.
+  ProcessEphemeralMarking(&root_visitor);
 
-  // The objects reachable from the roots or object groups are marked,
-  // yet unreachable objects are unmarked.  Mark objects reachable
-  // only from weak global handles.
+  // The objects reachable from the roots, weak maps or object groups
+  // are marked, yet unreachable objects are unmarked.  Mark objects
+  // reachable only from weak global handles.
   //
   // First we identify nonlive weak handles and mark them as pending
   // destruction.
@@ -2255,9 +2252,9 @@
     EmptyMarkingDeque();
   }
 
-  // Repeat host application specific marking to mark unmarked objects
-  // reachable from the weak roots.
-  ProcessExternalMarking(&root_visitor);
+  // Repeat host application specific and Harmony weak maps marking to
+  // mark unmarked objects reachable from the weak roots.
+  ProcessEphemeralMarking(&root_visitor);
 
   AfterMarking();
 }
@@ -2529,6 +2526,7 @@
 
 
 void MarkCompactCollector::ProcessWeakMaps() {
+  GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKMAP_PROCESS);
   Object* weak_map_obj = encountered_weak_maps();
   while (weak_map_obj != Smi::FromInt(0)) {
     ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
@@ -2554,6 +2552,7 @@
 
 
 void MarkCompactCollector::ClearWeakMaps() {
+  GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKMAP_CLEAR);
   Object* weak_map_obj = encountered_weak_maps();
   while (weak_map_obj != Smi::FromInt(0)) {
     ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
diff --git a/src/mark-compact.h b/src/mark-compact.h
index 0f20440..873534c 100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -841,14 +841,18 @@
   // is marked.
   void MarkImplicitRefGroups();
 
-  // Mark all objects which are reachable due to host application
-  // logic like object groups or implicit references' groups.
-  void ProcessExternalMarking(RootMarkingVisitor* visitor);
-
   // Mark objects reachable (transitively) from objects in the marking stack
   // or overflowed in the heap.
   void ProcessMarkingDeque();
 
+  // Mark objects reachable (transitively) from objects in the marking stack
+  // or overflowed in the heap.  This respects references only considered in
+  // the final atomic marking pause including the following:
+  //    - Processing of objects reachable through Harmony WeakMaps.
+  //    - Objects reachable due to host application logic like object groups
+  //      or implicit references' groups.
+  void ProcessEphemeralMarking(ObjectVisitor* visitor);
+
   // Mark objects reachable (transitively) from objects in the marking
   // stack.  This function empties the marking stack, but may leave
   // overflowed objects in the heap, in which case the marking stack's
diff --git a/src/messages.cc b/src/messages.cc
index de18a4b..9eae67a 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -57,23 +57,25 @@
 
 
 Handle<JSMessageObject> MessageHandler::MakeMessageObject(
+    Isolate* isolate,
     const char* type,
     MessageLocation* loc,
     Vector< Handle<Object> > args,
     Handle<String> stack_trace,
     Handle<JSArray> stack_frames) {
-  Handle<String> type_handle = FACTORY->InternalizeUtf8String(type);
+  Factory* factory = isolate->factory();
+  Handle<String> type_handle = factory->InternalizeUtf8String(type);
   Handle<FixedArray> arguments_elements =
-      FACTORY->NewFixedArray(args.length());
+      factory->NewFixedArray(args.length());
   for (int i = 0; i < args.length(); i++) {
     arguments_elements->set(i, *args[i]);
   }
   Handle<JSArray> arguments_handle =
-      FACTORY->NewJSArrayWithElements(arguments_elements);
+      factory->NewJSArrayWithElements(arguments_elements);
 
   int start = 0;
   int end = 0;
-  Handle<Object> script_handle = FACTORY->undefined_value();
+  Handle<Object> script_handle = factory->undefined_value();
   if (loc) {
     start = loc->start_pos();
     end = loc->end_pos();
@@ -81,15 +83,15 @@
   }
 
   Handle<Object> stack_trace_handle = stack_trace.is_null()
-      ? Handle<Object>::cast(FACTORY->undefined_value())
+      ? Handle<Object>::cast(factory->undefined_value())
       : Handle<Object>::cast(stack_trace);
 
   Handle<Object> stack_frames_handle = stack_frames.is_null()
-      ? Handle<Object>::cast(FACTORY->undefined_value())
+      ? Handle<Object>::cast(factory->undefined_value())
       : Handle<Object>::cast(stack_frames);
 
   Handle<JSMessageObject> message =
-      FACTORY->NewJSMessageObject(type_handle,
+      factory->NewJSMessageObject(type_handle,
                                   arguments_handle,
                                   start,
                                   end,
@@ -122,7 +124,7 @@
   v8::Local<v8::Message> api_message_obj = v8::Utils::MessageToLocal(message);
   v8::Local<v8::Value> api_exception_obj = v8::Utils::ToLocal(exception_handle);
 
-  v8::NeanderArray global_listeners(FACTORY->message_listeners());
+  v8::NeanderArray global_listeners(isolate->factory()->message_listeners());
   int global_length = global_listeners.length();
   if (global_length == 0) {
     DefaultMessageReport(isolate, loc, message);
diff --git a/src/messages.h b/src/messages.h
index 3361abe..5d84e46 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -91,6 +91,7 @@
  public:
   // Returns a message object for the API to use.
   static Handle<JSMessageObject> MakeMessageObject(
+      Isolate* isolate,
       const char* type,
       MessageLocation* loc,
       Vector< Handle<Object> > args,
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 552797a..89017f1 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -961,7 +961,7 @@
 
   __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask));
 
-  // Test for NaN. Sadly, we can't just compare to factory->nan_value(),
+  // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
   // so we do the second best thing - test it ourselves.
   // They are both equal and they are not both Smis so both of them are not
   // Smis. If it's not a heap number, then return equal.
@@ -2277,7 +2277,16 @@
 
 
 void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
-  Label not_smis, call_runtime;
+  Label right_arg_changed, call_runtime;
+
+  if (op_ == Token::MOD && has_fixed_right_arg_) {
+    // It is guaranteed that the value will fit into a Smi, because if it
+    // didn't, we wouldn't be here, see BinaryOp_Patch.
+    __ Branch(&right_arg_changed,
+              ne,
+              a0,
+              Operand(Smi::FromInt(fixed_right_arg_value())));
+  }
 
   if (result_type_ == BinaryOpIC::UNINITIALIZED ||
       result_type_ == BinaryOpIC::SMI) {
@@ -2294,6 +2303,7 @@
 
   // Code falls through if the result is not returned as either a smi or heap
   // number.
+  __ bind(&right_arg_changed);
   GenerateTypeTransition(masm);
 
   __ bind(&call_runtime);
@@ -2494,6 +2504,11 @@
         // to type transition.
 
       } else {
+        if (has_fixed_right_arg_) {
+          __ Move(f16, fixed_right_arg_value());
+          __ BranchF(&transition, NULL, ne, f14, f16);
+        }
+
         // We preserved a0 and a1 to be able to call runtime.
         // Save the left value on the stack.
         __ Push(t1, t0);
@@ -5113,7 +5128,11 @@
   __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
 
   if (RecordCallTarget()) {
-    GenerateRecordCallTargetNoArray(masm);
+    if (FLAG_optimize_constructed_arrays) {
+      GenerateRecordCallTarget(masm);
+    } else {
+      GenerateRecordCallTargetNoArray(masm);
+    }
   }
 
   // Fast-case: Invoke the function now.
@@ -7644,6 +7663,10 @@
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
     T stub(kind);
     stub.GetCode(isolate)->set_is_pregenerated(true);
+    if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+      T stub1(kind, true);
+      stub1.GetCode(isolate)->set_is_pregenerated(true);
+    }
   }
 }
 
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 78f44ab..fa85da6 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -3039,7 +3039,7 @@
   // string "valueOf" the result is false.
   // The use of t2 to store the valueOf string assumes that it is not otherwise
   // used in the loop below.
-  __ li(t2, Operand(FACTORY->value_of_string()));
+  __ li(t2, Operand(isolate()->factory()->value_of_string()));
   __ jmp(&entry);
   __ bind(&loop);
   __ lw(a3, MemOperand(t0, 0));
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 677d600..e1b01b3 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -3920,14 +3920,17 @@
   __ li(a0, Operand(instr->arity()));
   __ li(a2, Operand(instr->hydrogen()->property_cell()));
   ElementsKind kind = instr->hydrogen()->elements_kind();
+  bool disable_allocation_sites =
+      (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
+
   if (instr->arity() == 0) {
-    ArrayNoArgumentConstructorStub stub(kind);
+    ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else if (instr->arity() == 1) {
-    ArraySingleArgumentConstructorStub stub(kind);
+    ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else {
-    ArrayNArgumentsConstructorStub stub(kind);
+    ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   }
 }
@@ -5138,80 +5141,6 @@
 }
 
 
-void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
-  class DeferredAllocateObject: public LDeferredCode {
-   public:
-    DeferredAllocateObject(LCodeGen* codegen, LAllocateObject* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
-    virtual LInstruction* instr() { return instr_; }
-   private:
-    LAllocateObject* instr_;
-  };
-
-  DeferredAllocateObject* deferred =
-      new(zone()) DeferredAllocateObject(this, instr);
-
-  Register result = ToRegister(instr->result());
-  Register scratch = ToRegister(instr->temp());
-  Register scratch2 = ToRegister(instr->temp2());
-  Handle<JSFunction> constructor = instr->hydrogen()->constructor();
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-  ASSERT(initial_map->pre_allocated_property_fields() +
-         initial_map->unused_property_fields() -
-         initial_map->inobject_properties() == 0);
-
-  __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(),
-              TAG_OBJECT);
-
-  __ bind(deferred->exit());
-  if (FLAG_debug_code) {
-    Label is_in_new_space;
-    __ JumpIfInNewSpace(result, scratch, &is_in_new_space);
-    __ Abort("Allocated object is not in new-space");
-    __ bind(&is_in_new_space);
-  }
-
-  // Load the initial map.
-  Register map = scratch;
-  __ LoadHeapObject(map, constructor);
-  __ lw(map, FieldMemOperand(map, JSFunction::kPrototypeOrInitialMapOffset));
-
-  // Initialize map and fields of the newly allocated object.
-  ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
-  __ sw(map, FieldMemOperand(result, JSObject::kMapOffset));
-  __ LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
-  __ sw(scratch, FieldMemOperand(result, JSObject::kElementsOffset));
-  __ sw(scratch, FieldMemOperand(result, JSObject::kPropertiesOffset));
-  if (initial_map->inobject_properties() != 0) {
-    __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
-    for (int i = 0; i < initial_map->inobject_properties(); i++) {
-      int property_offset = JSObject::kHeaderSize + i * kPointerSize;
-      __ sw(scratch, FieldMemOperand(result, property_offset));
-    }
-  }
-}
-
-
-void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
-  Register result = ToRegister(instr->result());
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-
-  // TODO(3095996): Get rid of this. For now, we need to make the
-  // result register contain a valid pointer because it is already
-  // contained in the register pointer map.
-  __ mov(result, zero_reg);
-
-  PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
-  __ li(a0, Operand(Smi::FromInt(instance_size)));
-  __ push(a0);
-  CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
-  __ StoreToSafepointRegisterSlot(v0, result);
-}
-
-
 void LCodeGen::DoAllocate(LAllocate* instr) {
   class DeferredAllocate: public LDeferredCode {
    public:
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index 2f4e140..a208c40 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -151,7 +151,6 @@
   void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
-  void DoDeferredAllocateObject(LAllocateObject* instr);
   void DoDeferredAllocate(LAllocate* instr);
   void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                                        Label* map_check);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 2325064..60188a2 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -702,6 +702,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
@@ -2263,14 +2269,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
-  info()->MarkAsDeferredCalling();
-  LAllocateObject* result =
-      new(zone()) LAllocateObject(TempRegister(), TempRegister());
-  return AssignPointerMap(DefineAsRegister(result));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* size = instr->size()->IsConstant()
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 01dd6c2..50feee0 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -49,7 +49,6 @@
 #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V)    \
   V(AccessArgumentsAt)                          \
   V(AddI)                                       \
-  V(AllocateObject)                             \
   V(Allocate)                                   \
   V(ApplyArguments)                             \
   V(ArgumentsElements)                          \
@@ -2398,21 +2397,6 @@
 };
 
 
-class LAllocateObject: public LTemplateInstruction<1, 1, 2> {
- public:
-  LAllocateObject(LOperand* temp, LOperand* temp2) {
-    temps_[0] = temp;
-    temps_[1] = temp2;
-  }
-
-  LOperand* temp() { return temps_[0]; }
-  LOperand* temp2() { return temps_[1]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
-  DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
-};
-
-
 class LAllocate: public LTemplateInstruction<1, 2, 2> {
  public:
   LAllocate(LOperand* size, LOperand* temp1, LOperand* temp2) {
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index 7289296..3e255b7 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -929,9 +929,8 @@
 
   CodeDesc code_desc;
   masm_->GetCode(&code_desc);
-  Handle<Code> code = FACTORY->NewCode(code_desc,
-                                       Code::ComputeFlags(Code::REGEXP),
-                                       masm_->CodeObject());
+  Handle<Code> code = isolate()->factory()->NewCode(
+      code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject());
   LOG(Isolate::Current(), RegExpCodeCreateEvent(*code, *source));
   return Handle<HeapObject>::cast(code);
 }
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index a19b964..63fde97 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -3143,157 +3143,6 @@
 }
 
 
-Handle<Code> ConstructStubCompiler::CompileConstructStub(
-    Handle<JSFunction> function) {
-  // a0    : argc
-  // a1    : constructor
-  // ra    : return address
-  // [sp]  : last argument
-  Label generic_stub_call;
-
-  // Use t7 for holding undefined which is used in several places below.
-  __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
-  // Check to see whether there are any break points in the function code. If
-  // there are jump to the generic constructor stub which calls the actual
-  // code for the function thereby hitting the break points.
-  __ lw(t5, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
-  __ lw(a2, FieldMemOperand(t5, SharedFunctionInfo::kDebugInfoOffset));
-  __ Branch(&generic_stub_call, ne, a2, Operand(t7));
-#endif
-
-  // Load the initial map and verify that it is in fact a map.
-  // a1: constructor function
-  // t7: undefined
-  __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
-  __ JumpIfSmi(a2, &generic_stub_call);
-  __ GetObjectType(a2, a3, t0);
-  __ Branch(&generic_stub_call, ne, t0, Operand(MAP_TYPE));
-
-#ifdef DEBUG
-  // Cannot construct functions this way.
-  // a0: argc
-  // a1: constructor function
-  // a2: initial map
-  // t7: undefined
-  __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
-  __ Check(ne, "Function constructed by construct stub.",
-           a3, Operand(JS_FUNCTION_TYPE));
-#endif
-
-  // Now allocate the JSObject in new space.
-  // a0: argc
-  // a1: constructor function
-  // a2: initial map
-  // t7: undefined
-  ASSERT(function->has_initial_map());
-  __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
-#ifdef DEBUG
-  int instance_size = function->initial_map()->instance_size();
-  __ Check(eq, "Instance size of initial map changed.",
-           a3, Operand(instance_size >> kPointerSizeLog2));
-#endif
-  __ Allocate(a3, t4, t5, t6, &generic_stub_call, SIZE_IN_WORDS);
-
-  // Allocated the JSObject, now initialize the fields. Map is set to initial
-  // map and properties and elements are set to empty fixed array.
-  // a0: argc
-  // a1: constructor function
-  // a2: initial map
-  // a3: object size (in words)
-  // t4: JSObject (not tagged)
-  // t7: undefined
-  __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
-  __ mov(t5, t4);
-  __ sw(a2, MemOperand(t5, JSObject::kMapOffset));
-  __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset));
-  __ sw(t6, MemOperand(t5, JSObject::kElementsOffset));
-  __ Addu(t5, t5, Operand(3 * kPointerSize));
-  ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
-  ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
-  ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
-
-
-  // Calculate the location of the first argument. The stack contains only the
-  // argc arguments.
-  __ sll(a1, a0, kPointerSizeLog2);
-  __ Addu(a1, a1, sp);
-
-  // Fill all the in-object properties with undefined.
-  // a0: argc
-  // a1: first argument
-  // a3: object size (in words)
-  // t4: JSObject (not tagged)
-  // t5: First in-object property of JSObject (not tagged)
-  // t7: undefined
-  // Fill the initialized properties with a constant value or a passed argument
-  // depending on the this.x = ...; assignment in the function.
-  Handle<SharedFunctionInfo> shared(function->shared());
-  for (int i = 0; i < shared->this_property_assignments_count(); i++) {
-    if (shared->IsThisPropertyAssignmentArgument(i)) {
-      Label not_passed, next;
-      // Check if the argument assigned to the property is actually passed.
-      int arg_number = shared->GetThisPropertyAssignmentArgument(i);
-      __ Branch(&not_passed, less_equal, a0, Operand(arg_number));
-      // Argument passed - find it on the stack.
-      __ lw(a2, MemOperand(a1, (arg_number + 1) * -kPointerSize));
-      __ sw(a2, MemOperand(t5));
-      __ Addu(t5, t5, kPointerSize);
-      __ jmp(&next);
-      __ bind(&not_passed);
-      // Set the property to undefined.
-      __ sw(t7, MemOperand(t5));
-      __ Addu(t5, t5, Operand(kPointerSize));
-      __ bind(&next);
-    } else {
-      // Set the property to the constant value.
-      Handle<Object> constant(
-          shared->GetThisPropertyAssignmentConstant(i), isolate());
-      __ li(a2, Operand(constant));
-      __ sw(a2, MemOperand(t5));
-      __ Addu(t5, t5, kPointerSize);
-    }
-  }
-
-  // Fill the unused in-object property fields with undefined.
-  for (int i = shared->this_property_assignments_count();
-       i < function->initial_map()->inobject_properties();
-       i++) {
-      __ sw(t7, MemOperand(t5));
-      __ Addu(t5, t5, kPointerSize);
-  }
-
-  // a0: argc
-  // t4: JSObject (not tagged)
-  // Move argc to a1 and the JSObject to return to v0 and tag it.
-  __ mov(a1, a0);
-  __ mov(v0, t4);
-  __ Or(v0, v0, Operand(kHeapObjectTag));
-
-  // v0: JSObject
-  // a1: argc
-  // Remove caller arguments and receiver from the stack and return.
-  __ sll(t0, a1, kPointerSizeLog2);
-  __ Addu(sp, sp, t0);
-  __ Addu(sp, sp, Operand(kPointerSize));
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->constructed_objects(), 1, a1, a2);
-  __ IncrementCounter(counters->constructed_objects_stub(), 1, a1, a2);
-  __ Ret();
-
-  // Jump to the generic stub in case the specialized code cannot handle the
-  // construction.
-  __ bind(&generic_stub_call);
-  Handle<Code> generic_construct_stub =
-      isolate()->builtins()->JSConstructStubGeneric();
-  __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode();
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index be4af06..956d088 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -4460,8 +4460,6 @@
 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
-ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
-          kThisPropertyAssignmentsOffset)
 SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
 
 
@@ -4478,10 +4476,6 @@
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
                kIsTopLevelBit)
 
-BOOL_GETTER(SharedFunctionInfo,
-            compiler_hints,
-            has_only_simple_this_property_assignments,
-            kHasOnlySimpleThisPropertyAssignments)
 BOOL_ACCESSORS(SharedFunctionInfo,
                compiler_hints,
                allows_lazy_compilation,
@@ -4514,8 +4508,6 @@
               kFunctionTokenPositionOffset)
 SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
               kCompilerHintsOffset)
-SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
-              kThisPropertyAssignmentsCountOffset)
 SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
 SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
 SMI_ACCESSORS(SharedFunctionInfo,
@@ -4567,13 +4559,10 @@
                         compiler_hints,
                         kCompilerHintsOffset)
 
-PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
-                        this_property_assignments_count,
-                        kThisPropertyAssignmentsCountOffset)
-PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, opt_count, kOptCountOffset)
 
-PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
-PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
+PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset)
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
                         stress_deopt_counter,
                         kStressDeoptCounterOffset)
 #endif
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index f312794..549c9ff 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -885,10 +885,6 @@
   PrintF(out, "\n - debug info = ");
   debug_info()->ShortPrint(out);
   PrintF(out, "\n - length = %d", length());
-  PrintF(out, "\n - has_only_simple_this_property_assignments = %d",
-         has_only_simple_this_property_assignments());
-  PrintF(out, "\n - this_property_assignments = ");
-  this_property_assignments()->ShortPrint(out);
   PrintF(out, "\n - optimized_code_map = ");
   optimized_code_map()->ShortPrint(out);
   PrintF(out, "\n");
diff --git a/src/objects.cc b/src/objects.cc
index edb9120..ca1c650 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -155,6 +155,41 @@
 }
 
 
+bool Object::ToInt32(int32_t* value) {
+  if (IsSmi()) {
+    *value = Smi::cast(this)->value();
+    return true;
+  }
+  if (IsHeapNumber()) {
+    double num = HeapNumber::cast(this)->value();
+    if (FastI2D(FastD2I(num)) == num) {
+      *value = FastD2I(num);
+      return true;
+    }
+  }
+  return false;
+}
+
+
+bool Object::ToUint32(uint32_t* value) {
+  if (IsSmi()) {
+    int num = Smi::cast(this)->value();
+    if (num >= 0) {
+      *value = static_cast<uint32_t>(num);
+      return true;
+    }
+  }
+  if (IsHeapNumber()) {
+    double num = HeapNumber::cast(this)->value();
+    if (num >= 0 && FastUI2D(FastD2UI(num)) == num) {
+      *value = FastD2UI(num);
+      return true;
+    }
+  }
+  return false;
+}
+
+
 template<typename To>
 static inline To* CheckedCast(void *from) {
   uintptr_t temp = reinterpret_cast<uintptr_t>(from);
@@ -344,6 +379,8 @@
     {
       // Leaving JavaScript.
       VMState<EXTERNAL> state(isolate);
+      ExternalCallbackScope call_scope(isolate,
+                                       v8::ToCData<Address>(fun_obj));
       result = args.Call(call_fun, v8::Utils::ToLocal(key));
     }
     RETURN_IF_SCHEDULED_EXCEPTION(isolate);
@@ -1932,8 +1969,8 @@
     } else {
       Handle<Object> args[1] = {Handle<Name>(name)};
       return isolate->Throw(
-          *FACTORY->NewTypeError("object_not_extensible",
-                                 HandleVector(args, 1)));
+          *isolate->factory()->NewTypeError("object_not_extensible",
+                                            HandleVector(args, 1)));
     }
   }
 
@@ -2789,6 +2826,8 @@
     {
       // Leaving JavaScript.
       VMState<EXTERNAL> state(isolate);
+      ExternalCallbackScope call_scope(isolate,
+                                       v8::ToCData<Address>(call_obj));
       args.Call(call_fun,
                 v8::Utils::ToLocal(key),
                 v8::Utils::ToLocal(value_handle));
@@ -9608,114 +9647,6 @@
 }
 
 
-bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
-  // Check the basic conditions for generating inline constructor code.
-  if (!FLAG_inline_new
-      || !has_only_simple_this_property_assignments()
-      || is_generator()
-      || this_property_assignments_count() == 0) {
-    return false;
-  }
-
-  Isolate* isolate = GetIsolate();
-  Heap* heap = isolate->heap();
-
-  // Traverse the proposed prototype chain looking for properties of the
-  // same names as are set by the inline constructor.
-  for (Object* obj = prototype;
-       obj != heap->null_value();
-       obj = obj->GetPrototype(isolate)) {
-    JSReceiver* receiver = JSReceiver::cast(obj);
-    for (int i = 0; i < this_property_assignments_count(); i++) {
-      LookupResult result(heap->isolate());
-      String* name = GetThisPropertyAssignmentName(i);
-      receiver->LocalLookup(name, &result);
-      if (result.IsFound()) {
-        switch (result.type()) {
-          case NORMAL:
-          case FIELD:
-          case CONSTANT_FUNCTION:
-            break;
-          case INTERCEPTOR:
-          case CALLBACKS:
-          case HANDLER:
-            return false;
-          case TRANSITION:
-          case NONEXISTENT:
-            UNREACHABLE();
-            break;
-        }
-      }
-    }
-  }
-
-  return true;
-}
-
-
-void SharedFunctionInfo::ForbidInlineConstructor() {
-  set_compiler_hints(BooleanBit::set(compiler_hints(),
-                                     kHasOnlySimpleThisPropertyAssignments,
-                                     false));
-}
-
-
-void SharedFunctionInfo::SetThisPropertyAssignmentsInfo(
-    bool only_simple_this_property_assignments,
-    FixedArray* assignments) {
-  set_compiler_hints(BooleanBit::set(compiler_hints(),
-                                     kHasOnlySimpleThisPropertyAssignments,
-                                     only_simple_this_property_assignments));
-  set_this_property_assignments(assignments);
-  set_this_property_assignments_count(assignments->length() / 3);
-}
-
-
-void SharedFunctionInfo::ClearThisPropertyAssignmentsInfo() {
-  Heap* heap = GetHeap();
-  set_compiler_hints(BooleanBit::set(compiler_hints(),
-                                     kHasOnlySimpleThisPropertyAssignments,
-                                     false));
-  set_this_property_assignments(heap->undefined_value());
-  set_this_property_assignments_count(0);
-}
-
-
-String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) {
-  Object* obj = this_property_assignments();
-  ASSERT(obj->IsFixedArray());
-  ASSERT(index < this_property_assignments_count());
-  obj = FixedArray::cast(obj)->get(index * 3);
-  ASSERT(obj->IsString());
-  return String::cast(obj);
-}
-
-
-bool SharedFunctionInfo::IsThisPropertyAssignmentArgument(int index) {
-  Object* obj = this_property_assignments();
-  ASSERT(obj->IsFixedArray());
-  ASSERT(index < this_property_assignments_count());
-  obj = FixedArray::cast(obj)->get(index * 3 + 1);
-  return Smi::cast(obj)->value() != -1;
-}
-
-
-int SharedFunctionInfo::GetThisPropertyAssignmentArgument(int index) {
-  ASSERT(IsThisPropertyAssignmentArgument(index));
-  Object* obj =
-      FixedArray::cast(this_property_assignments())->get(index * 3 + 1);
-  return Smi::cast(obj)->value();
-}
-
-
-Object* SharedFunctionInfo::GetThisPropertyAssignmentConstant(int index) {
-  ASSERT(!IsThisPropertyAssignmentArgument(index));
-  Object* obj =
-      FixedArray::cast(this_property_assignments())->get(index * 3 + 2);
-  return obj;
-}
-
-
 // Support function for printing the source code to a StringStream
 // without any allocation in the heap.
 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
@@ -10903,18 +10834,70 @@
                         Handle<JSObject> object,
                         uint32_t index,
                         List<Handle<Object> >* old_values,
-                        List<Handle<String> >* indices) {
+                        List<uint32_t>* indices) {
   PropertyAttributes attributes = object->GetLocalElementAttribute(index);
   ASSERT(attributes != ABSENT);
   if (attributes == DONT_DELETE) return false;
   old_values->Add(object->GetLocalElementAccessorPair(index) == NULL
       ? Object::GetElement(object, index)
       : Handle<Object>::cast(isolate->factory()->the_hole_value()));
-  indices->Add(isolate->factory()->Uint32ToString(index));
+  indices->Add(index);
   return true;
 }
 
 
+// TODO(rafaelw): Remove |delete_count| argument and rely on the length of
+// of |deleted|.
+static void EnqueueSpliceRecord(Handle<JSArray> object,
+                                uint32_t index,
+                                Handle<JSArray> deleted,
+                                uint32_t delete_count,
+                                uint32_t add_count) {
+  Isolate* isolate = object->GetIsolate();
+  HandleScope scope(isolate);
+  Handle<Object> index_object = isolate->factory()->NewNumberFromUint(index);
+  Handle<Object> delete_count_object =
+      isolate->factory()->NewNumberFromUint(delete_count);
+  Handle<Object> add_count_object =
+      isolate->factory()->NewNumberFromUint(add_count);
+
+  Handle<Object> args[] =
+      { object, index_object, deleted, delete_count_object, add_count_object };
+
+  bool threw;
+  Execution::Call(Handle<JSFunction>(isolate->observers_enqueue_splice()),
+                  isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
+                  &threw);
+  ASSERT(!threw);
+}
+
+
+static void BeginPerformSplice(Handle<JSArray> object) {
+  Isolate* isolate = object->GetIsolate();
+  HandleScope scope(isolate);
+  Handle<Object> args[] = { object };
+
+  bool threw;
+  Execution::Call(Handle<JSFunction>(isolate->observers_begin_perform_splice()),
+                  isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
+                  &threw);
+  ASSERT(!threw);
+}
+
+
+static void EndPerformSplice(Handle<JSArray> object) {
+  Isolate* isolate = object->GetIsolate();
+  HandleScope scope(isolate);
+  Handle<Object> args[] = { object };
+
+  bool threw;
+  Execution::Call(Handle<JSFunction>(isolate->observers_end_perform_splice()),
+                  isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
+                  &threw);
+  ASSERT(!threw);
+}
+
+
 MaybeObject* JSArray::SetElementsLength(Object* len) {
   // We should never end in here with a pixel or external array.
   ASSERT(AllowsSetElementsLength());
@@ -10924,7 +10907,7 @@
   Isolate* isolate = GetIsolate();
   HandleScope scope(isolate);
   Handle<JSArray> self(this);
-  List<Handle<String> > indices;
+  List<uint32_t> indices;
   List<Handle<Object> > old_values;
   Handle<Object> old_length_handle(self->length(), isolate);
   Handle<Object> new_length_handle(len, isolate);
@@ -10964,15 +10947,34 @@
   if (!result->ToHandle(&hresult, isolate)) return result;
 
   CHECK(self->length()->ToArrayIndex(&new_length));
-  if (old_length != new_length) {
-    for (int i = 0; i < indices.length(); ++i) {
-      JSObject::EnqueueChangeRecord(
-          self, "deleted", indices[i], old_values[i]);
-    }
+  if (old_length == new_length) return *hresult;
+
+  BeginPerformSplice(self);
+
+  for (int i = 0; i < indices.length(); ++i) {
     JSObject::EnqueueChangeRecord(
-        self, "updated", isolate->factory()->length_string(),
-        old_length_handle);
+        self, "deleted", isolate->factory()->Uint32ToString(indices[i]),
+        old_values[i]);
   }
+  JSObject::EnqueueChangeRecord(
+      self, "updated", isolate->factory()->length_string(),
+      old_length_handle);
+
+  EndPerformSplice(self);
+
+  uint32_t index = Min(old_length, new_length);
+  uint32_t add_count = new_length > old_length ? new_length - old_length : 0;
+  uint32_t delete_count = new_length < old_length ? old_length - new_length : 0;
+  Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
+  if (delete_count) {
+    for (int i = indices.length() - 1; i >= 0; i--) {
+      JSObject::SetElement(deleted, indices[i] - index, old_values[i], NONE,
+                           kNonStrictMode);
+    }
+  }
+
+  EnqueueSpliceRecord(self, index, deleted, delete_count, add_count);
+
   return *hresult;
 }
 
@@ -11200,7 +11202,8 @@
       // Cycle detected.
       HandleScope scope(isolate);
       return isolate->Throw(
-          *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0)));
+          *isolate->factory()->NewError("cyclic_proto",
+                                        HandleVector<Object>(NULL, 0)));
     }
   }
 
@@ -11997,14 +12000,15 @@
   Handle<Object> value(value_raw, isolate);
   PropertyAttributes old_attributes = self->GetLocalElementAttribute(index);
   Handle<Object> old_value = isolate->factory()->the_hole_value();
-  Handle<Object> old_length;
+  Handle<Object> old_length_handle;
+  Handle<Object> new_length_handle;
 
   if (old_attributes != ABSENT) {
     if (self->GetLocalElementAccessorPair(index) == NULL)
       old_value = Object::GetElement(self, index);
   } else if (self->IsJSArray()) {
     // Store old array length in case adding an element grows the array.
-    old_length = handle(Handle<JSArray>::cast(self)->length(), isolate);
+    old_length_handle = handle(Handle<JSArray>::cast(self)->length(), isolate);
   }
 
   // Check for lookup interceptor
@@ -12020,11 +12024,25 @@
   Handle<String> name = isolate->factory()->Uint32ToString(index);
   PropertyAttributes new_attributes = self->GetLocalElementAttribute(index);
   if (old_attributes == ABSENT) {
-    EnqueueChangeRecord(self, "new", name, old_value);
     if (self->IsJSArray() &&
-        !old_length->SameValue(Handle<JSArray>::cast(self)->length())) {
-      EnqueueChangeRecord(
-          self, "updated", isolate->factory()->length_string(), old_length);
+        !old_length_handle->SameValue(Handle<JSArray>::cast(self)->length())) {
+      new_length_handle = handle(Handle<JSArray>::cast(self)->length(),
+                                 isolate);
+      uint32_t old_length = 0;
+      uint32_t new_length = 0;
+      CHECK(old_length_handle->ToArrayIndex(&old_length));
+      CHECK(new_length_handle->ToArrayIndex(&new_length));
+
+      BeginPerformSplice(Handle<JSArray>::cast(self));
+      EnqueueChangeRecord(self, "new", name, old_value);
+      EnqueueChangeRecord(self, "updated", isolate->factory()->length_string(),
+                          old_length_handle);
+      EndPerformSplice(Handle<JSArray>::cast(self));
+      Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
+      EnqueueSpliceRecord(Handle<JSArray>::cast(self), old_length, deleted, 0,
+                          new_length - old_length);
+    } else {
+      EnqueueChangeRecord(self, "new", name, old_value);
     }
   } else if (old_value->IsTheHole()) {
     EnqueueChangeRecord(self, "reconfigured", name, old_value);
@@ -15451,6 +15469,8 @@
 // Add the specified break point object.
 void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
                                    Handle<Object> break_point_object) {
+  Isolate* isolate = break_point_info->GetIsolate();
+
   // If there was no break point objects before just set it.
   if (break_point_info->break_point_objects()->IsUndefined()) {
     break_point_info->set_break_point_objects(*break_point_object);
@@ -15460,7 +15480,7 @@
   if (break_point_info->break_point_objects() == *break_point_object) return;
   // If there was one break point object before replace with array.
   if (!break_point_info->break_point_objects()->IsFixedArray()) {
-    Handle<FixedArray> array = FACTORY->NewFixedArray(2);
+    Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
     array->set(0, break_point_info->break_point_objects());
     array->set(1, *break_point_object);
     break_point_info->set_break_point_objects(*array);
@@ -15471,7 +15491,7 @@
       Handle<FixedArray>(
           FixedArray::cast(break_point_info->break_point_objects()));
   Handle<FixedArray> new_array =
-      FACTORY->NewFixedArray(old_array->length() + 1);
+      isolate->factory()->NewFixedArray(old_array->length() + 1);
   for (int i = 0; i < old_array->length(); i++) {
     // If the break point was there before just ignore.
     if (old_array->get(i) == *break_point_object) return;
diff --git a/src/objects.h b/src/objects.h
index 0fa8ffa..a16ebbf 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1057,6 +1057,8 @@
   // Extract the number.
   inline double Number();
   inline bool IsNaN();
+  bool ToInt32(int32_t* value);
+  bool ToUint32(uint32_t* value);
 
   inline Representation OptimalRepresentation() {
     if (FLAG_track_fields && IsSmi()) {
@@ -5441,6 +5443,13 @@
   int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
                                   PropertyAttributes filter = NONE);
 
+  // Returns the number of slots allocated for the initial properties
+  // backing storage for instances of this map.
+  int InitialPropertiesLength() {
+    return pre_allocated_property_fields() + unused_property_fields() -
+        inobject_properties();
+  }
+
   // Casting.
   static inline Map* cast(Object* obj);
 
@@ -6068,18 +6077,6 @@
   inline int ic_age();
   inline void set_ic_age(int age);
 
-  // Add information on assignments of the form this.x = ...;
-  void SetThisPropertyAssignmentsInfo(
-      bool has_only_simple_this_property_assignments,
-      FixedArray* this_property_assignments);
-
-  // Clear information on assignments of the form this.x = ...;
-  void ClearThisPropertyAssignmentsInfo();
-
-  // Indicate that this function only consists of assignments of the form
-  // this.x = y; where y is either a constant or refers to an argument.
-  inline bool has_only_simple_this_property_assignments();
-
   // Indicates if this function can be lazy compiled.
   // This is used to determine if we can safely flush code from a function
   // when doing GC if we expect that the function will no longer be used.
@@ -6180,24 +6177,6 @@
   // disabled).
   bool VerifyBailoutId(BailoutId id);
 
-  // Check whether a inlined constructor can be generated with the given
-  // prototype.
-  bool CanGenerateInlineConstructor(Object* prototype);
-
-  // Prevents further attempts to generate inline constructors.
-  // To be called if generation failed for any reason.
-  void ForbidInlineConstructor();
-
-  // For functions which only contains this property assignments this provides
-  // access to the names for the properties assigned.
-  DECL_ACCESSORS(this_property_assignments, Object)
-  inline int this_property_assignments_count();
-  inline void set_this_property_assignments_count(int value);
-  String* GetThisPropertyAssignmentName(int index);
-  bool IsThisPropertyAssignmentArgument(int index);
-  int GetThisPropertyAssignmentArgument(int index);
-  Object* GetThisPropertyAssignmentConstant(int index);
-
   // [source code]: Source code for the function.
   bool HasSourceCode();
   Handle<Object> GetSourceCode();
@@ -6267,12 +6246,10 @@
   static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
   static const int kInitialMapOffset =
       kInferredNameOffset + kPointerSize;
-  static const int kThisPropertyAssignmentsOffset =
-      kInitialMapOffset + kPointerSize;
   // ast_node_count is a Smi field. It could be grouped with another Smi field
   // into a PSEUDO_SMI_ACCESSORS pair (on x64), if one becomes available.
   static const int kAstNodeCountOffset =
-      kThisPropertyAssignmentsOffset + kPointerSize;
+      kInitialMapOffset + kPointerSize;
 #if V8_HOST_ARCH_32_BIT
   // Smi fields.
   static const int kLengthOffset =
@@ -6290,10 +6267,7 @@
       kEndPositionOffset + kPointerSize;
   static const int kCompilerHintsOffset =
       kFunctionTokenPositionOffset + kPointerSize;
-  static const int kThisPropertyAssignmentsCountOffset =
-      kCompilerHintsOffset + kPointerSize;
-  static const int kOptCountOffset =
-      kThisPropertyAssignmentsCountOffset + kPointerSize;
+  static const int kOptCountOffset = kCompilerHintsOffset + kPointerSize;
   static const int kCountersOffset = kOptCountOffset + kPointerSize;
   static const int kStressDeoptCounterOffset = kCountersOffset + kPointerSize;
 
@@ -6329,10 +6303,7 @@
   static const int kCompilerHintsOffset =
       kFunctionTokenPositionOffset + kIntSize;
 
-  static const int kThisPropertyAssignmentsCountOffset =
-      kCompilerHintsOffset + kIntSize;
-  static const int kOptCountOffset =
-      kThisPropertyAssignmentsCountOffset + kIntSize;
+  static const int kOptCountOffset = kCompilerHintsOffset + kIntSize;
 
   static const int kCountersOffset = kOptCountOffset + kIntSize;
   static const int kStressDeoptCounterOffset = kCountersOffset + kIntSize;
@@ -6356,7 +6327,7 @@
   static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
 
   typedef FixedBodyDescriptor<kNameOffset,
-                              kThisPropertyAssignmentsOffset + kPointerSize,
+                              kInitialMapOffset + kPointerSize,
                               kSize> BodyDescriptor;
 
   // Bit positions in start_position_and_type.
@@ -6372,7 +6343,6 @@
   static const int kCodeAgeMask = (1 << kCodeAgeSize) - 1;
 
   enum CompilerHints {
-    kHasOnlySimpleThisPropertyAssignments,
     kAllowLazyCompilation,
     kAllowLazyCompilationWithoutContext,
     kLiveObjectsMayExist,
diff --git a/src/parser.cc b/src/parser.cc
index 6b53cb5..f032d97 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -490,8 +490,6 @@
     : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
       next_handler_index_(0),
       expected_property_count_(0),
-      only_simple_this_property_assignments_(false),
-      this_property_assignments_(isolate->factory()->empty_fixed_array()),
       generator_object_variable_(NULL),
       parser_(parser),
       outer_function_state_(parser->current_function_state_),
@@ -675,8 +673,6 @@
           function_state.materialized_literal_count(),
           function_state.expected_property_count(),
           function_state.handler_count(),
-          function_state.only_simple_this_property_assignments(),
-          function_state.this_property_assignments(),
           0,
           FunctionLiteral::kNoDuplicateParameters,
           FunctionLiteral::ANONYMOUS_EXPRESSION,
@@ -850,178 +846,6 @@
 }
 
 
-// A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
-// this.x = ...;, where x is a named property. It also determines whether a
-// function contains only assignments of this type.
-class ThisNamedPropertyAssignmentFinder {
- public:
-  ThisNamedPropertyAssignmentFinder(Isolate* isolate, Zone* zone)
-      : isolate_(isolate),
-        only_simple_this_property_assignments_(true),
-        names_(0, zone),
-        assigned_arguments_(0, zone),
-        assigned_constants_(0, zone),
-        zone_(zone) {
-  }
-
-  static Assignment* AsAssignment(Statement* stat) {
-    if (stat == NULL) return NULL;
-    ExpressionStatement* exp_stat = stat->AsExpressionStatement();
-    if (exp_stat == NULL) return NULL;
-    return exp_stat->expression()->AsAssignment();
-  }
-
-  void Update(Scope* scope, Statement* stat) {
-    // Bail out if function already has property assignment that are
-    // not simple this property assignments.
-    if (!only_simple_this_property_assignments_) {
-      return;
-    }
-
-    // Check whether this statement is of the form this.x = ...;
-    Assignment* assignment = AsAssignment(stat);
-    if (IsThisPropertyAssignment(assignment)) {
-      HandleThisPropertyAssignment(scope, assignment);
-    } else {
-      only_simple_this_property_assignments_ = false;
-    }
-  }
-
-  // Returns whether only statements of the form this.x = y; where y is either a
-  // constant or a function argument was encountered.
-  bool only_simple_this_property_assignments() {
-    return only_simple_this_property_assignments_;
-  }
-
-  // Returns a fixed array containing three elements for each assignment of the
-  // form this.x = y;
-  Handle<FixedArray> GetThisPropertyAssignments() {
-    if (names_.is_empty()) {
-      return isolate_->factory()->empty_fixed_array();
-    }
-    ASSERT_EQ(names_.length(), assigned_arguments_.length());
-    ASSERT_EQ(names_.length(), assigned_constants_.length());
-    Handle<FixedArray> assignments =
-        isolate_->factory()->NewFixedArray(names_.length() * 3);
-    for (int i = 0; i < names_.length(); ++i) {
-      assignments->set(i * 3, *names_[i]);
-      assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i]));
-      assignments->set(i * 3 + 2, *assigned_constants_[i]);
-    }
-    return assignments;
-  }
-
- private:
-  bool IsThisPropertyAssignment(Assignment* assignment) {
-    if (assignment != NULL) {
-      Property* property = assignment->target()->AsProperty();
-      return assignment->op() == Token::ASSIGN
-             && property != NULL
-             && property->obj()->AsVariableProxy() != NULL
-             && property->obj()->AsVariableProxy()->is_this();
-    }
-    return false;
-  }
-
-  void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
-    // Check that the property assigned to is a named property, which is not
-    // __proto__.
-    Property* property = assignment->target()->AsProperty();
-    ASSERT(property != NULL);
-    Literal* literal = property->key()->AsLiteral();
-    uint32_t dummy;
-    if (literal != NULL &&
-        literal->handle()->IsString() &&
-        !String::cast(*(literal->handle()))->Equals(
-            isolate_->heap()->proto_string()) &&
-        !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
-      Handle<String> key = Handle<String>::cast(literal->handle());
-
-      // Check whether the value assigned is either a constant or matches the
-      // name of one of the arguments to the function.
-      if (assignment->value()->AsLiteral() != NULL) {
-        // Constant assigned.
-        Literal* literal = assignment->value()->AsLiteral();
-        AssignmentFromConstant(key, literal->handle());
-        return;
-      } else if (assignment->value()->AsVariableProxy() != NULL) {
-        // Variable assigned.
-        Handle<String> name =
-            assignment->value()->AsVariableProxy()->name();
-        // Check whether the variable assigned matches an argument name.
-        for (int i = 0; i < scope->num_parameters(); i++) {
-          if (*scope->parameter(i)->name() == *name) {
-            // Assigned from function argument.
-            AssignmentFromParameter(key, i);
-            return;
-          }
-        }
-      }
-    }
-    // It is not a simple "this.x = value;" assignment with a constant
-    // or parameter value.
-    AssignmentFromSomethingElse();
-  }
-
-
-
-
-  // We will potentially reorder the property assignments, so they must be
-  // simple enough that the ordering does not matter.
-  void AssignmentFromParameter(Handle<String> name, int index) {
-    EnsureInitialized();
-    for (int i = 0; i < names_.length(); ++i) {
-      if (name->Equals(*names_[i])) {
-        assigned_arguments_[i] = index;
-        assigned_constants_[i] = isolate_->factory()->undefined_value();
-        return;
-      }
-    }
-    names_.Add(name, zone());
-    assigned_arguments_.Add(index, zone());
-    assigned_constants_.Add(isolate_->factory()->undefined_value(), zone());
-  }
-
-  void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
-    EnsureInitialized();
-    for (int i = 0; i < names_.length(); ++i) {
-      if (name->Equals(*names_[i])) {
-        assigned_arguments_[i] = -1;
-        assigned_constants_[i] = value;
-        return;
-      }
-    }
-    names_.Add(name, zone());
-    assigned_arguments_.Add(-1, zone());
-    assigned_constants_.Add(value, zone());
-  }
-
-  void AssignmentFromSomethingElse() {
-    // The this assignment is not a simple one.
-    only_simple_this_property_assignments_ = false;
-  }
-
-  void EnsureInitialized() {
-    if (names_.capacity() == 0) {
-      ASSERT(assigned_arguments_.capacity() == 0);
-      ASSERT(assigned_constants_.capacity() == 0);
-      names_.Initialize(4, zone());
-      assigned_arguments_.Initialize(4, zone());
-      assigned_constants_.Initialize(4, zone());
-    }
-  }
-
-  Zone* zone() const { return zone_; }
-
-  Isolate* isolate_;
-  bool only_simple_this_property_assignments_;
-  ZoneStringList names_;
-  ZoneList<int> assigned_arguments_;
-  ZoneObjectList assigned_constants_;
-  Zone* zone_;
-};
-
-
 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
                                   int end_token,
                                   bool is_eval,
@@ -1037,8 +861,6 @@
   TargetScope scope(&this->target_stack_);
 
   ASSERT(processor != NULL);
-  ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate(),
-                                                                    zone());
   bool directive_prologue = true;     // Parsing directive prologue.
 
   while (peek() != end_token) {
@@ -1098,25 +920,9 @@
       }
     }
 
-    // Find and mark all assignments to named properties in this (this.x =)
-    if (top_scope_->is_function_scope()) {
-      this_property_assignment_finder.Update(top_scope_, stat);
-    }
     processor->Add(stat, zone());
   }
 
-  // Propagate the collected information on this property assignments.
-  if (top_scope_->is_function_scope()) {
-    bool only_simple_this_property_assignments =
-        this_property_assignment_finder.only_simple_this_property_assignments()
-        && top_scope_->declarations()->length() == 0;
-    if (only_simple_this_property_assignments) {
-      current_function_state_->SetThisPropertyAssignmentInfo(
-          only_simple_this_property_assignments,
-          this_property_assignment_finder.GetThisPropertyAssignments());
-    }
-  }
-
   return 0;
 }
 
@@ -3845,8 +3651,9 @@
 
 
 Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
+  Factory* factory = Isolate::Current()->factory();
   ASSERT(IsCompileTimeValue(expression));
-  Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED);
+  Handle<FixedArray> result = factory->NewFixedArray(2, TENURED);
   ObjectLiteral* object_literal = expression->AsObjectLiteral();
   if (object_literal != NULL) {
     ASSERT(object_literal->is_simple());
@@ -4386,8 +4193,6 @@
   int materialized_literal_count = -1;
   int expected_property_count = -1;
   int handler_count = 0;
-  bool only_simple_this_property_assignments;
-  Handle<FixedArray> this_property_assignments;
   FunctionLiteral::ParameterFlag duplicate_parameters =
       FunctionLiteral::kNoDuplicateParameters;
   FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
@@ -4518,8 +4323,6 @@
           materialized_literal_count = entry.literal_count();
           expected_property_count = entry.property_count();
           top_scope_->SetLanguageMode(entry.language_mode());
-          only_simple_this_property_assignments = false;
-          this_property_assignments = isolate()->factory()->empty_fixed_array();
         } else {
           is_lazily_compiled = false;
         }
@@ -4554,8 +4357,6 @@
         materialized_literal_count = logger.literals();
         expected_property_count = logger.properties();
         top_scope_->SetLanguageMode(logger.language_mode());
-        only_simple_this_property_assignments = false;
-        this_property_assignments = isolate()->factory()->empty_fixed_array();
       }
     }
 
@@ -4608,9 +4409,6 @@
       materialized_literal_count = function_state.materialized_literal_count();
       expected_property_count = function_state.expected_property_count();
       handler_count = function_state.handler_count();
-      only_simple_this_property_assignments =
-          function_state.only_simple_this_property_assignments();
-      this_property_assignments = function_state.this_property_assignments();
 
       Expect(Token::RBRACE, CHECK_OK);
       scope->set_end_position(scanner().location().end_pos);
@@ -4676,8 +4474,6 @@
                                     materialized_literal_count,
                                     expected_property_count,
                                     handler_count,
-                                    only_simple_this_property_assignments,
-                                    this_property_assignments,
                                     num_parameters,
                                     duplicate_parameters,
                                     type,
diff --git a/src/parser.h b/src/parser.h
index 8a3ae92..ed9ee10 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -501,20 +501,6 @@
     int NextHandlerIndex() { return next_handler_index_++; }
     int handler_count() { return next_handler_index_; }
 
-    void SetThisPropertyAssignmentInfo(
-        bool only_simple_this_property_assignments,
-        Handle<FixedArray> this_property_assignments) {
-      only_simple_this_property_assignments_ =
-          only_simple_this_property_assignments;
-      this_property_assignments_ = this_property_assignments;
-    }
-    bool only_simple_this_property_assignments() {
-      return only_simple_this_property_assignments_;
-    }
-    Handle<FixedArray> this_property_assignments() {
-      return this_property_assignments_;
-    }
-
     void AddProperty() { expected_property_count_++; }
     int expected_property_count() { return expected_property_count_; }
 
@@ -544,11 +530,6 @@
     // Properties count estimation.
     int expected_property_count_;
 
-    // Keeps track of assignments to properties of this. Used for
-    // optimizing constructors.
-    bool only_simple_this_property_assignments_;
-    Handle<FixedArray> this_property_assignments_;
-
     // For generators, the variable that holds the generator object.  This
     // variable is used by yield expressions and return statements.  NULL
     // indicates that this function is not a generator.
diff --git a/src/runtime.cc b/src/runtime.cc
index 45ff822..f8147a2 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2513,10 +2513,6 @@
   // Since we don't store the source we should never optimize this.
   target_shared->code()->set_optimizable(false);
 
-  // Clear the optimization hints related to the compiled code as these
-  // are no longer valid when the code is overwritten.
-  target_shared->ClearThisPropertyAssignmentsInfo();
-
   // Set the code of the target function.
   target->ReplaceCode(source_shared->code());
   ASSERT(target->next_function_link()->IsUndefined());
@@ -2816,7 +2812,8 @@
   }
 
   Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
-    FACTORY->SetContent(target_array, array_);
+    Factory* factory = target_array->GetIsolate()->factory();
+    factory->SetContent(target_array, array_);
     target_array->set_length(Smi::FromInt(length_));
     return target_array;
   }
@@ -7772,7 +7769,7 @@
       // called using 'new' and creates a new JSFunction object that
       // is returned.  The receiver object is only used for error
       // reporting if an error occurs when constructing the new
-      // JSFunction. FACTORY->NewJSObject() should not be used to
+      // JSFunction. Factory::NewJSObject() should not be used to
       // allocate JSFunctions since it does not properly initialize
       // the shared part of the function. Since the receiver is
       // ignored anyway, we use the global object as the receiver
@@ -13004,6 +13001,7 @@
   // Scan the heap for Script objects to find the script with the requested
   // script data.
   Handle<Script> script;
+  Factory* factory = script_name->GetIsolate()->factory();
   Heap* heap = script_name->GetHeap();
   heap->EnsureHeapIsIterable();
   DisallowHeapAllocation no_allocation_during_heap_iteration;
@@ -13021,7 +13019,7 @@
   }
 
   // If no script with the requested script data is found return undefined.
-  if (script.is_null()) return FACTORY->undefined_value();
+  if (script.is_null()) return factory->undefined_value();
 
   // Return the script found.
   return GetScriptWrapper(script);
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 15ee29f..b9dea22 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -74,7 +74,8 @@
       + parameter_count + stack_local_count + 2 * context_local_count
       + (has_function_name ? 2 : 0);
 
-  Handle<ScopeInfo> scope_info = FACTORY->NewScopeInfo(length);
+  Factory* factory = Isolate::Current()->factory();
+  Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
 
   // Encode the flags.
   int flags = TypeField::encode(scope->type()) |
diff --git a/src/string-stream.cc b/src/string-stream.cc
index ba4a65c..1096225 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -290,7 +290,8 @@
 
 
 Handle<String> StringStream::ToString() {
-  return FACTORY->NewStringFromUtf8(Vector<const char>(buffer_, length_));
+  Factory* factory = Isolate::Current()->factory();
+  return factory->NewStringFromUtf8(Vector<const char>(buffer_, length_));
 }
 
 
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 84e761f..76eb076 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1191,8 +1191,8 @@
   HandleScope scope(isolate);
   Handle<Name> name_handle(name);
   Handle<Object> error =
-      FACTORY->NewReferenceError("not_defined",
-                                  HandleVector(&name_handle, 1));
+      isolate->factory()->NewReferenceError("not_defined",
+                                            HandleVector(&name_handle, 1));
   return isolate->Throw(*error);
 }
 
@@ -2029,15 +2029,6 @@
 }
 
 
-Handle<Code> ConstructStubCompiler::GetCode() {
-  Code::Flags flags = Code::ComputeFlags(Code::STUB);
-  Handle<Code> code = GetCodeWithFlags(flags, "ConstructStub");
-  PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, "ConstructStub"));
-  GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", *code));
-  return code;
-}
-
-
 CallOptimization::CallOptimization(LookupResult* lookup) {
   if (lookup->IsFound() &&
       lookup->IsCacheable() &&
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 9365d96..a1b55d8 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -1067,17 +1067,6 @@
 };
 
 
-class ConstructStubCompiler: public StubCompiler {
- public:
-  explicit ConstructStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
-
-  Handle<Code> CompileConstructStub(Handle<JSFunction> function);
-
- private:
-  Handle<Code> GetCode();
-};
-
-
 // Holds information about possible function call optimizations.
 class CallOptimization BASE_EMBEDDED {
  public:
diff --git a/src/type-info.cc b/src/type-info.cc
index 0fa46e7..b284062 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -168,12 +168,7 @@
 
 bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) {
   Handle<Object> info = GetInfo(expr->CallNewFeedbackId());
-  if (info->IsSmi()) {
-    ASSERT(static_cast<ElementsKind>(Smi::cast(*info)->value()) <=
-           LAST_FAST_ELEMENTS_KIND);
-    return isolate_->global_context()->array_function();
-  }
-  return info->IsJSFunction();
+  return info->IsSmi() || info->IsJSFunction();
 }
 
 
@@ -298,7 +293,14 @@
 
 
 Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) {
-  return Handle<JSFunction>::cast(GetInfo(expr->CallFeedbackId()));
+  Handle<Object> info = GetInfo(expr->CallFeedbackId());
+  if (info->IsSmi()) {
+    ASSERT(static_cast<ElementsKind>(Smi::cast(*info)->value()) <=
+           LAST_FAST_ELEMENTS_KIND);
+    return Handle<JSFunction>(isolate_->global_context()->array_function());
+  } else {
+    return Handle<JSFunction>::cast(info);
+  }
 }
 
 
@@ -456,7 +458,9 @@
 void TypeFeedbackOracle::BinaryType(BinaryOperation* expr,
                                     TypeInfo* left,
                                     TypeInfo* right,
-                                    TypeInfo* result) {
+                                    TypeInfo* result,
+                                    bool* has_fixed_right_arg,
+                                    int* fixed_right_arg_value) {
   Handle<Object> object = GetInfo(expr->BinaryOperationFeedbackId());
   TypeInfo unknown = TypeInfo::Unknown();
   if (!object->IsCode()) {
@@ -465,12 +469,17 @@
   }
   Handle<Code> code = Handle<Code>::cast(object);
   if (code->is_binary_op_stub()) {
+    int minor_key = code->stub_info();
     BinaryOpIC::TypeInfo left_type, right_type, result_type;
-    BinaryOpStub::decode_types_from_minor_key(code->stub_info(), &left_type,
-                                              &right_type, &result_type);
+    BinaryOpStub::decode_types_from_minor_key(
+        minor_key, &left_type, &right_type, &result_type);
     *left = TypeFromBinaryOpType(left_type);
     *right = TypeFromBinaryOpType(right_type);
     *result = TypeFromBinaryOpType(result_type);
+    *has_fixed_right_arg =
+        BinaryOpStub::decode_has_fixed_right_arg_from_minor_key(minor_key);
+    *fixed_right_arg_value =
+        BinaryOpStub::decode_fixed_right_arg_value_from_minor_key(minor_key);
     return;
   }
   // Not a binary op stub.
@@ -663,7 +672,7 @@
       : 0;
   int length = infos->length() + cell_count;
   byte* old_start = code->instruction_start();
-  dictionary_ = FACTORY->NewUnseededNumberDictionary(length);
+  dictionary_ = isolate()->factory()->NewUnseededNumberDictionary(length);
   byte* new_start = code->instruction_start();
   RelocateRelocInfos(infos, old_start, new_start);
 }
diff --git a/src/type-info.h b/src/type-info.h
index 6c7e31a..15a0b81 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -305,7 +305,9 @@
   void BinaryType(BinaryOperation* expr,
                   TypeInfo* left,
                   TypeInfo* right,
-                  TypeInfo* result);
+                  TypeInfo* result,
+                  bool* has_fixed_right_arg,
+                  int* fixed_right_arg_value);
   void CompareType(CompareOperation* expr,
                    TypeInfo* left_type,
                    TypeInfo* right_type,
diff --git a/src/utils.h b/src/utils.h
index b16730b..5680384 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -86,6 +86,25 @@
 }
 
 
+inline int MostSignificantBit(uint32_t x) {
+  static const int msb4[] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4};
+  int nibble = 0;
+  if (x & 0xffff0000) {
+    nibble += 16;
+    x >>= 16;
+  }
+  if (x & 0xff00) {
+    nibble += 8;
+    x >>= 8;
+  }
+  if (x & 0xf0) {
+    nibble += 4;
+    x >>= 4;
+  }
+  return nibble + msb4[x];
+}
+
+
 // Magic numbers for integer division.
 // These are kind of 2's complement reciprocal of the divisors.
 // Details and proofs can be found in:
diff --git a/src/v8natives.js b/src/v8natives.js
index f5ab122..d444613 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -873,6 +873,7 @@
   // Step 3 - Special handling for length property.
   if (p === "length") {
     var length = obj.length;
+    var old_length = length;
     if (!desc.hasValue()) {
       return DefineObjectProperty(obj, "length", desc, should_throw);
     }
@@ -889,8 +890,24 @@
       }
     }
     var threw = false;
+
+    var emit_splice = %IsObserved(obj) && new_length !== old_length;
+    var removed;
+    if (emit_splice) {
+      BeginPerformSplice(obj);
+      removed = [];
+      if (new_length < old_length)
+        removed.length = old_length - new_length;
+    }
+
     while (new_length < length--) {
-      if (!Delete(obj, ToString(length), false)) {
+      var index = ToString(length);
+      if (emit_splice) {
+        var deletedDesc = GetOwnProperty(obj, index);
+        if (deletedDesc && deletedDesc.hasValue())
+          removed[length - new_length] = deletedDesc.getValue();
+      }
+      if (!Delete(obj, index, false)) {
         new_length = length + 1;
         threw = true;
         break;
@@ -902,13 +919,18 @@
     // respective TODO in Runtime_DefineOrRedefineDataProperty.
     // For the time being, we need a hack to prevent Object.observe from
     // generating two change records.
-    var isObserved = %IsObserved(obj);
-    if (isObserved) %SetIsObserved(obj, false);
     obj.length = new_length;
     desc.value_ = void 0;
     desc.hasValue_ = false;
     threw = !DefineObjectProperty(obj, "length", desc, should_throw) || threw;
-    if (isObserved) %SetIsObserved(obj, true);
+    if (emit_splice) {
+      EndPerformSplice(obj);
+      EnqueueSpliceRecord(obj,
+          new_length < old_length ? new_length : old_length,
+          removed,
+          removed.length,
+          new_length > old_length ? new_length - old_length : 0);
+    }
     if (threw) {
       if (should_throw) {
         throw MakeTypeError("redefine_disallowed", [p]);
@@ -916,27 +938,24 @@
         return false;
       }
     }
-    if (isObserved) {
-      var new_desc = GetOwnProperty(obj, "length");
-      var updated = length_desc.value_ !== new_desc.value_;
-      var reconfigured = length_desc.writable_ !== new_desc.writable_ ||
-          length_desc.configurable_ !== new_desc.configurable_ ||
-          length_desc.enumerable_ !== new_desc.configurable_;
-      if (updated || reconfigured) {
-        NotifyChange(reconfigured ? "reconfigured" : "updated",
-            obj, "length", length_desc.value_);
-      }
-    }
     return true;
   }
 
   // Step 4 - Special handling for array index.
   var index = ToUint32(p);
+  var emit_splice = false;
   if (ToString(index) == p && index != 4294967295) {
     var length = obj.length;
+    if (index >= length && %IsObserved(obj)) {
+      emit_splice = true;
+      BeginPerformSplice(obj);
+    }
+
     var length_desc = GetOwnProperty(obj, "length");
     if ((index >= length && !length_desc.isWritable()) ||
         !DefineObjectProperty(obj, p, desc, true)) {
+      if (emit_splice)
+        EndPerformSplice(obj);
       if (should_throw) {
         throw MakeTypeError("define_disallowed", [p]);
       } else {
@@ -946,6 +965,10 @@
     if (index >= length) {
       obj.length = index + 1;
     }
+    if (emit_splice) {
+      EndPerformSplice(obj);
+      EnqueueSpliceRecord(obj, length, [], 0, index + 1 - length);
+    }
     return true;
   }
 
diff --git a/src/version.cc b/src/version.cc
index ca4eaa5..204eb45 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     19
-#define BUILD_NUMBER      8
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      9
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index b1b99b4..2a01b0b 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -1477,14 +1477,20 @@
 
   // Run the native code for the InternalArray function called as a normal
   // function.
-  ArrayNativeCode(masm, &generic_array_code);
+  if (FLAG_optimize_constructed_arrays) {
+    // tail call a stub
+    InternalArrayConstructorStub stub(masm->isolate());
+    __ TailCallStub(&stub);
+  } else {
+    ArrayNativeCode(masm, &generic_array_code);
 
-  // Jump to the generic array code in case the specialized code cannot handle
-  // the construction.
-  __ bind(&generic_array_code);
-  Handle<Code> array_code =
-      masm->isolate()->builtins()->InternalArrayCodeGeneric();
-  __ Jump(array_code, RelocInfo::CODE_TARGET);
+    // Jump to the generic array code in case the specialized code cannot handle
+    // the construction.
+    __ bind(&generic_array_code);
+    Handle<Code> array_code =
+        masm->isolate()->builtins()->InternalArrayCodeGeneric();
+    __ Jump(array_code, RelocInfo::CODE_TARGET);
+  }
 }
 
 
@@ -1511,14 +1517,24 @@
   }
 
   // Run the native code for the Array function called as a normal function.
-  ArrayNativeCode(masm, &generic_array_code);
+  if (FLAG_optimize_constructed_arrays) {
+    // tail call a stub
+    Handle<Object> undefined_sentinel(
+        masm->isolate()->heap()->undefined_value(),
+        masm->isolate());
+    __ Move(rbx, undefined_sentinel);
+    ArrayConstructorStub stub(masm->isolate());
+    __ TailCallStub(&stub);
+  } else {
+    ArrayNativeCode(masm, &generic_array_code);
 
-  // Jump to the generic array code in case the specialized code cannot handle
-  // the construction.
-  __ bind(&generic_array_code);
-  Handle<Code> array_code =
-      masm->isolate()->builtins()->ArrayCodeGeneric();
-  __ Jump(array_code, RelocInfo::CODE_TARGET);
+    // Jump to the generic array code in case the specialized code cannot handle
+    // the construction.
+    __ bind(&generic_array_code);
+    Handle<Code> array_code =
+        masm->isolate()->builtins()->ArrayCodeGeneric();
+    __ Jump(array_code, RelocInfo::CODE_TARGET);
+  }
 }
 
 
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 5da0990..f5d38f3 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -137,6 +137,28 @@
 }
 
 
+static void InitializeInternalArrayConstructorDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor,
+    int constant_stack_parameter_count) {
+  // register state
+  // rax -- number of arguments
+  // rdi -- constructor function
+  static Register registers[] = { rdi };
+  descriptor->register_param_count_ = 1;
+
+  if (constant_stack_parameter_count != 0) {
+    // stack param count needs (constructor pointer, and single argument)
+    descriptor->stack_parameter_count_ = &rax;
+  }
+  descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
+  descriptor->register_params_ = registers;
+  descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
+  descriptor->deoptimization_handler_ =
+      FUNCTION_ADDR(InternalArrayConstructor_StubFailure);
+}
+
+
 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -158,6 +180,27 @@
 }
 
 
+void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 0);
+}
+
+
+void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, 1);
+}
+
+
+void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
+    Isolate* isolate,
+    CodeStubInterfaceDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate, descriptor, -1);
+}
+
+
 void CompareNilICStub::InitializeInterfaceDescriptor(
     Isolate* isolate,
     CodeStubInterfaceDescriptor* descriptor) {
@@ -1188,7 +1231,15 @@
 
 
 void BinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
-  Label call_runtime;
+  Label right_arg_changed, call_runtime;
+
+  if (op_ == Token::MOD && has_fixed_right_arg_) {
+    // It is guaranteed that the value will fit into a Smi, because if it
+    // didn't, we wouldn't be here, see BinaryOp_Patch.
+    __ Cmp(rax, Smi::FromInt(fixed_right_arg_value()));
+    __ j(not_equal, &right_arg_changed);
+  }
+
   if (result_type_ == BinaryOpIC::UNINITIALIZED ||
       result_type_ == BinaryOpIC::SMI) {
     // Only allow smi results.
@@ -1202,6 +1253,7 @@
 
   // Code falls through if the result is not returned as either a smi or heap
   // number.
+  __ bind(&right_arg_changed);
   GenerateTypeTransition(masm);
 
   if (call_runtime.is_linked()) {
@@ -3435,7 +3487,7 @@
       __ bind(&check_for_nan);
     }
 
-    // Test for NaN. Sadly, we can't just compare to FACTORY->nan_value(),
+    // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
     // so we do the second best thing - test it ourselves.
     Label heap_number;
     // If it's not a heap number, then return equal for (in)equality operator.
@@ -3809,7 +3861,11 @@
   __ j(not_equal, &slow);
 
   if (RecordCallTarget()) {
-    GenerateRecordCallTargetNoArray(masm);
+    if (FLAG_optimize_constructed_arrays) {
+      GenerateRecordCallTarget(masm);
+    } else {
+      GenerateRecordCallTargetNoArray(masm);
+    }
   }
 
   // Fast-case: Just invoke the function.
@@ -4386,7 +4442,7 @@
   static const int kOffsetToResultValue = 18;
   // The last 4 bytes of the instruction sequence
   //   movq(rdi, FieldOperand(rax, HeapObject::kMapOffset))
-  //   Move(kScratchRegister, FACTORY->the_hole_value())
+  //   Move(kScratchRegister, Factory::the_hole_value())
   // in front of the hole value address.
   static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78;
   // The last 4 bytes of the instruction sequence
@@ -6821,6 +6877,10 @@
     ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
     T stub(kind);
     stub.GetCode(isolate)->set_is_pregenerated(true);
+    if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+      T stub1(kind, true);
+      stub1.GetCode(isolate)->set_is_pregenerated(true);
+    }
   }
 }
 
@@ -6835,6 +6895,20 @@
 }
 
 
+void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
+    Isolate* isolate) {
+  ElementsKind kinds[2] = { FAST_ELEMENTS, FAST_HOLEY_ELEMENTS };
+  for (int i = 0; i < 2; i++) {
+    // For internal arrays we only need a few things
+    InternalArrayNoArgumentConstructorStub stubh1(kinds[i]);
+    stubh1.GetCode(isolate)->set_is_pregenerated(true);
+    InternalArraySingleArgumentConstructorStub stubh2(kinds[i]);
+    stubh2.GetCode(isolate)->set_is_pregenerated(true);
+    InternalArrayNArgumentsConstructorStub stubh3(kinds[i]);
+    stubh3.GetCode(isolate)->set_is_pregenerated(true);
+  }
+}
+
 
 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
   // ----------- S t a t e -------------
@@ -6922,6 +6996,108 @@
 }
 
 
+void InternalArrayConstructorStub::GenerateCase(
+    MacroAssembler* masm, ElementsKind kind) {
+  Label not_zero_case, not_one_case;
+  Label normal_sequence;
+
+  __ testq(rax, rax);
+  __ j(not_zero, &not_zero_case);
+  InternalArrayNoArgumentConstructorStub stub0(kind);
+  __ TailCallStub(&stub0);
+
+  __ bind(&not_zero_case);
+  __ cmpl(rax, Immediate(1));
+  __ j(greater, &not_one_case);
+
+  if (IsFastPackedElementsKind(kind)) {
+    // We might need to create a holey array
+    // look at the first argument
+    __ movq(rcx, Operand(rsp, kPointerSize));
+    __ testq(rcx, rcx);
+    __ j(zero, &normal_sequence);
+
+    InternalArraySingleArgumentConstructorStub
+        stub1_holey(GetHoleyElementsKind(kind));
+    __ TailCallStub(&stub1_holey);
+  }
+
+  __ bind(&normal_sequence);
+  InternalArraySingleArgumentConstructorStub stub1(kind);
+  __ TailCallStub(&stub1);
+
+  __ bind(&not_one_case);
+  InternalArrayNArgumentsConstructorStub stubN(kind);
+  __ TailCallStub(&stubN);
+}
+
+
+void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- eax : argc
+  //  -- ebx : type info cell
+  //  -- edi : constructor
+  //  -- esp[0] : return address
+  //  -- esp[4] : last argument
+  // -----------------------------------
+
+  if (FLAG_debug_code) {
+    // The array construct code is only set for the global and natives
+    // builtin Array functions which always have maps.
+
+    // Initial map for the builtin Array function should be a map.
+    __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
+    // Will both indicate a NULL and a Smi.
+    STATIC_ASSERT(kSmiTag == 0);
+    Condition not_smi = NegateCondition(masm->CheckSmi(rcx));
+    __ Check(not_smi, "Unexpected initial map for Array function");
+    __ CmpObjectType(rcx, MAP_TYPE, rcx);
+    __ Check(equal, "Unexpected initial map for Array function");
+  }
+
+  if (FLAG_optimize_constructed_arrays) {
+    // Figure out the right elements kind
+    __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
+
+    // Load the map's "bit field 2" into |result|. We only need the first byte,
+    // but the following masking takes care of that anyway.
+    __ movzxbq(rcx, FieldOperand(rcx, Map::kBitField2Offset));
+    // Retrieve elements_kind from bit field 2.
+    __ and_(rcx, Immediate(Map::kElementsKindMask));
+    __ shr(rcx, Immediate(Map::kElementsKindShift));
+
+    if (FLAG_debug_code) {
+      Label done;
+      __ cmpl(rcx, Immediate(FAST_ELEMENTS));
+      __ j(equal, &done);
+      __ cmpl(rcx, Immediate(FAST_HOLEY_ELEMENTS));
+      __ Assert(equal,
+          "Invalid ElementsKind for InternalArray or InternalPackedArray");
+      __ bind(&done);
+    }
+
+    Label fast_elements_case;
+    __ cmpl(rcx, Immediate(FAST_ELEMENTS));
+    __ j(equal, &fast_elements_case);
+    GenerateCase(masm, FAST_HOLEY_ELEMENTS);
+
+    __ bind(&fast_elements_case);
+    GenerateCase(masm, FAST_ELEMENTS);
+  } else {
+    Label generic_constructor;
+    // Run the native code for the Array function called as constructor.
+    ArrayNativeCode(masm, &generic_constructor);
+
+    // Jump to the generic construct code in case the specialized code cannot
+    // handle the construction.
+    __ bind(&generic_constructor);
+    Handle<Code> generic_construct_stub =
+        masm->isolate()->builtins()->JSConstructStubGeneric();
+    __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
+  }
+}
+
+
 #undef __
 
 } }  // namespace v8::internal
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index e03c023..ed4896d 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -2934,7 +2934,7 @@
   __ jmp(&entry);
   __ bind(&loop);
   __ movq(rdx, FieldOperand(rbx, 0));
-  __ Cmp(rdx, FACTORY->value_of_string());
+  __ Cmp(rdx, isolate()->factory()->value_of_string());
   __ j(equal, if_false);
   __ addq(rbx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize));
   __ bind(&entry);
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 6425f89..efb41c8 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -1380,6 +1380,23 @@
 }
 
 
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+
+  __ pop(rbx);
+  __ push(rax);  // receiver
+  __ push(rcx);  // name
+  __ push(rbx);  // return address
+
+  // Perform tail call to the entry.
+  __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
+}
+
+
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm, ICMissMode miss_mode) {
   // ----------- S t a t e -------------
   //  -- rax    : key
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index cb3cd44..4a469f7 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3935,14 +3935,17 @@
   __ Set(rax, instr->arity());
   __ Move(rbx, instr->hydrogen()->property_cell());
   ElementsKind kind = instr->hydrogen()->elements_kind();
+  bool disable_allocation_sites =
+      (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE);
+
   if (instr->arity() == 0) {
-    ArrayNoArgumentConstructorStub stub(kind);
+    ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else if (instr->arity() == 1) {
-    ArraySingleArgumentConstructorStub stub(kind);
+    ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   } else {
-    ArrayNArgumentsConstructorStub stub(kind);
+    ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites);
     CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
   }
 }
@@ -5088,94 +5091,6 @@
 }
 
 
-void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
-  class DeferredAllocateObject: public LDeferredCode {
-   public:
-    DeferredAllocateObject(LCodeGen* codegen, LAllocateObject* instr)
-        : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
-    virtual LInstruction* instr() { return instr_; }
-   private:
-    LAllocateObject* instr_;
-  };
-
-  DeferredAllocateObject* deferred =
-      new(zone()) DeferredAllocateObject(this, instr);
-
-  Register result = ToRegister(instr->result());
-  Register scratch = ToRegister(instr->temp());
-  Handle<JSFunction> constructor = instr->hydrogen()->constructor();
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-  ASSERT(initial_map->pre_allocated_property_fields() +
-         initial_map->unused_property_fields() -
-         initial_map->inobject_properties() == 0);
-
-  __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(),
-              TAG_OBJECT);
-
-  __ bind(deferred->exit());
-  if (FLAG_debug_code) {
-    Label is_in_new_space;
-    __ JumpIfInNewSpace(result, scratch, &is_in_new_space);
-    __ Abort("Allocated object is not in new-space");
-    __ bind(&is_in_new_space);
-  }
-
-  // Load the initial map.
-  Register map = scratch;
-  __ LoadHeapObject(scratch, constructor);
-  __ movq(map, FieldOperand(scratch, JSFunction::kPrototypeOrInitialMapOffset));
-
-  if (FLAG_debug_code) {
-    __ AssertNotSmi(map);
-    __ cmpb(FieldOperand(map, Map::kInstanceSizeOffset),
-            Immediate(instance_size >> kPointerSizeLog2));
-    __ Assert(equal, "Unexpected instance size");
-    __ cmpb(FieldOperand(map, Map::kPreAllocatedPropertyFieldsOffset),
-            Immediate(initial_map->pre_allocated_property_fields()));
-    __ Assert(equal, "Unexpected pre-allocated property fields count");
-    __ cmpb(FieldOperand(map, Map::kUnusedPropertyFieldsOffset),
-            Immediate(initial_map->unused_property_fields()));
-    __ Assert(equal, "Unexpected unused property fields count");
-    __ cmpb(FieldOperand(map, Map::kInObjectPropertiesOffset),
-            Immediate(initial_map->inobject_properties()));
-    __ Assert(equal, "Unexpected in-object property fields count");
-  }
-
-  // Initialize map and fields of the newly allocated object.
-  ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
-  __ movq(FieldOperand(result, JSObject::kMapOffset), map);
-  __ LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
-  __ movq(FieldOperand(result, JSObject::kElementsOffset), scratch);
-  __ movq(FieldOperand(result, JSObject::kPropertiesOffset), scratch);
-  if (initial_map->inobject_properties() != 0) {
-    __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
-    for (int i = 0; i < initial_map->inobject_properties(); i++) {
-      int property_offset = JSObject::kHeaderSize + i * kPointerSize;
-      __ movq(FieldOperand(result, property_offset), scratch);
-    }
-  }
-}
-
-
-void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
-  Register result = ToRegister(instr->result());
-  Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
-  int instance_size = initial_map->instance_size();
-
-  // TODO(3095996): Get rid of this. For now, we need to make the
-  // result register contain a valid pointer because it is already
-  // contained in the register pointer map.
-  __ Set(result, 0);
-
-  PushSafepointRegistersScope scope(this);
-  __ Push(Smi::FromInt(instance_size));
-  CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
-  __ StoreToSafepointRegisterSlot(result, rax);
-}
-
-
 void LCodeGen::DoAllocate(LAllocate* instr) {
   class DeferredAllocate: public LDeferredCode {
    public:
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index 9890649..07a948c 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -130,7 +130,6 @@
   void DoDeferredRandom(LRandom* instr);
   void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
   void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
-  void DoDeferredAllocateObject(LAllocateObject* instr);
   void DoDeferredAllocate(LAllocate* instr);
   void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                                        Label* map_check);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index fe23709..e50be08 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -427,7 +427,14 @@
   } else {
     stream->Add("] <- ");
   }
-  value()->PrintTo(stream);
+
+  if (value() == NULL) {
+    ASSERT(hydrogen()->IsConstantHoleStore() &&
+           hydrogen()->value()->representation().IsDouble());
+    stream->Add("<the hole(nan)>");
+  } else {
+    value()->PrintTo(stream);
+  }
 }
 
 
@@ -706,6 +713,12 @@
 }
 
 
+LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
   return AssignEnvironment(new(zone()) LDeoptimize);
 }
@@ -2328,13 +2341,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
-  info()->MarkAsDeferredCalling();
-  LAllocateObject* result = new(zone()) LAllocateObject(TempRegister());
-  return AssignPointerMap(DefineAsRegister(result));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* size = instr->size()->IsConstant()
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 36b080f..1121af5 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -50,7 +50,6 @@
   V(AccessArgumentsAt)                          \
   V(AddI)                                       \
   V(Allocate)                                   \
-  V(AllocateObject)                             \
   V(ApplyArguments)                             \
   V(ArgumentsElements)                          \
   V(ArgumentsLength)                            \
@@ -2363,19 +2362,6 @@
 };
 
 
-class LAllocateObject: public LTemplateInstruction<1, 0, 1> {
- public:
-  explicit LAllocateObject(LOperand* temp) {
-    temps_[0] = temp;
-  }
-
-  LOperand* temp() { return temps_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
-  DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
-};
-
-
 class LAllocate: public LTemplateInstruction<1, 1, 1> {
  public:
   LAllocate(LOperand* size, LOperand* temp) {
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index c1cab8f..bc3df68 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -2961,139 +2961,6 @@
 }
 
 
-// Specialized stub for constructing objects from functions which only have only
-// simple assignments of the form this.x = ...; in their body.
-Handle<Code> ConstructStubCompiler::CompileConstructStub(
-    Handle<JSFunction> function) {
-  // ----------- S t a t e -------------
-  //  -- rax : argc
-  //  -- rdi : constructor
-  //  -- rsp[0] : return address
-  //  -- rsp[4] : last argument
-  // -----------------------------------
-  Label generic_stub_call;
-
-  // Use r8 for holding undefined which is used in several places below.
-  __ Move(r8, factory()->undefined_value());
-
-#ifdef ENABLE_DEBUGGER_SUPPORT
-  // Check to see whether there are any break points in the function code. If
-  // there are jump to the generic constructor stub which calls the actual
-  // code for the function thereby hitting the break points.
-  __ movq(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
-  __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kDebugInfoOffset));
-  __ cmpq(rbx, r8);
-  __ j(not_equal, &generic_stub_call);
-#endif
-
-  // Load the initial map and verify that it is in fact a map.
-  // rdi: constructor
-  __ movq(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
-  // Will both indicate a NULL and a Smi.
-  STATIC_ASSERT(kSmiTag == 0);
-  __ JumpIfSmi(rbx, &generic_stub_call);
-  __ CmpObjectType(rbx, MAP_TYPE, rcx);
-  __ j(not_equal, &generic_stub_call);
-
-#ifdef DEBUG
-  // Cannot construct functions this way.
-  // rbx: initial map
-  __ CmpInstanceType(rbx, JS_FUNCTION_TYPE);
-  __ Check(not_equal, "Function constructed by construct stub.");
-#endif
-
-  // Now allocate the JSObject in new space.
-  // rbx: initial map
-  ASSERT(function->has_initial_map());
-  int instance_size = function->initial_map()->instance_size();
-#ifdef DEBUG
-  __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
-  __ shl(rcx, Immediate(kPointerSizeLog2));
-  __ cmpq(rcx, Immediate(instance_size));
-  __ Check(equal, "Instance size of initial map changed.");
-#endif
-  __ Allocate(instance_size, rdx, rcx, no_reg, &generic_stub_call,
-              NO_ALLOCATION_FLAGS);
-
-  // Allocated the JSObject, now initialize the fields and add the heap tag.
-  // rbx: initial map
-  // rdx: JSObject (untagged)
-  __ movq(Operand(rdx, JSObject::kMapOffset), rbx);
-  __ Move(rbx, factory()->empty_fixed_array());
-  __ movq(Operand(rdx, JSObject::kPropertiesOffset), rbx);
-  __ movq(Operand(rdx, JSObject::kElementsOffset), rbx);
-
-  // rax: argc
-  // rdx: JSObject (untagged)
-  // Load the address of the first in-object property into r9.
-  __ lea(r9, Operand(rdx, JSObject::kHeaderSize));
-  // Calculate the location of the first argument. The stack contains only the
-  // return address on top of the argc arguments.
-  __ lea(rcx, Operand(rsp, rax, times_pointer_size, 0));
-
-  // rax: argc
-  // rcx: first argument
-  // rdx: JSObject (untagged)
-  // r8: undefined
-  // r9: first in-object property of the JSObject
-  // Fill the initialized properties with a constant value or a passed argument
-  // depending on the this.x = ...; assignment in the function.
-  Handle<SharedFunctionInfo> shared(function->shared());
-  for (int i = 0; i < shared->this_property_assignments_count(); i++) {
-    if (shared->IsThisPropertyAssignmentArgument(i)) {
-      // Check if the argument assigned to the property is actually passed.
-      // If argument is not passed the property is set to undefined,
-      // otherwise find it on the stack.
-      int arg_number = shared->GetThisPropertyAssignmentArgument(i);
-      __ movq(rbx, r8);
-      __ cmpq(rax, Immediate(arg_number));
-      __ cmovq(above, rbx, Operand(rcx, arg_number * -kPointerSize));
-      // Store value in the property.
-      __ movq(Operand(r9, i * kPointerSize), rbx);
-    } else {
-      // Set the property to the constant value.
-      Handle<Object> constant(shared->GetThisPropertyAssignmentConstant(i),
-                              isolate());
-      __ Move(Operand(r9, i * kPointerSize), constant);
-    }
-  }
-
-  // Fill the unused in-object property fields with undefined.
-  for (int i = shared->this_property_assignments_count();
-       i < function->initial_map()->inobject_properties();
-       i++) {
-    __ movq(Operand(r9, i * kPointerSize), r8);
-  }
-
-  // rax: argc
-  // rdx: JSObject (untagged)
-  // Move argc to rbx and the JSObject to return to rax and tag it.
-  __ movq(rbx, rax);
-  __ movq(rax, rdx);
-  __ or_(rax, Immediate(kHeapObjectTag));
-
-  // rax: JSObject
-  // rbx: argc
-  // Remove caller arguments and receiver from the stack and return.
-  __ pop(rcx);
-  __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize));
-  __ push(rcx);
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->constructed_objects(), 1);
-  __ IncrementCounter(counters->constructed_objects_stub(), 1);
-  __ ret(0);
-
-  // Jump to the generic stub in case the specialized code cannot handle the
-  // construction.
-  __ bind(&generic_stub_call);
-  Handle<Code> code = isolate()->builtins()->JSConstructStubGeneric();
-  __ Jump(code, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode();
-}
-
-
 #undef __
 #define __ ACCESS_MASM(masm)
 
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 6297f56..8ce11eb 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -73,6 +73,12 @@
 test-serialize/DeserializeFromSecondSerialization: SKIP
 
 ##############################################################################
+[ $arch == mipsel ]
+
+# BUG(2628): The test sometimes fails on MIPS simulator.
+test-cpu-profiler/SampleWhenFrameIsNotSetup: PASS || FAIL
+
+##############################################################################
 [ $arch == android_arm || $arch == android_ia32 ]
 
 # Tests crash as there is no /tmp directory in Android.
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index bc469aa..d316c8e 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -117,25 +117,27 @@
 
 
 TEST(StressJS) {
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(v8::Isolate::GetCurrent());
   v8::Handle<v8::Context> env = v8::Context::New(v8::Isolate::GetCurrent());
   env->Enter();
   Handle<JSFunction> function =
-      FACTORY->NewFunction(FACTORY->function_string(), FACTORY->null_value());
+      factory->NewFunction(factory->function_string(), factory->null_value());
   // Force the creation of an initial map and set the code to
   // something empty.
-  FACTORY->NewJSObject(function);
+  factory->NewJSObject(function);
   function->ReplaceCode(Isolate::Current()->builtins()->builtin(
       Builtins::kEmptyFunction));
   // Patch the map to have an accessor for "get".
   Handle<Map> map(function->initial_map());
   Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
-  Handle<Foreign> foreign = FACTORY->NewForeign(&kDescriptor);
+  Handle<Foreign> foreign = factory->NewForeign(&kDescriptor);
   Handle<String> name =
-      FACTORY->NewStringFromAscii(Vector<const char>("get", 3));
+      factory->NewStringFromAscii(Vector<const char>("get", 3));
   ASSERT(instance_descriptors->IsEmpty());
 
-  Handle<DescriptorArray> new_descriptors = FACTORY->NewDescriptorArray(0, 1);
+  Handle<DescriptorArray> new_descriptors = factory->NewDescriptorArray(0, 1);
 
   v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
   map->set_instance_descriptors(*new_descriptors);
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 26a9207..cb3a38e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -596,6 +596,7 @@
 
 
 THREADED_TEST(UsingExternalString) {
+  i::Factory* factory = i::Isolate::Current()->factory();
   {
     v8::HandleScope scope(v8::Isolate::GetCurrent());
     uint16_t* two_byte_string = AsciiToTwoByteString("test string");
@@ -606,7 +607,7 @@
     HEAP->CollectGarbage(i::NEW_SPACE);  // in survivor space now
     HEAP->CollectGarbage(i::NEW_SPACE);  // in old gen now
     i::Handle<i::String> isymbol =
-        FACTORY->InternalizedStringFromString(istring);
+        factory->InternalizedStringFromString(istring);
     CHECK(isymbol->IsInternalizedString());
   }
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -615,6 +616,7 @@
 
 
 THREADED_TEST(UsingExternalAsciiString) {
+  i::Factory* factory = i::Isolate::Current()->factory();
   {
     v8::HandleScope scope(v8::Isolate::GetCurrent());
     const char* one_byte_string = "test string";
@@ -625,7 +627,7 @@
     HEAP->CollectGarbage(i::NEW_SPACE);  // in survivor space now
     HEAP->CollectGarbage(i::NEW_SPACE);  // in old gen now
     i::Handle<i::String> isymbol =
-        FACTORY->InternalizedStringFromString(istring);
+        factory->InternalizedStringFromString(istring);
     CHECK(isymbol->IsInternalizedString());
   }
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -13509,6 +13511,7 @@
   uint16_t* two_byte_string = AsciiToTwoByteString(c_string);
   {
     LocalContext env;
+    i::Factory* factory = i::Isolate::Current()->factory();
     v8::HandleScope scope(env->GetIsolate());
     AsciiVectorResource ascii_resource(
         i::Vector<const char>(c_string, i::StrLength(c_string)));
@@ -13517,9 +13520,9 @@
                                   i::StrLength(c_string)));
 
     Local<String> lhs(v8::Utils::ToLocal(
-        FACTORY->NewExternalStringFromAscii(&ascii_resource)));
+        factory->NewExternalStringFromAscii(&ascii_resource)));
     Local<String> rhs(v8::Utils::ToLocal(
-        FACTORY->NewExternalStringFromAscii(&ascii_resource)));
+        factory->NewExternalStringFromAscii(&ascii_resource)));
 
     env->Global()->Set(v8_str("lhs"), lhs);
     env->Global()->Set(v8_str("rhs"), rhs);
@@ -13606,6 +13609,8 @@
         uc16_resource_(i::Vector<const uint16_t>(two_byte_content_, 15)) {}
   ~RegExpStringModificationTest() { delete block_; }
   void RunTest() {
+    i::Factory* factory = i::Isolate::Current()->factory();
+
     regexp_success_ = false;
     morph_success_ = false;
 
@@ -13618,11 +13623,11 @@
 
     // Create the input string for the regexp - the one we are going to change
     // properties of.
-    input_ = FACTORY->NewExternalStringFromAscii(&ascii_resource_);
+    input_ = factory->NewExternalStringFromAscii(&ascii_resource_);
 
     // Inject the input as a global variable.
     i::Handle<i::String> input_name =
-        FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5));
+        factory->NewStringFromAscii(i::Vector<const char>("input", 5));
     i::Isolate::Current()->native_context()->global_object()->SetProperty(
         *input_name,
         *input_,
@@ -14116,12 +14121,13 @@
 
 THREADED_TEST(PixelArray) {
   LocalContext context;
+  i::Factory* factory = i::Isolate::Current()->factory();
   v8::HandleScope scope(context->GetIsolate());
   const int kElementCount = 260;
   uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
   i::Handle<i::ExternalPixelArray> pixels =
       i::Handle<i::ExternalPixelArray>::cast(
-          FACTORY->NewExternalArray(kElementCount,
+          factory->NewExternalArray(kElementCount,
                                     v8::kExternalPixelArray,
                                     pixel_data));
   // Force GC to trigger verification.
@@ -14538,12 +14544,13 @@
 
 THREADED_TEST(PixelArrayWithInterceptor) {
   LocalContext context;
+  i::Factory* factory = i::Isolate::Current()->factory();
   v8::HandleScope scope(context->GetIsolate());
   const int kElementCount = 260;
   uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount));
   i::Handle<i::ExternalPixelArray> pixels =
       i::Handle<i::ExternalPixelArray>::cast(
-          FACTORY->NewExternalArray(kElementCount,
+          factory->NewExternalArray(kElementCount,
                                     v8::kExternalPixelArray,
                                     pixel_data));
   for (int i = 0; i < kElementCount; i++) {
@@ -14905,6 +14912,7 @@
                                     int64_t low,
                                     int64_t high) {
   LocalContext context;
+  i::Factory* factory = i::Isolate::Current()->factory();
   v8::HandleScope scope(context->GetIsolate());
   const int kElementCount = 40;
   int element_size = ExternalArrayElementSize(array_type);
@@ -14912,7 +14920,7 @@
       static_cast<ElementType*>(malloc(kElementCount * element_size));
   i::Handle<ExternalArrayClass> array =
       i::Handle<ExternalArrayClass>::cast(
-          FACTORY->NewExternalArray(kElementCount, array_type, array_data));
+          factory->NewExternalArray(kElementCount, array_type, array_data));
   // Force GC to trigger verification.
   HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
   for (int i = 0; i < kElementCount; i++) {
@@ -15849,10 +15857,11 @@
 }
 
 static void CreateGarbageInOldSpace() {
+  i::Factory* factory = i::Isolate::Current()->factory();
   v8::HandleScope scope(v8::Isolate::GetCurrent());
   i::AlwaysAllocateScope always_allocate;
   for (int i = 0; i < 1000; i++) {
-    FACTORY->NewFixedArray(1000, i::TENURED);
+    factory->NewFixedArray(1000, i::TENURED);
   }
 }
 
@@ -17528,13 +17537,6 @@
   explicit Visitor42(v8::Persistent<v8::Object>* object)
       : counter_(0), object_(object) { }
 
-#ifdef V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS
-  virtual void VisitPersistentHandle(Persistent<Value> value,
-                                     uint16_t class_id) {
-    VisitPersistentHandle(&value, class_id);
-  }
-#endif
-
   virtual void VisitPersistentHandle(Persistent<Value>* value,
                                      uint16_t class_id) {
     if (class_id != 42) return;
@@ -18547,18 +18549,19 @@
 
 TEST(StaticGetters) {
   LocalContext context;
+  i::Factory* factory = i::Isolate::Current()->factory();
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
   v8::HandleScope scope(isolate);
-  i::Handle<i::Object> undefined_value = FACTORY->undefined_value();
+  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();
+  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();
+  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();
+  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);
 
@@ -18609,9 +18612,10 @@
 
 TEST(StringEmpty) {
   LocalContext context;
+  i::Factory* factory = i::Isolate::Current()->factory();
   v8::Isolate* isolate = v8::Isolate::GetCurrent();
   v8::HandleScope scope(isolate);
-  i::Handle<i::Object> empty_string = FACTORY->empty_string();
+  i::Handle<i::Object> empty_string = factory->empty_string();
   CHECK(*v8::Utils::OpenHandle(*v8::String::Empty()) == *empty_string);
   CHECK(*v8::Utils::OpenHandle(*v8::String::Empty(isolate)) == *empty_string);
 
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc
index 61eaa98..232f846 100644
--- a/test/cctest/test-assembler-arm.cc
+++ b/test/cctest/test-assembler-arm.cc
@@ -133,7 +133,7 @@
 
   // some relocated stuff here, not executed
   __ RecordComment("dead code, just testing relocations");
-  __ mov(r0, Operand(FACTORY->true_value()));
+  __ mov(r0, Operand(isolate->factory()->true_value()));
   __ RecordComment("dead code, just testing immediate operands");
   __ mov(r0, Operand(-1));
   __ mov(r0, Operand(0xFF000000));
diff --git a/test/cctest/test-assembler-ia32.cc b/test/cctest/test-assembler-ia32.cc
index 8d39ee7..880370f 100644
--- a/test/cctest/test-assembler-ia32.cc
+++ b/test/cctest/test-assembler-ia32.cc
@@ -137,7 +137,7 @@
   __ ret(0);
 
   // some relocated stuff here, not executed
-  __ mov(eax, FACTORY->true_value());
+  __ mov(eax, isolate->factory()->true_value());
   __ jmp(NULL, RelocInfo::RUNTIME_ENTRY);
 
   CodeDesc desc;
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index f200435..b74ccb2 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -80,9 +80,10 @@
 
 
 static MaybeObject* GetGlobalProperty(const char* name) {
-  Handle<String> internalized_name = FACTORY->InternalizeUtf8String(name);
-  return Isolate::Current()->context()->global_object()->GetProperty(
-      *internalized_name);
+  Isolate* isolate = Isolate::Current();
+  Handle<String> internalized_name =
+      isolate->factory()->InternalizeUtf8String(name);
+  return isolate->context()->global_object()->GetProperty(*internalized_name);
 }
 
 
@@ -97,19 +98,21 @@
 
 
 static Handle<JSFunction> Compile(const char* source) {
-  Handle<String> source_code(FACTORY->NewStringFromUtf8(CStrVector(source)));
+  Isolate* isolate = Isolate::Current();
+  Handle<String> source_code(
+      isolate->factory()->NewStringFromUtf8(CStrVector(source)));
   Handle<SharedFunctionInfo> shared_function =
       Compiler::Compile(source_code,
                         Handle<String>(),
                         0,
                         0,
-                        Handle<Context>(Isolate::Current()->native_context()),
+                        Handle<Context>(isolate->native_context()),
                         NULL,
                         NULL,
                         Handle<String>::null(),
                         NOT_NATIVES_CODE);
-  return FACTORY->NewFunctionFromSharedFunctionInfo(shared_function,
-      Isolate::Current()->native_context());
+  return isolate->factory()->NewFunctionFromSharedFunctionInfo(
+      shared_function, isolate->native_context());
 }
 
 
@@ -283,16 +286,15 @@
   Execution::Call(fun0, global, 0, NULL, &has_pending_exception);
   CHECK(!has_pending_exception);
 
-  Object* foo_string =
-      FACTORY->InternalizeOneByteString(STATIC_ASCII_VECTOR("foo"))->
-        ToObjectChecked();
+  Object* foo_string = isolate->factory()->InternalizeOneByteString(
+      STATIC_ASCII_VECTOR("foo"))->ToObjectChecked();
   MaybeObject* fun1_object = isolate->context()->global_object()->
       GetProperty(String::cast(foo_string));
   Handle<Object> fun1(fun1_object->ToObjectChecked(), isolate);
   CHECK(fun1->IsJSFunction());
 
-  Handle<Object> argv[] =
-    { FACTORY->InternalizeOneByteString(STATIC_ASCII_VECTOR("hello")) };
+  Handle<Object> argv[] = { isolate->factory()->InternalizeOneByteString(
+      STATIC_ASCII_VECTOR("hello")) };
   Execution::Call(Handle<JSFunction>::cast(fun1),
                   global,
                   ARRAY_SIZE(argv),
@@ -306,9 +308,11 @@
 // source resulted in crash.
 TEST(Regression236) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
 
-  Handle<Script> script = FACTORY->NewScript(FACTORY->empty_string());
+  Handle<Script> script = factory->NewScript(factory->empty_string());
   script->set_source(HEAP->undefined_value());
   CHECK_EQ(-1, GetScriptLineNumber(script, 0));
   CHECK_EQ(-1, GetScriptLineNumber(script, 100));
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 2234e11..901c116 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -638,3 +638,158 @@
 
   cpu_profiler->DeleteAllCpuProfiles();
 }
+
+
+static const char* native_accessor_test_source = "function start(count) {\n"
+"  for (var i = 0; i < count; i++) {\n"
+"    var o = instance.foo;\n"
+"    instance.foo = o + 1;\n"
+"  }\n"
+"}\n";
+
+
+class FooAccessorsData {
+ public:
+  explicit FooAccessorsData(int min_duration_ms)
+      : min_duration_ms_(min_duration_ms),
+        getter_duration_(0),
+        setter_duration_(0) {}
+
+  static v8::Handle<v8::Value> Getter(v8::Local<v8::String> name,
+                                      const v8::AccessorInfo& info) {
+    FooAccessorsData* data = fromInfo(info);
+    data->getter_duration_ = data->Wait();
+    return v8::Int32::New(2013);
+  }
+
+  static void Setter(v8::Local<v8::String> name,
+                     v8::Local<v8::Value> value,
+                     const v8::AccessorInfo& info) {
+    FooAccessorsData* data = fromInfo(info);
+    data->setter_duration_ = data->Wait();
+  }
+
+  void PrintAccessorTime() {
+    i::OS::Print("getter: %f ms; setter: %f ms\n", getter_duration_,
+        setter_duration_);
+  }
+
+ private:
+  double Wait() {
+    double start = i::OS::TimeCurrentMillis();
+    double duration = 0;
+    while (duration < min_duration_ms_) {
+      duration = i::OS::TimeCurrentMillis() - start;
+    }
+    return duration;
+  }
+
+  static FooAccessorsData* fromInfo(const v8::AccessorInfo& info) {
+    void* data = v8::External::Cast(*info.Data())->Value();
+    return reinterpret_cast<FooAccessorsData*>(data);
+  }
+
+  int min_duration_ms_;
+  double getter_duration_;
+  double setter_duration_;
+};
+
+
+// Test that native accessors are properly reported in the CPU profile.
+// This test checks the case when the long-running accessors are called
+// only once and the optimizer doesn't have chance to change the invocation
+// code.
+TEST(NativeAccessorNameInProfile1) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+
+
+  v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New();
+  v8::Local<v8::ObjectTemplate> instance_template =
+      func_template->InstanceTemplate();
+
+  FooAccessorsData accessors(100);
+  v8::Local<v8::External> data = v8::External::New(&accessors);
+  instance_template->SetAccessor(
+      v8::String::New("foo"), &FooAccessorsData::Getter,
+      &FooAccessorsData::Setter, data);
+  v8::Local<v8::Function> func = func_template->GetFunction();
+  v8::Local<v8::Object> instance = func->NewInstance();
+  env->Global()->Set(v8::String::New("instance"), instance);
+
+  v8::Script::Compile(v8::String::New(native_accessor_test_source))->Run();
+  v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("start")));
+
+  v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
+  v8::Local<v8::String> profile_name = v8::String::New("my_profile");
+
+  cpu_profiler->StartCpuProfiling(profile_name);
+  int32_t repeat_count = 1;
+  v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) };
+  function->Call(env->Global(), ARRAY_SIZE(args), args);
+  const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
+
+  CHECK_NE(NULL, profile);
+  // Dump collected profile to have a better diagnostic in case of failure.
+  reinterpret_cast<i::CpuProfile*>(
+      const_cast<v8::CpuProfile*>(profile))->Print();
+  accessors.PrintAccessorTime();
+
+  const v8::CpuProfileNode* root = profile->GetTopDownRoot();
+  const v8::CpuProfileNode* startNode = GetChild(root, "start");
+  GetChild(startNode, "get foo");
+  GetChild(startNode, "set foo");
+
+  cpu_profiler->DeleteAllCpuProfiles();
+}
+
+
+// Test that native accessors are properly reported in the CPU profile.
+// This test makes sure that the accessors are called enough times to become
+// hot and to trigger optimizations.
+TEST(NativeAccessorNameInProfile2) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+
+
+  v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New();
+  v8::Local<v8::ObjectTemplate> instance_template =
+      func_template->InstanceTemplate();
+
+  FooAccessorsData accessors(1);
+  v8::Local<v8::External> data = v8::External::New(&accessors);
+  instance_template->SetAccessor(
+      v8::String::New("foo"), &FooAccessorsData::Getter,
+      &FooAccessorsData::Setter, data);
+  v8::Local<v8::Function> func = func_template->GetFunction();
+  v8::Local<v8::Object> instance = func->NewInstance();
+  env->Global()->Set(v8::String::New("instance"), instance);
+
+  v8::Script::Compile(v8::String::New(native_accessor_test_source))->Run();
+  v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
+      env->Global()->Get(v8::String::New("start")));
+
+  v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
+  v8::Local<v8::String> profile_name = v8::String::New("my_profile");
+
+  cpu_profiler->StartCpuProfiling(profile_name);
+  int32_t repeat_count = 100;
+  v8::Handle<v8::Value> args[] = { v8::Integer::New(repeat_count) };
+  function->Call(env->Global(), ARRAY_SIZE(args), args);
+  const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
+
+  CHECK_NE(NULL, profile);
+  // Dump collected profile to have a better diagnostic in case of failure.
+  reinterpret_cast<i::CpuProfile*>(
+      const_cast<v8::CpuProfile*>(profile))->Print();
+
+  const v8::CpuProfileNode* root = profile->GetTopDownRoot();
+  const v8::CpuProfileNode* startNode = GetChild(root, "start");
+  // TODO(yurys): in LoadIC should be changed to report external callback
+  // invocation. See r13768 where it was LoadCallbackProperty was removed.
+  // GetChild(startNode, "get foo");
+  GetChild(startNode, "set foo");
+
+  cpu_profiler->DeleteAllCpuProfiles();
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index d802a85..b22092a 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -149,6 +149,7 @@
   void ExposeDebug() {
     v8::internal::Isolate* isolate =
         reinterpret_cast<v8::internal::Isolate*>(context_->GetIsolate());
+    v8::internal::Factory* factory = isolate->factory();
     v8::internal::Debug* debug = isolate->debug();
     // Expose the debug context global object in the global object for testing.
     debug->Load();
@@ -158,7 +159,7 @@
     Handle<JSGlobalProxy> global(Handle<JSGlobalProxy>::cast(
         v8::Utils::OpenHandle(*context_->Global())));
     Handle<v8::internal::String> debug_string =
-        FACTORY->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug"));
+        factory->InternalizeOneByteString(STATIC_ASCII_VECTOR("debug"));
     SetProperty(isolate, global, debug_string,
                 Handle<Object>(debug->debug_context()->global_proxy(), isolate),
                 DONT_ENUM,
@@ -404,7 +405,7 @@
 
   // Allocate array for the debugged functions
   Handle<FixedArray> debugged_functions =
-      FACTORY->NewFixedArray(count);
+      Isolate::Current()->factory()->NewFixedArray(count);
 
   // Run through the debug info objects and collect all functions.
   count = 0;
diff --git a/test/cctest/test-dictionary.cc b/test/cctest/test-dictionary.cc
index 32fff60..27c4fe4 100644
--- a/test/cctest/test-dictionary.cc
+++ b/test/cctest/test-dictionary.cc
@@ -41,10 +41,12 @@
 
 TEST(ObjectHashTable) {
   LocalContext context;
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(context->GetIsolate());
-  Handle<ObjectHashTable> table = FACTORY->NewObjectHashTable(23);
-  Handle<JSObject> a = FACTORY->NewJSArray(7);
-  Handle<JSObject> b = FACTORY->NewJSArray(11);
+  Handle<ObjectHashTable> table = factory->NewObjectHashTable(23);
+  Handle<JSObject> a = factory->NewJSArray(7);
+  Handle<JSObject> b = factory->NewJSArray(11);
   table = PutIntoObjectHashTable(table, a, b);
   CHECK_EQ(table->NumberOfElements(), 1);
   CHECK_EQ(table->Lookup(*a), *b);
@@ -57,12 +59,12 @@
   CHECK_EQ(table->Lookup(*b), HEAP->the_hole_value());
 
   // Keys that are overwritten should not change number of elements.
-  table = PutIntoObjectHashTable(table, a, FACTORY->NewJSArray(13));
+  table = PutIntoObjectHashTable(table, a, factory->NewJSArray(13));
   CHECK_EQ(table->NumberOfElements(), 1);
   CHECK_NE(table->Lookup(*a), *b);
 
   // Keys mapped to the hole should be removed permanently.
-  table = PutIntoObjectHashTable(table, a, FACTORY->the_hole_value());
+  table = PutIntoObjectHashTable(table, a, factory->the_hole_value());
   CHECK_EQ(table->NumberOfElements(), 0);
   CHECK_EQ(table->NumberOfDeletedElements(), 1);
   CHECK_EQ(table->Lookup(*a), HEAP->the_hole_value());
@@ -70,8 +72,8 @@
   // Keys should map back to their respective values and also should get
   // an identity hash code generated.
   for (int i = 0; i < 100; i++) {
-    Handle<JSObject> key = FACTORY->NewJSArray(7);
-    Handle<JSObject> value = FACTORY->NewJSArray(11);
+    Handle<JSObject> key = factory->NewJSArray(7);
+    Handle<JSObject> value = factory->NewJSArray(11);
     table = PutIntoObjectHashTable(table, key, value);
     CHECK_EQ(table->NumberOfElements(), i + 1);
     CHECK_NE(table->FindEntry(*key), ObjectHashTable::kNotFound);
@@ -82,7 +84,7 @@
   // Keys never added to the map which already have an identity hash
   // code should not be found.
   for (int i = 0; i < 100; i++) {
-    Handle<JSObject> key = FACTORY->NewJSArray(7);
+    Handle<JSObject> key = factory->NewJSArray(7);
     CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
     CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
     CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
@@ -92,7 +94,7 @@
   // Keys that don't have an identity hash should not be found and also
   // should not get an identity hash code generated.
   for (int i = 0; i < 100; i++) {
-    Handle<JSObject> key = FACTORY->NewJSArray(7);
+    Handle<JSObject> key = factory->NewJSArray(7);
     CHECK_EQ(table->Lookup(*key), HEAP->the_hole_value());
     CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), HEAP->undefined_value());
   }
@@ -102,9 +104,11 @@
 #ifdef DEBUG
 TEST(ObjectHashSetCausesGC) {
   LocalContext context;
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(context->GetIsolate());
-  Handle<ObjectHashSet> table = FACTORY->NewObjectHashSet(1);
-  Handle<JSObject> key = FACTORY->NewJSArray(0);
+  Handle<ObjectHashSet> table = factory->NewObjectHashSet(1);
+  Handle<JSObject> key = factory->NewJSArray(0);
   v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key);
 
   // Force allocation of hash table backing store for hidden properties.
@@ -132,9 +136,11 @@
 #ifdef DEBUG
 TEST(ObjectHashTableCausesGC) {
   LocalContext context;
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(context->GetIsolate());
-  Handle<ObjectHashTable> table = FACTORY->NewObjectHashTable(1);
-  Handle<JSObject> key = FACTORY->NewJSArray(0);
+  Handle<ObjectHashTable> table = factory->NewObjectHashTable(1);
+  Handle<JSObject> key = factory->NewJSArray(0);
   v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key);
 
   // Force allocation of hash table backing store for hidden properties.
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index ca81a5a..14447b2 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -61,7 +61,7 @@
   __ sub(eax, Immediate(12345678));
   __ xor_(eax, 12345678);
   __ and_(eax, 12345678);
-  Handle<FixedArray> foo = FACTORY->NewFixedArray(10, TENURED);
+  Handle<FixedArray> foo = isolate->factory()->NewFixedArray(10, TENURED);
   __ cmp(eax, foo);
 
   // ---- This one caused crash
@@ -92,7 +92,7 @@
   __ cmp(edx, 3);
   __ cmp(edx, Operand(esp, 4));
   __ cmp(Operand(ebp, ecx, times_4, 0), Immediate(1000));
-  Handle<FixedArray> foo2 = FACTORY->NewFixedArray(10, TENURED);
+  Handle<FixedArray> foo2 = isolate->factory()->NewFixedArray(10, TENURED);
   __ cmp(ebx, foo2);
   __ cmpb(ebx, Operand(ebp, ecx, times_2, 0));
   __ cmpb(Operand(ebp, ecx, times_2, 0), ebx);
diff --git a/test/cctest/test-func-name-inference.cc b/test/cctest/test-func-name-inference.cc
index dcc6272..a0c4b1e 100644
--- a/test/cctest/test-func-name-inference.cc
+++ b/test/cctest/test-func-name-inference.cc
@@ -51,6 +51,9 @@
 static void CheckFunctionName(v8::Handle<v8::Script> script,
                               const char* func_pos_src,
                               const char* ref_inferred_name) {
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+
   // Get script source.
   Handle<Object> obj = v8::Utils::OpenHandle(*script);
   Handle<SharedFunctionInfo> shared_function;
@@ -67,8 +70,8 @@
 
   // Find the position of a given func source substring in the source.
   Handle<String> func_pos_str =
-      FACTORY->NewStringFromAscii(CStrVector(func_pos_src));
-  int func_pos = Runtime::StringMatch(Isolate::Current(),
+      factory->NewStringFromAscii(CStrVector(func_pos_src));
+  int func_pos = Runtime::StringMatch(isolate,
                                       script_src,
                                       func_pos_str,
                                       0);
@@ -76,10 +79,9 @@
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Obtain SharedFunctionInfo for the function.
-  Isolate::Current()->debug()->PrepareForBreakPoints();
+  isolate->debug()->PrepareForBreakPoints();
   Object* shared_func_info_ptr =
-      Isolate::Current()->debug()->FindSharedFunctionInfoInScript(i_script,
-                                                                  func_pos);
+      isolate->debug()->FindSharedFunctionInfoInScript(i_script, func_pos);
   CHECK(shared_func_info_ptr != HEAP->undefined_value());
   Handle<SharedFunctionInfo> shared_func_info(
       SharedFunctionInfo::cast(shared_func_info_ptr));
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 0c66c8f..68ed83d 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -146,6 +146,7 @@
 TEST(HeapObjects) {
   CcTest::InitializeVM();
   Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   Heap* heap = isolate->heap();
 
   HandleScope sc(isolate);
@@ -201,7 +202,7 @@
   CHECK(heap->nan_value()->IsNumber());
   CHECK(std::isnan(heap->nan_value()->Number()));
 
-  Handle<String> s = FACTORY->NewStringFromAscii(CStrVector("fisk hest "));
+  Handle<String> s = factory->NewStringFromAscii(CStrVector("fisk hest "));
   CHECK(s->IsString());
   CHECK_EQ(10, s->length());
 
@@ -339,10 +340,12 @@
 
 TEST(LocalHandles) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   v8::HandleScope scope(CcTest::isolate());
   const char* name = "Kasper the spunky";
-  Handle<String> string = FACTORY->NewStringFromAscii(CStrVector(name));
+  Handle<String> string = factory->NewStringFromAscii(CStrVector(name));
   CHECK_EQ(StrLength(name), string->length());
 }
 
@@ -609,17 +612,19 @@
 
 TEST(FunctionAllocation) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   v8::HandleScope sc(CcTest::isolate());
-  Handle<String> name = FACTORY->InternalizeUtf8String("theFunction");
+  Handle<String> name = factory->InternalizeUtf8String("theFunction");
   Handle<JSFunction> function =
-      FACTORY->NewFunction(name, FACTORY->undefined_value());
+      factory->NewFunction(name, factory->undefined_value());
   Handle<Map> initial_map =
-      FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+      factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   function->set_initial_map(*initial_map);
 
-  Handle<String> prop_name = FACTORY->InternalizeUtf8String("theSlot");
-  Handle<JSObject> obj = FACTORY->NewJSObject(function);
+  Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
+  Handle<JSObject> obj = factory->NewJSObject(function);
   obj->SetProperty(
       *prop_name, Smi::FromInt(23), NONE, kNonStrictMode)->ToObjectChecked();
   CHECK_EQ(Smi::FromInt(23), obj->GetProperty(*prop_name));
@@ -632,6 +637,8 @@
 
 TEST(ObjectProperties) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   v8::HandleScope sc(CcTest::isolate());
   String* object_string = String::cast(HEAP->Object_string());
@@ -639,9 +646,9 @@
       GetProperty(object_string)->ToObjectChecked();
   JSFunction* object_function = JSFunction::cast(raw_object);
   Handle<JSFunction> constructor(object_function);
-  Handle<JSObject> obj = FACTORY->NewJSObject(constructor);
-  Handle<String> first = FACTORY->InternalizeUtf8String("first");
-  Handle<String> second = FACTORY->InternalizeUtf8String("second");
+  Handle<JSObject> obj = factory->NewJSObject(constructor);
+  Handle<String> first = factory->InternalizeUtf8String("first");
+  Handle<String> second = factory->InternalizeUtf8String("second");
 
   // check for empty
   CHECK(!obj->HasLocalProperty(*first));
@@ -687,35 +694,37 @@
 
   // check string and internalized string match
   const char* string1 = "fisk";
-  Handle<String> s1 = FACTORY->NewStringFromAscii(CStrVector(string1));
+  Handle<String> s1 = factory->NewStringFromAscii(CStrVector(string1));
   obj->SetProperty(
       *s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
-  Handle<String> s1_string = FACTORY->InternalizeUtf8String(string1);
+  Handle<String> s1_string = factory->InternalizeUtf8String(string1);
   CHECK(obj->HasLocalProperty(*s1_string));
 
   // check internalized string and string match
   const char* string2 = "fugl";
-  Handle<String> s2_string = FACTORY->InternalizeUtf8String(string2);
+  Handle<String> s2_string = factory->InternalizeUtf8String(string2);
   obj->SetProperty(
       *s2_string, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
-  Handle<String> s2 = FACTORY->NewStringFromAscii(CStrVector(string2));
+  Handle<String> s2 = factory->NewStringFromAscii(CStrVector(string2));
   CHECK(obj->HasLocalProperty(*s2));
 }
 
 
 TEST(JSObjectMaps) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   v8::HandleScope sc(CcTest::isolate());
-  Handle<String> name = FACTORY->InternalizeUtf8String("theFunction");
+  Handle<String> name = factory->InternalizeUtf8String("theFunction");
   Handle<JSFunction> function =
-      FACTORY->NewFunction(name, FACTORY->undefined_value());
+      factory->NewFunction(name, factory->undefined_value());
   Handle<Map> initial_map =
-      FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+      factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   function->set_initial_map(*initial_map);
 
-  Handle<String> prop_name = FACTORY->InternalizeUtf8String("theSlot");
-  Handle<JSObject> obj = FACTORY->NewJSObject(function);
+  Handle<String> prop_name = factory->InternalizeUtf8String("theSlot");
+  Handle<JSObject> obj = factory->NewJSObject(function);
 
   // Set a propery
   obj->SetProperty(
@@ -729,16 +738,18 @@
 
 TEST(JSArray) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   v8::HandleScope sc(CcTest::isolate());
-  Handle<String> name = FACTORY->InternalizeUtf8String("Array");
+  Handle<String> name = factory->InternalizeUtf8String("Array");
   Object* raw_object = Isolate::Current()->context()->global_object()->
       GetProperty(*name)->ToObjectChecked();
   Handle<JSFunction> function = Handle<JSFunction>(
       JSFunction::cast(raw_object));
 
   // Allocate the object.
-  Handle<JSObject> object = FACTORY->NewJSObject(function);
+  Handle<JSObject> object = factory->NewJSObject(function);
   Handle<JSArray> array = Handle<JSArray>::cast(object);
   // We just initialized the VM, no heap allocation failure yet.
   array->Initialize(0)->ToObjectChecked();
@@ -756,7 +767,7 @@
 
   // Set array length with larger than smi value.
   Handle<Object> length =
-      FACTORY->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
+      factory->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
   array->SetElementsLength(*length)->ToObjectChecked();
 
   uint32_t int_length = 0;
@@ -776,6 +787,8 @@
 
 TEST(JSObjectCopy) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   v8::HandleScope sc(CcTest::isolate());
   String* object_string = String::cast(HEAP->Object_string());
@@ -783,9 +796,9 @@
       GetProperty(object_string)->ToObjectChecked();
   JSFunction* object_function = JSFunction::cast(raw_object);
   Handle<JSFunction> constructor(object_function);
-  Handle<JSObject> obj = FACTORY->NewJSObject(constructor);
-  Handle<String> first = FACTORY->InternalizeUtf8String("first");
-  Handle<String> second = FACTORY->InternalizeUtf8String("second");
+  Handle<JSObject> obj = factory->NewJSObject(constructor);
+  Handle<String> first = factory->InternalizeUtf8String("first");
+  Handle<String> second = factory->InternalizeUtf8String("second");
 
   obj->SetProperty(
       *first, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
@@ -824,6 +837,8 @@
 
 TEST(StringAllocation) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   const unsigned char chars[] = { 0xe5, 0xa4, 0xa7 };
   for (int length = 0; length < 100; length++) {
@@ -839,18 +854,18 @@
       non_ascii[3 * i + 2] = chars[2];
     }
     Handle<String> non_ascii_sym =
-        FACTORY->InternalizeUtf8String(
+        factory->InternalizeUtf8String(
             Vector<const char>(non_ascii, 3 * length));
     CHECK_EQ(length, non_ascii_sym->length());
     Handle<String> ascii_sym =
-        FACTORY->InternalizeOneByteString(OneByteVector(ascii, length));
+        factory->InternalizeOneByteString(OneByteVector(ascii, length));
     CHECK_EQ(length, ascii_sym->length());
     Handle<String> non_ascii_str =
-        FACTORY->NewStringFromUtf8(Vector<const char>(non_ascii, 3 * length));
+        factory->NewStringFromUtf8(Vector<const char>(non_ascii, 3 * length));
     non_ascii_str->Hash();
     CHECK_EQ(length, non_ascii_str->length());
     Handle<String> ascii_str =
-        FACTORY->NewStringFromUtf8(Vector<const char>(ascii, length));
+        factory->NewStringFromUtf8(Vector<const char>(ascii, length));
     ascii_str->Hash();
     CHECK_EQ(length, ascii_str->length());
     DeleteArray(non_ascii);
@@ -876,6 +891,8 @@
 
 TEST(Iteration) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
 
   // Array of objects to scan haep for.
@@ -884,16 +901,16 @@
   int next_objs_index = 0;
 
   // Allocate a JS array to OLD_POINTER_SPACE and NEW_SPACE
-  objs[next_objs_index++] = FACTORY->NewJSArray(10);
-  objs[next_objs_index++] = FACTORY->NewJSArray(10,
+  objs[next_objs_index++] = factory->NewJSArray(10);
+  objs[next_objs_index++] = factory->NewJSArray(10,
                                                 FAST_HOLEY_ELEMENTS,
                                                 TENURED);
 
   // Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
   objs[next_objs_index++] =
-      FACTORY->NewStringFromAscii(CStrVector("abcdefghij"));
+      factory->NewStringFromAscii(CStrVector("abcdefghij"));
   objs[next_objs_index++] =
-      FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
+      factory->NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
 
   // Allocate a large string (for large object space).
   int large_size = Page::kMaxNonCodeHeapObjectSize + 1;
@@ -901,7 +918,7 @@
   for (int i = 0; i < large_size - 1; ++i) str[i] = 'a';
   str[large_size - 1] = '\0';
   objs[next_objs_index++] =
-      FACTORY->NewStringFromAscii(CStrVector(str), TENURED);
+      factory->NewStringFromAscii(CStrVector(str), TENURED);
   delete[] str;
 
   // Add a Map object to look for.
@@ -936,6 +953,8 @@
 TEST(Regression39128) {
   // Test case for crbug.com/39128.
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   // Increase the chance of 'bump-the-pointer' allocation in old space.
   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
@@ -952,7 +971,7 @@
   CHECK(object_ctor->has_initial_map());
   Handle<Map> object_map(object_ctor->initial_map());
   // Create a map with single inobject property.
-  Handle<Map> my_map = FACTORY->CopyMap(object_map, 1);
+  Handle<Map> my_map = factory->CopyMap(object_map, 1);
   int n_properties = my_map->inobject_properties();
   CHECK_GT(n_properties, 0);
 
@@ -1013,6 +1032,8 @@
   if (!FLAG_flush_code) return;
   i::FLAG_allow_natives_syntax = true;
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
   const char* source = "function foo() {"
                        "  var x = 42;"
@@ -1020,7 +1041,7 @@
                        "  var z = x + y;"
                        "};"
                        "foo()";
-  Handle<String> foo_name = FACTORY->InternalizeUtf8String("foo");
+  Handle<String> foo_name = factory->InternalizeUtf8String("foo");
 
   // This compile will add the code to the compilation cache.
   { v8::HandleScope scope(CcTest::isolate());
@@ -1060,6 +1081,8 @@
   if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
   i::FLAG_allow_natives_syntax = true;
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
   const char* source = "function foo() {"
                        "  var x = 42;"
@@ -1067,7 +1090,7 @@
                        "  var z = x + y;"
                        "};"
                        "foo()";
-  Handle<String> foo_name = FACTORY->InternalizeUtf8String("foo");
+  Handle<String> foo_name = factory->InternalizeUtf8String("foo");
 
   // This compile will add the code to the compilation cache.
   { v8::HandleScope scope(CcTest::isolate());
@@ -1126,6 +1149,8 @@
   if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
   i::FLAG_allow_natives_syntax = true;
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
   const char* source = "var foo = function() {"
                        "  var x = 42;"
@@ -1137,8 +1162,8 @@
                        "  var x = 23;"
                        "};"
                        "bar();";
-  Handle<String> foo_name = FACTORY->InternalizeUtf8String("foo");
-  Handle<String> bar_name = FACTORY->InternalizeUtf8String("bar");
+  Handle<String> foo_name = factory->InternalizeUtf8String("foo");
+  Handle<String> bar_name = factory->InternalizeUtf8String("bar");
 
   // Perfrom one initial GC to enable code flushing.
   HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
@@ -1193,6 +1218,7 @@
   i::FLAG_allow_natives_syntax = true;
   CcTest::InitializeVM();
   Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   Heap* heap = isolate->heap();
   v8::HandleScope scope(CcTest::isolate());
   const char* source = "function foo() {"
@@ -1201,7 +1227,7 @@
                        "  var z = x + y;"
                        "};"
                        "foo()";
-  Handle<String> foo_name = FACTORY->InternalizeUtf8String("foo");
+  Handle<String> foo_name = factory->InternalizeUtf8String("foo");
 
   // This compile will add the code to the compilation cache.
   { v8::HandleScope scope(CcTest::isolate());
@@ -1892,6 +1918,8 @@
 
 TEST(PrototypeTransitionClearing) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
 
   CompileRun(
@@ -1931,7 +1959,7 @@
   {
     AlwaysAllocateScope always_allocate;
     SimulateFullSpace(space);
-    prototype = FACTORY->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+    prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
   }
 
   // Add a prototype on an evacuation candidate and verify that transition
@@ -2155,6 +2183,30 @@
 }
 
 
+TEST(OptimizedPretenuringCallNew) {
+  i::FLAG_allow_natives_syntax = true;
+  i::FLAG_pretenuring_call_new = true;
+  CcTest::InitializeVM();
+  if (!i::V8::UseCrankshaft() || i::FLAG_always_opt) return;
+  if (i::FLAG_gc_global || i::FLAG_stress_compaction) return;
+  v8::HandleScope scope(CcTest::isolate());
+  HEAP->SetNewSpaceHighPromotionModeActive(true);
+
+  AlwaysAllocateScope always_allocate;
+  v8::Local<v8::Value> res = CompileRun(
+      "function g() { this.a = 0; }"
+      "function f() {"
+      "  return new g();"
+      "};"
+      "f(); f(); f();"
+      "%OptimizeFunctionOnNextCall(f);"
+      "f();");
+
+  Handle<JSObject> o =
+      v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
+  CHECK(HEAP->InOldPointerSpace(*o));
+}
+
 static int CountMapTransitions(Map* map) {
   return map->transitions()->number_of_transitions();
 }
@@ -2290,6 +2342,8 @@
   i::FLAG_crankshaft = false;
   i::FLAG_always_opt = false;
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
   static const int number_of_test_pages = 20;
 
@@ -2299,7 +2353,7 @@
   for (int i = 0; i < number_of_test_pages; i++) {
     AlwaysAllocateScope always_allocate;
     SimulateFullSpace(old_pointer_space);
-    FACTORY->NewFixedArray(1, TENURED);
+    factory->NewFixedArray(1, TENURED);
   }
   CHECK_EQ(number_of_test_pages + 1, old_pointer_space->CountTotalPages());
 
@@ -2329,6 +2383,8 @@
 
 TEST(Regress2237) {
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
   Handle<String> slice(HEAP->empty_string());
 
@@ -2336,7 +2392,7 @@
     // Generate a parent that lives in new-space.
     v8::HandleScope inner_scope(CcTest::isolate());
     const char* c = "This text is long enough to trigger sliced strings.";
-    Handle<String> s = FACTORY->NewStringFromAscii(CStrVector(c));
+    Handle<String> s = factory->NewStringFromAscii(CStrVector(c));
     CHECK(s->IsSeqOneByteString());
     CHECK(HEAP->InNewSpace(*s));
 
@@ -2344,7 +2400,7 @@
     // lives in old-space.
     SimulateFullSpace(HEAP->new_space());
     AlwaysAllocateScope always_allocate;
-    Handle<String> t = FACTORY->NewProperSubString(s, 5, 35);
+    Handle<String> t = factory->NewProperSubString(s, 5, 35);
     CHECK(t->IsSlicedString());
     CHECK(!HEAP->InNewSpace(*t));
     *slice.location() = *t.location();
@@ -2900,6 +2956,8 @@
   i::FLAG_allow_natives_syntax = true;
   i::FLAG_crankshaft = false;
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
   v8::HandleScope scope(CcTest::isolate());
 
   // Some flags turn Scavenge collections into Mark-sweep collections
@@ -2930,7 +2988,7 @@
   HEAP->CollectGarbage(NEW_SPACE);
 
   // Allocate the object.
-  Handle<FixedArray> array_data = FACTORY->NewFixedArray(2, NOT_TENURED);
+  Handle<FixedArray> array_data = factory->NewFixedArray(2, NOT_TENURED);
   array_data->set(0, Smi::FromInt(1));
   array_data->set(1, Smi::FromInt(2));
 
@@ -2938,7 +2996,7 @@
                        JSArray::kSize + AllocationSiteInfo::kSize +
                        kPointerSize);
 
-  Handle<JSArray> array = FACTORY->NewJSArrayWithElements(array_data,
+  Handle<JSArray> array = factory->NewJSArrayWithElements(array_data,
                                                           FAST_SMI_ELEMENTS,
                                                           NOT_TENURED);
 
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index c9482d6..45cb39c 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -235,24 +235,26 @@
 
 // TODO(1600): compaction of map space is temporary removed from GC.
 #if 0
-static Handle<Map> CreateMap() {
-  return FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+static Handle<Map> CreateMap(Isolate* isolate) {
+  return isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
 }
 
 
 TEST(MapCompact) {
   FLAG_max_map_space_pages = 16;
   CcTest::InitializeVM();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
 
   {
     v8::HandleScope sc;
     // keep allocating maps while pointers are still encodable and thus
     // mark compact is permitted.
-    Handle<JSObject> root = FACTORY->NewJSObjectFromMap(CreateMap());
+    Handle<JSObject> root = factory->NewJSObjectFromMap(CreateMap());
     do {
       Handle<Map> map = CreateMap();
       map->set_prototype(*root);
-      root = FACTORY->NewJSObjectFromMap(map);
+      root = factory->NewJSObjectFromMap(map);
     } while (HEAP->map_space()->MapPointersEncodable());
   }
   // Now, as we don't have any handles to just allocated maps, we should
diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc
index 9eb6f3c..0dd0265 100644
--- a/test/cctest/test-object-observe.cc
+++ b/test/cctest/test-object-observe.cc
@@ -418,7 +418,8 @@
       "Object.observe(obj, function(){});"
       "Object.getNotifier(obj);"
       "obj = null;");
-  i::Handle<i::JSObject> observation_state = FACTORY->observation_state();
+  i::Handle<i::JSObject> observation_state =
+      i::Isolate::Current()->factory()->observation_state();
   i::Handle<i::JSWeakMap> observerInfoMap =
       i::Handle<i::JSWeakMap>::cast(
           i::GetProperty(observation_state, "observerInfoMap"));
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index e81bf32..b580f4b 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -336,13 +336,15 @@
 
 TEST(Regress928) {
   v8::V8::Initialize();
+  i::Isolate* isolate = i::Isolate::Current();
+  i::Factory* factory = isolate->factory();
 
   // Preparsing didn't consider the catch clause of a try statement
   // as with-content, which made it assume that a function inside
   // the block could be lazily compiled, and an extra, unexpected,
   // entry was added to the data.
   int marker;
-  i::Isolate::Current()->stack_guard()->SetStackLimit(
+  isolate->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
 
   const char* program =
@@ -351,7 +353,7 @@
 
   v8::HandleScope handles(v8::Isolate::GetCurrent());
   i::Handle<i::String> source(
-      FACTORY->NewStringFromAscii(i::CStrVector(program)));
+      factory->NewStringFromAscii(i::CStrVector(program)));
   i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
   i::ScriptDataImpl* data = i::PreParserApi::PreParse(&stream);
   CHECK(!data->HasError());
@@ -434,17 +436,19 @@
                          unsigned end = 0) {
   if (end == 0) end = length;
   unsigned sub_length = end - start;
-  i::HandleScope test_scope(i::Isolate::Current());
+  i::Isolate* isolate = i::Isolate::Current();
+  i::Factory* factory = isolate->factory();
+  i::HandleScope test_scope(isolate);
   i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]);
   for (unsigned i = 0; i < length; i++) {
     uc16_buffer[i] = static_cast<i::uc16>(ascii_source[i]);
   }
   i::Vector<const char> ascii_vector(ascii_source, static_cast<int>(length));
   i::Handle<i::String> ascii_string(
-      FACTORY->NewStringFromAscii(ascii_vector));
+      factory->NewStringFromAscii(ascii_vector));
   TestExternalResource resource(*uc16_buffer, length);
   i::Handle<i::String> uc16_string(
-      FACTORY->NewExternalStringFromTwoByte(&resource));
+      factory->NewExternalStringFromTwoByte(&resource));
 
   i::ExternalTwoByteStringUtf16CharacterStream uc16_stream(
       i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
@@ -984,12 +988,15 @@
     { NULL, NULL, NULL, i::EVAL_SCOPE, i::CLASSIC_MODE }
   };
 
+  i::Isolate* isolate = i::Isolate::Current();
+  i::Factory* factory = isolate->factory();
+
   v8::HandleScope handles(v8::Isolate::GetCurrent());
   v8::Handle<v8::Context> context = v8::Context::New(v8::Isolate::GetCurrent());
   v8::Context::Scope context_scope(context);
 
   int marker;
-  i::Isolate::Current()->stack_guard()->SetStackLimit(
+  isolate->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
 
   for (int i = 0; source_data[i].outer_prefix; i++) {
@@ -1009,9 +1016,9 @@
 
     // Parse program source.
     i::Handle<i::String> source(
-        FACTORY->NewStringFromUtf8(i::CStrVector(program.start())));
+        factory->NewStringFromUtf8(i::CStrVector(program.start())));
     CHECK_EQ(source->length(), kProgramSize);
-    i::Handle<i::Script> script = FACTORY->NewScript(source);
+    i::Handle<i::Script> script = factory->NewScript(source);
     i::CompilationInfoWithZone info(script);
     i::Parser parser(&info);
     parser.set_allow_lazy(true);
@@ -1039,10 +1046,12 @@
 
 
 i::Handle<i::String> FormatMessage(i::ScriptDataImpl* data) {
+  i::Isolate* isolate = i::Isolate::Current();
+  i::Factory* factory = isolate->factory();
   i::Handle<i::String> format = v8::Utils::OpenHandle(
                                     *v8::String::New(data->BuildMessage()));
   i::Vector<const char*> args = data->BuildArgs();
-  i::Handle<i::JSArray> args_array = FACTORY->NewJSArray(args.length());
+  i::Handle<i::JSArray> args_array = factory->NewJSArray(args.length());
   for (int i = 0; i < args.length(); i++) {
     i::JSArray::SetElement(args_array,
                            i,
@@ -1050,7 +1059,7 @@
                            NONE,
                            i::kNonStrictMode);
   }
-  i::Handle<i::JSObject> builtins(i::Isolate::Current()->js_builtins_object());
+  i::Handle<i::JSObject> builtins(isolate->js_builtins_object());
   i::Handle<i::Object> format_fun =
       i::GetProperty(builtins, "FormatMessage");
   i::Handle<i::Object> arg_handles[] = { format, args_array };
@@ -1088,12 +1097,15 @@
   parser.set_allow_generators(checkParserFlag(flags, kAllowGenerators));
 
 void TestParserSyncWithFlags(i::Handle<i::String> source, unsigned flags) {
-  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
+  i::Isolate* isolate = i::Isolate::Current();
+  i::Factory* factory = isolate->factory();
+
+  uintptr_t stack_limit = isolate->stack_guard()->real_climit();
 
   // Preparse the data.
   i::CompleteParserRecorder log;
   {
-    i::Scanner scanner(i::Isolate::Current()->unicode_cache());
+    i::Scanner scanner(isolate->unicode_cache());
     i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
     v8::preparser::PreParser preparser(&scanner, &log, stack_limit);
     SET_PARSER_FLAGS(preparser, flags);
@@ -1107,7 +1119,7 @@
   // Parse the data
   i::FunctionLiteral* function;
   {
-    i::Handle<i::Script> script = FACTORY->NewScript(source);
+    i::Handle<i::Script> script = factory->NewScript(source);
     i::CompilationInfoWithZone info(script);
     i::Parser parser(&info);
     SET_PARSER_FLAGS(parser, flags);
@@ -1118,8 +1130,8 @@
   // Check that preparsing fails iff parsing fails.
   if (function == NULL) {
     // Extract exception from the parser.
-    CHECK(i::Isolate::Current()->has_pending_exception());
-    i::MaybeObject* maybe_object = i::Isolate::Current()->pending_exception();
+    CHECK(isolate->has_pending_exception());
+    i::MaybeObject* maybe_object = isolate->pending_exception();
     i::JSObject* exception = NULL;
     CHECK(maybe_object->To(&exception));
     i::Handle<i::JSObject> exception_handle(exception);
@@ -1243,12 +1255,15 @@
   // correct timeout for this and re-enable this test again.
   if (i::FLAG_stress_compaction) return;
 
+  i::Isolate* isolate = i::Isolate::Current();
+  i::Factory* factory = isolate->factory();
+
   v8::HandleScope handles(v8::Isolate::GetCurrent());
   v8::Handle<v8::Context> context = v8::Context::New(v8::Isolate::GetCurrent());
   v8::Context::Scope context_scope(context);
 
   int marker;
-  i::Isolate::Current()->stack_guard()->SetStackLimit(
+  isolate->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
 
   for (int i = 0; context_data[i][0] != NULL; ++i) {
@@ -1271,7 +1286,7 @@
             context_data[i][1]);
         CHECK(length == kProgramSize);
         i::Handle<i::String> source =
-            FACTORY->NewStringFromAscii(i::CStrVector(program.start()));
+            factory->NewStringFromAscii(i::CStrVector(program.start()));
         TestParserSync(source);
       }
     }
diff --git a/test/cctest/test-random.cc b/test/cctest/test-random.cc
index 430355c..0a8594c 100644
--- a/test/cctest/test-random.cc
+++ b/test/cctest/test-random.cc
@@ -81,8 +81,8 @@
 
   CompileRun("function f() { return Math.random(); }");
 
-  Object* string = FACTORY->InternalizeOneByteString(STATIC_ASCII_VECTOR("f"))->
-      ToObjectChecked();
+  Object* string = Isolate::Current()->factory()->InternalizeOneByteString(
+      STATIC_ASCII_VECTOR("f"))->ToObjectChecked();
   MaybeObject* fun_object =
       context->global_object()->GetProperty(String::cast(string));
   Handle<JSFunction> fun(JSFunction::cast(fun_object->ToObjectChecked()));
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index f87eb96..8973d54 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -286,14 +286,15 @@
 
 
 static void SanityCheck() {
+  Isolate* isolate = Isolate::Current();
   v8::HandleScope scope(v8::Isolate::GetCurrent());
 #ifdef VERIFY_HEAP
   HEAP->Verify();
 #endif
-  CHECK(Isolate::Current()->global_object()->IsJSObject());
-  CHECK(Isolate::Current()->native_context()->IsContext());
+  CHECK(isolate->global_object()->IsJSObject());
+  CHECK(isolate->native_context()->IsContext());
   CHECK(HEAP->string_table()->IsStringTable());
-  CHECK(!FACTORY->InternalizeOneByteString(
+  CHECK(!isolate->factory()->InternalizeOneByteString(
       STATIC_ASCII_VECTOR("Empty"))->IsFailure());
 }
 
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index e0ff32f..12d71e9 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -136,7 +136,9 @@
                                      RandomNumberGenerator* rng) {
   // A list of pointers that we don't have any interest in cleaning up.
   // If they are reachable from a root then leak detection won't complain.
-  Zone* zone = Isolate::Current()->runtime_zone();
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  Zone* zone = isolate->runtime_zone();
   for (int i = 0; i < bb_length; i++) {
     int len = rng->next(16);
     int slice_head_chars = 0;
@@ -168,7 +170,7 @@
           buf[j] = rng->next(0x10000);
         }
         building_blocks[i] =
-            FACTORY->NewStringFromTwoByte(Vector<const uc16>(buf, len));
+            factory->NewStringFromTwoByte(Vector<const uc16>(buf, len));
         for (int j = 0; j < len; j++) {
           CHECK_EQ(buf[j], building_blocks[i]->Get(j));
         }
@@ -180,7 +182,7 @@
           buf[j] = rng->next(0x80);
         }
         building_blocks[i] =
-            FACTORY->NewStringFromAscii(Vector<const char>(buf, len));
+            factory->NewStringFromAscii(Vector<const char>(buf, len));
         for (int j = 0; j < len; j++) {
           CHECK_EQ(buf[j], building_blocks[i]->Get(j));
         }
@@ -192,7 +194,7 @@
           buf[j] = rng->next(0x10000);
         }
         Resource* resource = new(zone) Resource(Vector<const uc16>(buf, len));
-        building_blocks[i] = FACTORY->NewExternalStringFromTwoByte(resource);
+        building_blocks[i] = factory->NewExternalStringFromTwoByte(resource);
         for (int j = 0; j < len; j++) {
           CHECK_EQ(buf[j], building_blocks[i]->Get(j));
         }
@@ -205,7 +207,7 @@
         }
         AsciiResource* resource =
             new(zone) AsciiResource(Vector<const char>(buf, len));
-        building_blocks[i] = FACTORY->NewExternalStringFromAscii(resource);
+        building_blocks[i] = factory->NewExternalStringFromAscii(resource);
         for (int j = 0; j < len; j++) {
           CHECK_EQ(buf[j], building_blocks[i]->Get(j));
         }
@@ -213,7 +215,7 @@
       }
     }
     for (int j = slice_depth; j > 0; j--) {
-      building_blocks[i] = FACTORY->NewSubString(
+      building_blocks[i] = factory->NewSubString(
           building_blocks[i],
           slice_head_chars,
           building_blocks[i]->length() - slice_tail_chars);
@@ -400,6 +402,7 @@
 
 static Handle<String> ConstructRandomString(ConsStringGenerationData* data,
                                             unsigned max_recursion) {
+  Factory* factory = Isolate::Current()->factory();
   // Compute termination characteristics.
   bool terminate = false;
   bool flat = data->rng_.next(data->empty_leaf_threshold_);
@@ -446,7 +449,7 @@
     left = ConstructRandomString(data, max_recursion - 1);
   }
   // Build the cons string.
-  Handle<String> root = FACTORY->NewConsString(left, right);
+  Handle<String> root = factory->NewConsString(left, right);
   CHECK(root->IsConsString() && !root->IsFlat());
   // Special work needed for flat string.
   if (flat) {
@@ -461,11 +464,12 @@
 static Handle<String> ConstructLeft(
     ConsStringGenerationData* data,
     int depth) {
-  Handle<String> answer = FACTORY->NewStringFromAscii(CStrVector(""));
+  Factory* factory = Isolate::Current()->factory();
+  Handle<String> answer = factory->NewStringFromAscii(CStrVector(""));
   data->stats_.leaves_++;
   for (int i = 0; i < depth; i++) {
     Handle<String> block = data->block(i);
-    Handle<String> next = FACTORY->NewConsString(answer, block);
+    Handle<String> next = factory->NewConsString(answer, block);
     if (next->IsConsString()) data->stats_.leaves_++;
     data->stats_.chars_ += block->length();
     answer = next;
@@ -478,11 +482,12 @@
 static Handle<String> ConstructRight(
     ConsStringGenerationData* data,
     int depth) {
-  Handle<String> answer = FACTORY->NewStringFromAscii(CStrVector(""));
+  Factory* factory = Isolate::Current()->factory();
+  Handle<String> answer = factory->NewStringFromAscii(CStrVector(""));
   data->stats_.leaves_++;
   for (int i = depth - 1; i >= 0; i--) {
     Handle<String> block = data->block(i);
-    Handle<String> next = FACTORY->NewConsString(block, answer);
+    Handle<String> next = factory->NewConsString(block, answer);
     if (next->IsConsString()) data->stats_.leaves_++;
     data->stats_.chars_ += block->length();
     answer = next;
@@ -496,6 +501,7 @@
     ConsStringGenerationData* data,
     int from,
     int to) {
+  Factory* factory = Isolate::Current()->factory();
   CHECK(to > from);
   if (to - from == 1) {
     data->stats_.chars_ += data->block(from)->length();
@@ -504,7 +510,7 @@
   if (to - from == 2) {
     data->stats_.chars_ += data->block(from)->length();
     data->stats_.chars_ += data->block(from+1)->length();
-    return FACTORY->NewConsString(data->block(from), data->block(from+1));
+    return factory->NewConsString(data->block(from), data->block(from+1));
   }
   Handle<String> part1 =
     ConstructBalancedHelper(data, from, from + ((to - from) / 2));
@@ -512,7 +518,7 @@
     ConstructBalancedHelper(data, from + ((to - from) / 2), to);
   if (part1->IsConsString()) data->stats_.left_traversals_++;
   if (part2->IsConsString()) data->stats_.right_traversals_++;
-  return FACTORY->NewConsString(part1, part2);
+  return factory->NewConsString(part1, part2);
 }
 
 
@@ -690,6 +696,7 @@
 
 static Handle<String> BuildEdgeCaseConsString(
     int test_case, ConsStringGenerationData* data) {
+  Factory* factory = Isolate::Current()->factory();
   data->Reset();
   switch (test_case) {
     case 0:
@@ -707,7 +714,7 @@
       data->stats_.chars_ += data->block(0)->length();
       data->stats_.chars_ += data->block(1)->length();
       data->stats_.leaves_ += 2;
-      return FACTORY->NewConsString(data->block(0), data->block(1));
+      return factory->NewConsString(data->block(0), data->block(1));
     case 6:
       // Simple flattened tree.
       data->stats_.chars_ += data->block(0)->length();
@@ -716,7 +723,7 @@
       data->stats_.empty_leaves_ += 1;
       {
         Handle<String> string =
-            FACTORY->NewConsString(data->block(0), data->block(1));
+            factory->NewConsString(data->block(0), data->block(1));
         FlattenString(string);
         return string;
       }
@@ -730,9 +737,9 @@
       data->stats_.left_traversals_ += 1;
       {
         Handle<String> left =
-            FACTORY->NewConsString(data->block(0), data->block(1));
+            factory->NewConsString(data->block(0), data->block(1));
         FlattenString(left);
-        return FACTORY->NewConsString(left, data->block(2));
+        return factory->NewConsString(left, data->block(2));
       }
     case 8:
       // Left node and right node flattened.
@@ -746,12 +753,12 @@
       data->stats_.right_traversals_ += 1;
       {
         Handle<String> left =
-            FACTORY->NewConsString(data->block(0), data->block(1));
+            factory->NewConsString(data->block(0), data->block(1));
         FlattenString(left);
         Handle<String> right =
-            FACTORY->NewConsString(data->block(2), data->block(2));
+            factory->NewConsString(data->block(2), data->block(2));
         FlattenString(right);
-        return FACTORY->NewConsString(left, right);
+        return factory->NewConsString(left, right);
       }
   }
   UNREACHABLE();
@@ -852,6 +859,7 @@
 TEST(DeepAscii) {
   printf("TestDeepAscii\n");
   CcTest::InitializeVM();
+  Factory* factory = Isolate::Current()->factory();
   v8::HandleScope scope(CcTest::isolate());
 
   char* foo = NewArray<char>(DEEP_ASCII_DEPTH);
@@ -859,12 +867,12 @@
     foo[i] = "foo "[i % 4];
   }
   Handle<String> string =
-      FACTORY->NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH));
-  Handle<String> foo_string = FACTORY->NewStringFromAscii(CStrVector("foo"));
+      factory->NewStringFromAscii(Vector<const char>(foo, DEEP_ASCII_DEPTH));
+  Handle<String> foo_string = factory->NewStringFromAscii(CStrVector("foo"));
   for (int i = 0; i < DEEP_ASCII_DEPTH; i += 10) {
-    string = FACTORY->NewConsString(string, foo_string);
+    string = factory->NewConsString(string, foo_string);
   }
-  Handle<String> flat_string = FACTORY->NewConsString(string, foo_string);
+  Handle<String> flat_string = factory->NewConsString(string, foo_string);
   FlattenString(flat_string);
 
   for (int i = 0; i < 500; i++) {
@@ -1059,13 +1067,14 @@
 TEST(SliceFromCons) {
   FLAG_string_slices = true;
   CcTest::InitializeVM();
+  Factory* factory = Isolate::Current()->factory();
   v8::HandleScope scope(CcTest::isolate());
   Handle<String> string =
-      FACTORY->NewStringFromAscii(CStrVector("parentparentparent"));
-  Handle<String> parent = FACTORY->NewConsString(string, string);
+      factory->NewStringFromAscii(CStrVector("parentparentparent"));
+  Handle<String> parent = factory->NewConsString(string, string);
   CHECK(parent->IsConsString());
   CHECK(!parent->IsFlat());
-  Handle<String> slice = FACTORY->NewSubString(parent, 1, 25);
+  Handle<String> slice = factory->NewSubString(parent, 1, 25);
   // After slicing, the original string becomes a flat cons.
   CHECK(parent->IsFlat());
   CHECK(slice->IsSlicedString());
@@ -1093,12 +1102,13 @@
 TEST(SliceFromExternal) {
   FLAG_string_slices = true;
   CcTest::InitializeVM();
+  Factory* factory = Isolate::Current()->factory();
   v8::HandleScope scope(CcTest::isolate());
   AsciiVectorResource resource(
       i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26));
-  Handle<String> string = FACTORY->NewExternalStringFromAscii(&resource);
+  Handle<String> string = factory->NewExternalStringFromAscii(&resource);
   CHECK(string->IsExternalString());
-  Handle<String> slice = FACTORY->NewSubString(string, 1, 25);
+  Handle<String> slice = factory->NewSubString(string, 1, 25);
   CHECK(slice->IsSlicedString());
   CHECK(string->IsExternalString());
   CHECK_EQ(SlicedString::cast(*slice)->parent(), *string);
@@ -1112,6 +1122,7 @@
   // actually creates a new string (it should not).
   FLAG_string_slices = true;
   CcTest::InitializeVM();
+  Factory* factory = Isolate::Current()->factory();
   v8::HandleScope scope(CcTest::isolate());
   v8::Local<v8::Value> result;
   Handle<String> string;
@@ -1126,7 +1137,7 @@
   string = v8::Utils::OpenHandle(v8::String::Cast(*result));
   CHECK(!string->IsSlicedString());
 
-  string = FACTORY->NewSubString(string, 0, 26);
+  string = factory->NewSubString(string, 0, 26);
   CHECK(!string->IsSlicedString());
   result = CompileRun(crosscheck);
   CHECK(result->IsString());
diff --git a/test/mjsunit/bugs/bug-618.js b/test/mjsunit/bugs/bug-618.js
deleted file mode 100644
index 0513f87..0000000
--- a/test/mjsunit/bugs/bug-618.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2010 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.
-
-// When this bug is corrected move to object-define-property and add
-// additional tests for configurable in the same manner as existing tests
-// there.
-
-function C() {
-  this.x = 23;
-}
-
-// If a setter is added to the prototype chain of a simple constructor setting
-// one of the properties assigned in the constructor then this setter is
-// ignored when constructing new objects from the constructor.
-
-// This only happens if the setter is added _after_ an instance has been
-// created.
-
-assertEquals(23, new C().x);
-C.prototype.__defineSetter__('x', function(value) { this.y = 23; });
-assertEquals(void 0, new C().x);
diff --git a/test/mjsunit/debug-evaluate-locals-optimized-double.js b/test/mjsunit/debug-evaluate-locals-optimized-double.js
index 8d91b97..6696ec5 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized-double.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized-double.js
@@ -185,6 +185,7 @@
   a0 = a0 + a0 / 100;
   b0 = b0 + b0 / 100;
   debugger;  // Breakpoint.
+  return a0 + b0;
 };
 
 function g3(i, x1, y1) {
@@ -193,7 +194,7 @@
   a1 = a1 + a1 / 100;
   b1 = b1 + b1 / 100;
   h(i - 1, a1, b1);
-  return a1+b1;
+  return a1 + b1;
 };
 
 function g2(i) {
@@ -202,6 +203,7 @@
   a2 = a2 + a2 / 100;
   b2 = b2 + b2 / 100;
   g3(i - 1, a2, b2);
+  return a2 + b2;
 };
 
 function g1(i, x3, y3, z3) {
@@ -210,6 +212,7 @@
   a3 = a3 + a3 / 100;
   b3 = b3 + b3 / 100;
   new g2(i - 1, a3, b3);
+  return a3 + b3;
 };
 
 function f(i, x4, y4) {
@@ -218,6 +221,7 @@
   a4 = a4 + a4 / 100;
   b4 = b4 + b4 / 100;
   g1(i - 1, a4, b4);
+  return a4 + b4;
 };
 
 // Test calling f normally and as a constructor.
diff --git a/test/mjsunit/debug-evaluate-locals-optimized.js b/test/mjsunit/debug-evaluate-locals-optimized.js
index f662912..d424001 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized.js
@@ -174,30 +174,35 @@
   var a0 = expected[i].locals.a0;
   var b0 = expected[i].locals.b0;
   debugger;  // Breakpoint.
+  return a0 + b0;
 }
 
 function g3(i, x1, y1) {
   var a1 = expected[i].locals.a1;
   var b1 = expected[i].locals.b1;
   h(i - 1, a1, b1);
+  return a1 + b1;
 }
 
 function g2(i) {
   var a2 = expected[i].locals.a2;
   var b2 = expected[i].locals.b2;
   g3(i - 1, a2, b2);
+  return a2 + b2;
 }
 
 function g1(i, x3, y3, z3) {
   var a3 = expected[i].locals.a3;
   var b3 = expected[i].locals.b3;
   new g2(i - 1, a3, b3);
+  return a3 + b3;
 }
 
 function f(i, x4, y4) {
   var a4 = expected[i].locals.a4;
   var b4 = expected[i].locals.b4;
   g1(i - 1, a4, b4);
+  return a4 + b4;
 }
 
 // Test calling f normally and as a constructor.
diff --git a/test/mjsunit/harmony/object-observe.js b/test/mjsunit/harmony/object-observe.js
index 4c75e63..0434ccd 100644
--- a/test/mjsunit/harmony/object-observe.js
+++ b/test/mjsunit/harmony/object-observe.js
@@ -957,15 +957,15 @@
 var arr3 = ['hello'];
 arr3[2] = 'goodbye';
 arr3.length = 6;
-var slow_arr = new Array(1000000000);
-slow_arr[500000000] = 'hello';
 Object.defineProperty(arr, '0', {configurable: false});
 Object.defineProperty(arr, '2', {get: function(){}});
 Object.defineProperty(arr2, '0', {get: function(){}, configurable: false});
 Object.observe(arr, observer.callback);
+Array.observe(arr, observer2.callback);
 Object.observe(arr2, observer.callback);
+Array.observe(arr2, observer2.callback);
 Object.observe(arr3, observer.callback);
-Object.observe(slow_arr, observer.callback);
+Array.observe(arr3, observer2.callback);
 arr.length = 2;
 arr.length = 0;
 arr.length = 10;
@@ -978,8 +978,8 @@
 arr3.length++;
 arr3.length /= 2;
 Object.defineProperty(arr3, 'length', {value: 5});
-Object.defineProperty(arr3, 'length', {value: 10, writable: false});
-slow_arr.length = 100;
+arr3[4] = 5;
+Object.defineProperty(arr3, 'length', {value: 1, writable: false});
 Object.deliverChangeRecords(observer.callback);
 observer.assertCallbackRecords([
   { object: arr, name: '3', type: 'deleted', oldValue: 'd' },
@@ -991,7 +991,7 @@
   { object: arr, name: 'length', type: 'reconfigured' },
   { object: arr2, name: '1', type: 'deleted', oldValue: 'beta' },
   { object: arr2, name: 'length', type: 'updated', oldValue: 2 },
-  { object: arr2, name: 'length', type: 'reconfigured', oldValue: 1 },
+  { object: arr2, name: 'length', type: 'reconfigured' },
   { object: arr3, name: '2', type: 'deleted', oldValue: 'goodbye' },
   { object: arr3, name: '0', type: 'deleted', oldValue: 'hello' },
   { object: arr3, name: 'length', type: 'updated', oldValue: 6 },
@@ -999,10 +999,60 @@
   { object: arr3, name: 'length', type: 'updated', oldValue: 1 },
   { object: arr3, name: 'length', type: 'updated', oldValue: 2 },
   { object: arr3, name: 'length', type: 'updated', oldValue: 1 },
-  { object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 },
+  { object: arr3, name: '4', type: 'new' },
+  { object: arr3, name: '4', type: 'deleted', oldValue: 5 },
+  // TODO(rafaelw): It breaks spec compliance to get two records here.
+  // When the TODO in v8natives.js::DefineArrayProperty is addressed
+  // which prevents DefineProperty from over-writing the magic length
+  // property, these will collapse into a single record.
+  { object: arr3, name: 'length', type: 'updated', oldValue: 5 },
+  { object: arr3, name: 'length', type: 'reconfigured' }
+]);
+Object.deliverChangeRecords(observer2.callback);
+observer2.assertCallbackRecords([
+  { object: arr, type: 'splice', index: 2, removed: [, 'd'], addedCount: 0 },
+  { object: arr, type: 'splice', index: 1, removed: ['b'], addedCount: 0 },
+  { object: arr, type: 'splice', index: 1, removed: [], addedCount: 9 },
+  { object: arr2, type: 'splice', index: 1, removed: ['beta'], addedCount: 0 },
+  { object: arr3, type: 'splice', index: 0, removed: ['hello',, 'goodbye',,,,], addedCount: 0 },
+  { object: arr3, type: 'splice', index: 0, removed: [], addedCount: 1 },
+  { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 1 },
+  { object: arr3, type: 'splice', index: 1, removed: [,], addedCount: 0 },
+  { object: arr3, type: 'splice', index: 1, removed: [], addedCount: 4 },
+  { object: arr3, name: '4', type: 'new' },
+  { object: arr3, type: 'splice', index: 1, removed: [,,,5], addedCount: 0 }
+]);
+
+
+// Updating length on large (slow) array
+reset();
+var slow_arr = new Array(1000000000);
+slow_arr[500000000] = 'hello';
+Object.observe(slow_arr, observer.callback);
+var spliceRecords;
+function slowSpliceCallback(records) {
+  spliceRecords = records;
+}
+Array.observe(slow_arr, slowSpliceCallback);
+slow_arr.length = 100;
+Object.deliverChangeRecords(observer.callback);
+observer.assertCallbackRecords([
   { object: slow_arr, name: '500000000', type: 'deleted', oldValue: 'hello' },
   { object: slow_arr, name: 'length', type: 'updated', oldValue: 1000000000 },
 ]);
+Object.deliverChangeRecords(slowSpliceCallback);
+assertEquals(spliceRecords.length, 1);
+// Have to custom assert this splice record because the removed array is huge.
+var splice = spliceRecords[0];
+assertSame(splice.object, slow_arr);
+assertEquals(splice.type, 'splice');
+assertEquals(splice.index, 100);
+assertEquals(splice.addedCount, 0);
+var array_keys = %GetArrayKeys(splice.removed, splice.removed.length);
+assertEquals(array_keys.length, 1);
+assertEquals(array_keys[0], 499999900);
+assertEquals(splice.removed[499999900], 'hello');
+assertEquals(splice.removed.length, 999999900);
 
 
 // Assignments in loops (checking different IC states).
@@ -1037,10 +1087,12 @@
 ]);
 
 
-// Adding elements past the end of an array should notify on length
+// Adding elements past the end of an array should notify on length for
+// Object.observe and emit "splices" for Array.observe.
 reset();
 var arr = [1, 2, 3];
 Object.observe(arr, observer.callback);
+Array.observe(arr, observer2.callback);
 arr[3] = 10;
 arr[100] = 20;
 Object.defineProperty(arr, '200', {value: 7});
@@ -1058,6 +1110,14 @@
   { object: arr, name: 'length', type: 'updated', oldValue: 201 },
   { object: arr, name: '50', type: 'new' },
 ]);
+Object.deliverChangeRecords(observer2.callback);
+observer2.assertCallbackRecords([
+  { object: arr, type: 'splice', index: 3, removed: [], addedCount: 1 },
+  { object: arr, type: 'splice', index: 4, removed: [], addedCount: 97 },
+  { object: arr, type: 'splice', index: 101, removed: [], addedCount: 100 },
+  { object: arr, type: 'splice', index: 201, removed: [], addedCount: 200 },
+  { object: arr, type: 'new', name: '50' },
+]);
 
 
 // Tests for array methods, first on arrays and then on plain objects
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
index 835d0e0..cbb2d21 100644
--- a/test/mjsunit/object-define-property.js
+++ b/test/mjsunit/object-define-property.js
@@ -1195,3 +1195,12 @@
 %OptimizeFunctionOnNextCall(Assign);
 Object.defineProperty(C.prototype, "blubb", {get: function() { return -42; }});
 Assign(new C);
+
+// Test that changes to the prototype of a simple constructor are not ignored,
+// even after creating initial instances.
+function C() {
+  this.x = 23;
+}
+assertEquals(23, new C().x);
+C.prototype.__defineSetter__('x', function(value) { this.y = 23; });
+assertEquals(void 0, new C().x);
diff --git a/test/mjsunit/bugs/618.js b/test/mjsunit/regress/regress-618.js
similarity index 100%
rename from test/mjsunit/bugs/618.js
rename to test/mjsunit/regress/regress-618.js
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 3db7101..9b90cba 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -322,6 +322,8 @@
         '../../src/heap-snapshot-generator.h',
         '../../src/heap.cc',
         '../../src/heap.h',
+        '../../src/hydrogen-environment-liveness.cc',
+        '../../src/hydrogen-environment-liveness.h',
         '../../src/hydrogen-instructions.cc',
         '../../src/hydrogen-instructions.h',
         '../../src/hydrogen.cc',