Version 3.23.12

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@18076 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/allocation-site-scopes.cc b/src/allocation-site-scopes.cc
index 8097045..31120b9 100644
--- a/src/allocation-site-scopes.cc
+++ b/src/allocation-site-scopes.cc
@@ -82,27 +82,4 @@
   }
 }
 
-
-Handle<AllocationSite> AllocationSiteUsageContext::EnterNewScope() {
-  if (top().is_null()) {
-    InitializeTraversal(top_site_);
-  } else {
-    // Advance current site
-    Object* nested_site = current()->nested_site();
-    // Something is wrong if we advance to the end of the list here.
-    ASSERT(nested_site->IsAllocationSite());
-    update_current_site(AllocationSite::cast(nested_site));
-  }
-  return Handle<AllocationSite>(*current(), isolate());
-}
-
-
-void AllocationSiteUsageContext::ExitScope(
-    Handle<AllocationSite> scope_site,
-    Handle<JSObject> object) {
-  // This assert ensures that we are pointing at the right sub-object in a
-  // recursive walk of a nested literal.
-  ASSERT(object.is_null() || *object == scope_site->transition_info());
-}
-
 } }  // namespace v8::internal
diff --git a/src/allocation-site-scopes.h b/src/allocation-site-scopes.h
index 1c3afdf..f106c5e 100644
--- a/src/allocation-site-scopes.h
+++ b/src/allocation-site-scopes.h
@@ -45,7 +45,6 @@
     isolate_ = isolate;
     activated_ = activated;
   };
-  virtual ~AllocationSiteContext() {}
 
   Handle<AllocationSite> top() { return top_; }
   Handle<AllocationSite> current() { return current_; }
@@ -53,19 +52,13 @@
   // If activated, then recursively create mementos
   bool activated() const { return activated_; }
 
-  // Returns the AllocationSite that matches this scope.
-  virtual Handle<AllocationSite> EnterNewScope() = 0;
-
-  // scope_site should be the handle returned by the matching EnterNewScope()
-  virtual void ExitScope(Handle<AllocationSite> scope_site,
-                         Handle<JSObject> object) = 0;
+  Isolate* isolate() { return isolate_; }
 
  protected:
   void update_current_site(AllocationSite* site) {
     *(current_.location()) = site;
   }
 
-  Isolate* isolate() { return isolate_; }
   void InitializeTraversal(Handle<AllocationSite> site) {
     top_ = site;
     current_ = Handle<AllocationSite>(*top_, isolate());
@@ -86,9 +79,8 @@
   explicit AllocationSiteCreationContext(Isolate* isolate)
       : AllocationSiteContext(isolate, true) { }
 
-  virtual Handle<AllocationSite> EnterNewScope() V8_OVERRIDE;
-  virtual void ExitScope(Handle<AllocationSite> site,
-                         Handle<JSObject> object) V8_OVERRIDE;
+  Handle<AllocationSite> EnterNewScope();
+  void ExitScope(Handle<AllocationSite> site, Handle<JSObject> object);
 };
 
 
@@ -101,9 +93,25 @@
       : AllocationSiteContext(isolate, activated),
         top_site_(site) { }
 
-  virtual Handle<AllocationSite> EnterNewScope() V8_OVERRIDE;
-  virtual void ExitScope(Handle<AllocationSite> site,
-                         Handle<JSObject> object) V8_OVERRIDE;
+  inline Handle<AllocationSite> EnterNewScope() {
+    if (top().is_null()) {
+      InitializeTraversal(top_site_);
+    } else {
+      // Advance current site
+      Object* nested_site = current()->nested_site();
+      // Something is wrong if we advance to the end of the list here.
+      ASSERT(nested_site->IsAllocationSite());
+      update_current_site(AllocationSite::cast(nested_site));
+    }
+    return Handle<AllocationSite>(*current(), isolate());
+  }
+
+  inline void ExitScope(Handle<AllocationSite> scope_site,
+                        Handle<JSObject> object) {
+    // This assert ensures that we are pointing at the right sub-object in a
+    // recursive walk of a nested literal.
+    ASSERT(object.is_null() || *object == scope_site->transition_info());
+  }
 
  private:
   Handle<AllocationSite> top_site_;
diff --git a/src/api.cc b/src/api.cc
index 18aca94..30a7ef8 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1078,32 +1078,42 @@
 }
 
 Local<FunctionTemplate> FunctionTemplate::New(
+    Isolate* isolate,
     FunctionCallback callback,
     v8::Handle<Value> data,
     v8::Handle<Signature> signature,
     int length) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
-  LOG_API(isolate, "FunctionTemplate::New");
-  ENTER_V8(isolate);
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::FunctionTemplate::New()");
+  LOG_API(i_isolate, "FunctionTemplate::New");
+  ENTER_V8(i_isolate);
   return FunctionTemplateNew(
-      isolate, callback, data, signature, length, false);
+      i_isolate, callback, data, signature, length, false);
 }
 
 
-Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
-      int argc, Handle<FunctionTemplate> argv[]) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
-  LOG_API(isolate, "Signature::New");
-  ENTER_V8(isolate);
+Local<FunctionTemplate> FunctionTemplate::New(
+    FunctionCallback callback,
+    v8::Handle<Value> data,
+    v8::Handle<Signature> signature,
+    int length) {
+  return New(Isolate::GetCurrent(), callback, data, signature, length);
+}
+
+Local<Signature> Signature::New(Isolate* isolate,
+                                Handle<FunctionTemplate> receiver, int argc,
+                                Handle<FunctionTemplate> argv[]) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::Signature::New()");
+  LOG_API(i_isolate, "Signature::New");
+  ENTER_V8(i_isolate);
   i::Handle<i::Struct> struct_obj =
-      isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
+      i_isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
   i::Handle<i::SignatureInfo> obj =
       i::Handle<i::SignatureInfo>::cast(struct_obj);
   if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
   if (argc > 0) {
-    i::Handle<i::FixedArray> args = isolate->factory()->NewFixedArray(argc);
+    i::Handle<i::FixedArray> args = i_isolate->factory()->NewFixedArray(argc);
     for (int i = 0; i < argc; i++) {
       if (!argv[i].IsEmpty())
         args->set(i, *Utils::OpenHandle(*argv[i]));
@@ -1114,6 +1124,20 @@
 }
 
 
+Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
+      int argc, Handle<FunctionTemplate> argv[]) {
+  return New(Isolate::GetCurrent(), receiver, argc, argv);
+}
+
+
+Local<AccessorSignature> AccessorSignature::New(
+      Isolate* isolate,
+      Handle<FunctionTemplate> receiver) {
+  return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
+}
+
+
+// While this is just a cast, it's lame not to use an Isolate parameter.
 Local<AccessorSignature> AccessorSignature::New(
       Handle<FunctionTemplate> receiver) {
   return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
@@ -1363,7 +1387,7 @@
   i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this);
   if (handle->instance_template()->IsUndefined()) {
     Local<ObjectTemplate> templ =
-        ObjectTemplate::New(ToApiHandle<FunctionTemplate>(handle));
+        ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
     handle->set_instance_template(*Utils::OpenHandle(*templ));
   }
   i::Handle<i::ObjectTemplateInfo> result(
@@ -1410,14 +1434,19 @@
 // --- O b j e c t T e m p l a t e ---
 
 
+Local<ObjectTemplate> ObjectTemplate::New(Isolate* isolate) {
+  return New(reinterpret_cast<i::Isolate*>(isolate), Local<FunctionTemplate>());
+}
+
+
 Local<ObjectTemplate> ObjectTemplate::New() {
-  return New(Local<FunctionTemplate>());
+  return New(i::Isolate::Current(), Local<FunctionTemplate>());
 }
 
 
 Local<ObjectTemplate> ObjectTemplate::New(
+      i::Isolate* isolate,
       v8::Handle<FunctionTemplate> constructor) {
-  i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
   LOG_API(isolate, "ObjectTemplate::New");
   ENTER_V8(isolate);
@@ -2285,10 +2314,15 @@
 }
 
 
+void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  ENTER_V8(i_isolate);
+  i_isolate->PrintCurrentStackTrace(out);
+}
+
+
 void Message::PrintCurrentStackTrace(FILE* out) {
-  i::Isolate* isolate = i::Isolate::Current();
-  ENTER_V8(isolate);
-  isolate->PrintCurrentStackTrace(out);
+  PrintCurrentStackTrace(Isolate::GetCurrent(), out);
 }
 
 
@@ -2319,13 +2353,21 @@
 }
 
 
+Local<StackTrace> StackTrace::CurrentStackTrace(
+    Isolate* isolate,
+    int frame_limit,
+    StackTraceOptions options) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  ENTER_V8(i_isolate);
+  i::Handle<i::JSArray> stackTrace =
+      i_isolate->CaptureCurrentStackTrace(frame_limit, options);
+  return Utils::StackTraceToLocal(stackTrace);
+}
+
+
 Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit,
     StackTraceOptions options) {
-  i::Isolate* isolate = i::Isolate::Current();
-  ENTER_V8(isolate);
-  i::Handle<i::JSArray> stackTrace =
-      isolate->CaptureCurrentStackTrace(frame_limit, options);
-  return Utils::StackTraceToLocal(stackTrace);
+  return CurrentStackTrace(Isolate::GetCurrent(), frame_limit, options);
 }
 
 
@@ -5646,18 +5688,25 @@
 
 
 Local<String> v8::String::NewExternal(
+      Isolate* isolate,
       v8::String::ExternalStringResource* resource) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
-  LOG_API(isolate, "String::NewExternal");
-  ENTER_V8(isolate);
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()");
+  LOG_API(i_isolate, "String::NewExternal");
+  ENTER_V8(i_isolate);
   CHECK(resource && resource->data());
-  i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
-  isolate->heap()->external_string_table()->AddString(*result);
+  i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource);
+  i_isolate->heap()->external_string_table()->AddString(*result);
   return Utils::ToLocal(result);
 }
 
 
+Local<String> v8::String::NewExternal(
+      v8::String::ExternalStringResource* resource) {
+  return NewExternal(Isolate::GetCurrent(), resource);
+}
+
+
 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
   i::Handle<i::String> obj = Utils::OpenHandle(this);
   i::Isolate* isolate = obj->GetIsolate();
@@ -5695,18 +5744,26 @@
 
 
 Local<String> v8::String::NewExternal(
+      Isolate* isolate,
       v8::String::ExternalAsciiStringResource* resource) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
-  LOG_API(isolate, "String::NewExternal");
-  ENTER_V8(isolate);
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::String::NewExternal()");
+  LOG_API(i_isolate, "String::NewExternal");
+  ENTER_V8(i_isolate);
   CHECK(resource && resource->data());
-  i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
-  isolate->heap()->external_string_table()->AddString(*result);
+  i::Handle<i::String> result =
+      NewExternalAsciiStringHandle(i_isolate, resource);
+  i_isolate->heap()->external_string_table()->AddString(*result);
   return Utils::ToLocal(result);
 }
 
 
+Local<String> v8::String::NewExternal(
+      v8::String::ExternalAsciiStringResource* resource) {
+  return NewExternal(Isolate::GetCurrent(), resource);
+}
+
+
 bool v8::String::MakeExternal(
     v8::String::ExternalAsciiStringResource* resource) {
   i::Handle<i::String> obj = Utils::OpenHandle(this);
@@ -5762,25 +5819,35 @@
 }
 
 
-Local<v8::Object> v8::Object::New() {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::Object::New()");
-  LOG_API(isolate, "Object::New");
-  ENTER_V8(isolate);
+Local<v8::Object> v8::Object::New(Isolate* isolate) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::Object::New()");
+  LOG_API(i_isolate, "Object::New");
+  ENTER_V8(i_isolate);
   i::Handle<i::JSObject> obj =
-      isolate->factory()->NewJSObject(isolate->object_function());
+      i_isolate->factory()->NewJSObject(i_isolate->object_function());
+  return Utils::ToLocal(obj);
+}
+
+
+Local<v8::Object> v8::Object::New() {
+  return New(Isolate::GetCurrent());
+}
+
+
+Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::NumberObject::New()");
+  LOG_API(i_isolate, "NumberObject::New");
+  ENTER_V8(i_isolate);
+  i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
+  i::Handle<i::Object> obj = i_isolate->factory()->ToObject(number);
   return Utils::ToLocal(obj);
 }
 
 
 Local<v8::Value> v8::NumberObject::New(double value) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::NumberObject::New()");
-  LOG_API(isolate, "NumberObject::New");
-  ENTER_V8(isolate);
-  i::Handle<i::Object> number = isolate->factory()->NewNumber(value);
-  i::Handle<i::Object> obj = isolate->factory()->ToObject(number);
-  return Utils::ToLocal(obj);
+  return New(Isolate::GetCurrent(), value);
 }
 
 
@@ -5858,23 +5925,28 @@
 }
 
 
-Local<v8::Value> v8::Date::New(double time) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::Date::New()");
-  LOG_API(isolate, "Date::New");
+Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::Date::New()");
+  LOG_API(i_isolate, "Date::New");
   if (std::isnan(time)) {
     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
     time = i::OS::nan_value();
   }
-  ENTER_V8(isolate);
-  EXCEPTION_PREAMBLE(isolate);
+  ENTER_V8(i_isolate);
+  EXCEPTION_PREAMBLE(i_isolate);
   i::Handle<i::Object> obj =
-      i::Execution::NewDate(isolate, time, &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
+      i::Execution::NewDate(i_isolate, time, &has_pending_exception);
+  EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::Value>());
   return Utils::ToLocal(obj);
 }
 
 
+Local<v8::Value> v8::Date::New(double time) {
+  return New(Isolate::GetCurrent(), time);
+}
+
+
 double v8::Date::ValueOf() const {
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "Date::NumberValue");
@@ -5884,22 +5956,22 @@
 }
 
 
-void v8::Date::DateTimeConfigurationChangeNotification() {
-  i::Isolate* isolate = i::Isolate::Current();
-  ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
+void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
              return);
-  LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
-  ENTER_V8(isolate);
+  LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
+  ENTER_V8(i_isolate);
 
-  isolate->date_cache()->ResetDateCache();
+  i_isolate->date_cache()->ResetDateCache();
 
-  i::HandleScope scope(isolate);
+  i::HandleScope scope(i_isolate);
   // Get the function ResetDateCache (defined in date.js).
   i::Handle<i::String> func_name_str =
-      isolate->factory()->InternalizeOneByteString(
+      i_isolate->factory()->InternalizeOneByteString(
           STATIC_ASCII_VECTOR("ResetDateCache"));
   i::MaybeObject* result =
-      isolate->js_builtins_object()->GetProperty(*func_name_str);
+      i_isolate->js_builtins_object()->GetProperty(*func_name_str);
   i::Object* object_func;
   if (!result->ToObject(&object_func)) {
     return;
@@ -5912,7 +5984,7 @@
     // Call ResetDateCache(0 but expect no exceptions:
     bool caught_exception = false;
     i::Execution::TryCall(func,
-                          isolate->js_builtins_object(),
+                          i_isolate->js_builtins_object(),
                           0,
                           NULL,
                           &caught_exception);
@@ -5920,6 +5992,11 @@
 }
 
 
+void v8::Date::DateTimeConfigurationChangeNotification() {
+  DateTimeConfigurationChangeNotification(Isolate::GetCurrent());
+}
+
+
 static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
   i::Isolate* isolate = i::Isolate::Current();
   uint8_t flags_buf[3];
@@ -5971,20 +6048,25 @@
 }
 
 
-Local<v8::Array> v8::Array::New(int length) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::Array::New()");
-  LOG_API(isolate, "Array::New");
-  ENTER_V8(isolate);
+Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::Array::New()");
+  LOG_API(i_isolate, "Array::New");
+  ENTER_V8(i_isolate);
   int real_length = length > 0 ? length : 0;
-  i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
+  i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
   i::Handle<i::Object> length_obj =
-      isolate->factory()->NewNumberFromInt(real_length);
+      i_isolate->factory()->NewNumberFromInt(real_length);
   obj->set_length(*length_obj);
   return Utils::ToLocal(obj);
 }
 
 
+Local<v8::Array> v8::Array::New(int length) {
+  return New(Isolate::GetCurrent(), length);
+}
+
+
 uint32_t v8::Array::Length() const {
   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
   i::Object* length = obj->length();
@@ -6068,27 +6150,38 @@
 }
 
 
-Local<ArrayBuffer> v8::ArrayBuffer::New(size_t byte_length) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::ArrayBuffer::New(size_t)");
-  LOG_API(isolate, "v8::ArrayBuffer::New(size_t)");
-  ENTER_V8(isolate);
+Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(size_t)");
+  LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
+  ENTER_V8(i_isolate);
   i::Handle<i::JSArrayBuffer> obj =
-      isolate->factory()->NewJSArrayBuffer();
-  i::Runtime::SetupArrayBufferAllocatingData(isolate, obj, byte_length);
+      i_isolate->factory()->NewJSArrayBuffer();
+  i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length);
+  return Utils::ToLocal(obj);
+}
+
+
+Local<ArrayBuffer> v8::ArrayBuffer::New(size_t byte_length) {
+  return New(Isolate::GetCurrent(), byte_length);
+}
+
+
+Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
+                                        size_t byte_length) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  EnsureInitializedForIsolate(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
+  LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
+  ENTER_V8(i_isolate);
+  i::Handle<i::JSArrayBuffer> obj =
+      i_isolate->factory()->NewJSArrayBuffer();
+  i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
   return Utils::ToLocal(obj);
 }
 
 
 Local<ArrayBuffer> v8::ArrayBuffer::New(void* data, size_t byte_length) {
-  i::Isolate* isolate = i::Isolate::Current();
-  EnsureInitializedForIsolate(isolate, "v8::ArrayBuffer::New(void*, size_t)");
-  LOG_API(isolate, "v8::ArrayBuffer::New(void*, size_t)");
-  ENTER_V8(isolate);
-  i::Handle<i::JSArrayBuffer> obj =
-      isolate->factory()->NewJSArrayBuffer();
-  i::Runtime::SetupArrayBuffer(isolate, obj, true, data, byte_length);
-  return Utils::ToLocal(obj);
+  return New(Isolate::GetCurrent(), data, byte_length);
 }
 
 
@@ -6280,18 +6373,28 @@
 Local<Integer> v8::Integer::New(int32_t value) {
   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   EnsureInitializedForIsolate(isolate, "v8::Integer::New()");
-  return v8::Integer::New(value, reinterpret_cast<Isolate*>(isolate));
+  return v8::Integer::New(reinterpret_cast<Isolate*>(isolate), value);
 }
 
 
 Local<Integer> Integer::NewFromUnsigned(uint32_t value) {
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Integer::NewFromUnsigned()");
-  return Integer::NewFromUnsigned(value, reinterpret_cast<Isolate*>(isolate));
+  return Integer::NewFromUnsigned(reinterpret_cast<Isolate*>(isolate), value);
 }
 
 
 Local<Integer> v8::Integer::New(int32_t value, Isolate* isolate) {
+  return Integer::New(isolate, value);
+}
+
+
+Local<Integer> v8::Integer::NewFromUnsigned(uint32_t value, Isolate* isolate) {
+  return Integer::NewFromUnsigned(isolate, value);
+}
+
+
+Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
   ASSERT(internal_isolate->IsInitialized());
   if (i::Smi::IsValid(value)) {
@@ -6304,7 +6407,7 @@
 }
 
 
-Local<Integer> v8::Integer::NewFromUnsigned(uint32_t value, Isolate* isolate) {
+Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
   ASSERT(internal_isolate->IsInitialized());
   bool fits_into_int32_t = (value & (1 << 31)) == 0;
diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h
index 24c5cca..3399958 100644
--- a/src/arm/assembler-arm-inl.h
+++ b/src/arm/assembler-arm-inl.h
@@ -457,12 +457,6 @@
 }
 
 
-void Assembler::set_external_target_at(Address constant_pool_entry,
-                                       Address target) {
-  Memory::Address_at(constant_pool_entry) = target;
-}
-
-
 static Instr EncodeMovwImmediate(uint32_t immediate) {
   ASSERT(immediate < 0x10000);
   return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 137dd73..afb0c62 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -803,11 +803,6 @@
   inline static void deserialization_set_special_target_at(
       Address constant_pool_entry, Address target);
 
-  // This sets the branch destination (which is in the constant pool on ARM).
-  // This is for calls and branches to runtime code.
-  inline static void set_external_target_at(Address constant_pool_entry,
-                                            Address target);
-
   // Here we are patching the address in the constant pool, not the actual call
   // instruction.  The address in the constant pool is the same size as a
   // pointer.
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 3473445..bfe6da0 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -77,7 +77,7 @@
   descriptor->register_param_count_ = 3;
   descriptor->register_params_ = registers;
   descriptor->deoptimization_handler_ =
-      Runtime::FunctionForId(Runtime::kCreateArrayLiteral)->entry;
+      Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry;
 }
 
 
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 4a39970..15bfba3 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1770,6 +1770,10 @@
   Comment cmnt(masm_, "[ ArrayLiteral");
 
   expr->BuildConstantElements(isolate());
+  int flags = expr->depth() == 1
+      ? ArrayLiteral::kShallowElements
+      : ArrayLiteral::kNoFlags;
+
   ZoneList<Expression*>* subexprs = expr->values();
   int length = subexprs->length();
   Handle<FixedArray> constant_elements = expr->constant_elements();
@@ -1795,8 +1799,9 @@
         isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2);
   } else if (expr->depth() > 1 || Serializer::enabled() ||
              length > FastCloneShallowArrayStub::kMaximumClonedLength) {
-    __ Push(r3, r2, r1);
-    __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
+    __ mov(r0, Operand(Smi::FromInt(flags)));
+    __ Push(r3, r2, r1, r0);
+    __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
   } else {
     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
            FLAG_smi_only_arrays);
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index eeffc16..71c9dda 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1667,6 +1667,15 @@
       result = AssignEnvironment(result);
     }
     return result;
+  } else if (instr->representation().IsExternal()) {
+    ASSERT(instr->left()->representation().IsExternal());
+    ASSERT(instr->right()->representation().IsInteger32());
+    ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
+    LOperand* left = UseRegisterAtStart(instr->left());
+    LOperand* right = UseOrConstantAtStart(instr->right());
+    LAddI* add = new(zone()) LAddI(left, right);
+    LInstruction* result = DefineAsRegister(add);
+    return result;
   } else if (instr->representation().IsDouble()) {
     if (instr->left()->IsMul()) {
       return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
@@ -2561,7 +2570,7 @@
   LInstruction* goto_instr = CheckElideControlInstruction(instr);
   if (goto_instr != NULL) return goto_instr;
 
-  return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value()));
+  return new(zone()) LTypeofIsAndBranch(UseRegister(instr->value()));
 }
 
 
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 4b05db1..6dadef0 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -5557,22 +5557,21 @@
   Register scratch = scratch0();
   if (type_name->Equals(heap()->number_string())) {
     __ JumpIfSmi(input, true_label);
-    __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset));
-    __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
-    __ cmp(input, Operand(ip));
+    __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+    __ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
     final_branch_condition = eq;
 
   } else if (type_name->Equals(heap()->string_string())) {
     __ JumpIfSmi(input, false_label);
-    __ CompareObjectType(input, input, scratch, FIRST_NONSTRING_TYPE);
+    __ CompareObjectType(input, scratch, no_reg, FIRST_NONSTRING_TYPE);
     __ b(ge, false_label);
-    __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
-    __ tst(ip, Operand(1 << Map::kIsUndetectable));
+    __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+    __ tst(scratch, Operand(1 << Map::kIsUndetectable));
     final_branch_condition = eq;
 
   } else if (type_name->Equals(heap()->symbol_string())) {
     __ JumpIfSmi(input, false_label);
-    __ CompareObjectType(input, input, scratch, SYMBOL_TYPE);
+    __ CompareObjectType(input, scratch, no_reg, SYMBOL_TYPE);
     final_branch_condition = eq;
 
   } else if (type_name->Equals(heap()->boolean_string())) {
@@ -5590,33 +5589,35 @@
     __ b(eq, true_label);
     __ JumpIfSmi(input, false_label);
     // Check for undetectable objects => true.
-    __ ldr(input, FieldMemOperand(input, HeapObject::kMapOffset));
-    __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
-    __ tst(ip, Operand(1 << Map::kIsUndetectable));
+    __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+    __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+    __ tst(scratch, Operand(1 << Map::kIsUndetectable));
     final_branch_condition = ne;
 
   } else if (type_name->Equals(heap()->function_string())) {
     STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
+    Register type_reg = scratch;
     __ JumpIfSmi(input, false_label);
-    __ CompareObjectType(input, scratch, input, JS_FUNCTION_TYPE);
+    __ CompareObjectType(input, scratch, type_reg, JS_FUNCTION_TYPE);
     __ b(eq, true_label);
-    __ cmp(input, Operand(JS_FUNCTION_PROXY_TYPE));
+    __ cmp(type_reg, Operand(JS_FUNCTION_PROXY_TYPE));
     final_branch_condition = eq;
 
   } else if (type_name->Equals(heap()->object_string())) {
+    Register map = scratch;
     __ JumpIfSmi(input, false_label);
     if (!FLAG_harmony_typeof) {
       __ CompareRoot(input, Heap::kNullValueRootIndex);
       __ b(eq, true_label);
     }
-    __ CompareObjectType(input, input, scratch,
-                         FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
-    __ b(lt, false_label);
-    __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
-    __ b(gt, false_label);
+    __ CheckObjectTypeRange(input,
+                            map,
+                            FIRST_NONCALLABLE_SPEC_OBJECT_TYPE,
+                            LAST_NONCALLABLE_SPEC_OBJECT_TYPE,
+                            false_label);
     // Check for undetectable objects => false.
-    __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
-    __ tst(ip, Operand(1 << Map::kIsUndetectable));
+    __ ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
+    __ tst(scratch, Operand(1 << Map::kIsUndetectable));
     final_branch_condition = eq;
 
   } else {
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 65962e7..8bb1cb1 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -2022,14 +2022,36 @@
                                        Register map,
                                        Register type_reg,
                                        InstanceType type) {
+  const Register temp = type_reg.is(no_reg) ? ip : type_reg;
+
   ldr(map, FieldMemOperand(object, HeapObject::kMapOffset));
-  CompareInstanceType(map, type_reg, type);
+  CompareInstanceType(map, temp, type);
+}
+
+
+void MacroAssembler::CheckObjectTypeRange(Register object,
+                                          Register map,
+                                          InstanceType min_type,
+                                          InstanceType max_type,
+                                          Label* false_label) {
+  STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
+  STATIC_ASSERT(LAST_TYPE < 256);
+  ldr(map, FieldMemOperand(object, HeapObject::kMapOffset));
+  ldrb(ip, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  sub(ip, ip, Operand(min_type));
+  cmp(ip, Operand(max_type - min_type));
+  b(hi, false_label);
 }
 
 
 void MacroAssembler::CompareInstanceType(Register map,
                                          Register type_reg,
                                          InstanceType type) {
+  // Registers map and type_reg can be ip. These two lines assert
+  // that ip can be used with the two instructions (the constants
+  // will never need ip).
+  STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
+  STATIC_ASSERT(LAST_TYPE < 256);
   ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
   cmp(type_reg, Operand(type));
 }
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 5e20eec..467a1ac 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -845,11 +845,21 @@
   // are the same register).  It leaves the heap object in the heap_object
   // register unless the heap_object register is the same register as one of the
   // other registers.
+  // Type_reg can be no_reg. In that case ip is used.
   void CompareObjectType(Register heap_object,
                          Register map,
                          Register type_reg,
                          InstanceType type);
 
+  // Compare object type for heap object. Branch to false_label if type
+  // is lower than min_type or greater than max_type.
+  // Load map into the register map.
+  void CheckObjectTypeRange(Register heap_object,
+                            Register map,
+                            InstanceType min_type,
+                            InstanceType max_type,
+                            Label* false_label);
+
   // Compare instance type in a map.  map contains a valid map object whose
   // object type should be compared with the given type.  This both
   // sets the flags and leaves the object type in the type_reg register.
diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h
index e392c5c..0af5162 100644
--- a/src/arm/simulator-arm.h
+++ b/src/arm/simulator-arm.h
@@ -269,7 +269,7 @@
 
   // Checks if the current instruction should be executed based on its
   // condition bits.
-  bool ConditionallyExecute(Instruction* instr);
+  inline bool ConditionallyExecute(Instruction* instr);
 
   // Helper functions to set the conditional flags in the architecture state.
   void SetNZFlags(int32_t val);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 9b2ba53..00ea079 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -798,17 +798,12 @@
     Register receiver,
     Register holder,
     Register name,
-    Handle<JSObject> holder_obj) {
+    Handle<JSObject> holder_obj,
+    IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-
-  ExternalReference ref =
-      ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
-                        masm->isolate());
-  __ mov(r0, Operand(StubCache::kInterceptorArgsLength));
-  __ mov(r1, Operand(ref));
-
-  CEntryStub stub(1);
-  __ CallStub(&stub);
+  __ CallExternalReference(
+      ExternalReference(IC_Utility(id), masm->isolate()),
+      StubCache::kInterceptorArgsLength);
 }
 
 
@@ -1113,11 +1108,11 @@
     FrameScope scope(masm, StackFrame::INTERNAL);
     // Save the name_ register across the call.
     __ push(name_);
-    PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder);
-    __ CallExternalReference(
-        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
-                          masm->isolate()),
-        StubCache::kInterceptorArgsLength);
+
+    CompileCallLoadPropertyWithInterceptor(
+        masm, receiver, holder, name_, interceptor_holder,
+        IC::kLoadPropertyWithInterceptorForCall);
+
     // Restore the name_ register.
     __ pop(name_);
     // Leave the internal frame.
@@ -1132,11 +1127,9 @@
     {
       FrameScope scope(masm, StackFrame::INTERNAL);
       __ Push(holder, name_);
-      CompileCallLoadPropertyWithInterceptor(masm,
-                                             receiver,
-                                             holder,
-                                             name_,
-                                             holder_obj);
+      CompileCallLoadPropertyWithInterceptor(
+          masm, receiver, holder, name_, holder_obj,
+          IC::kLoadPropertyWithInterceptorOnly);
       __ pop(name_);  // Restore the name.
       __ pop(receiver);  // Restore the holder.
     }
@@ -1503,11 +1496,10 @@
       // Invoke an interceptor.  Note: map checks from receiver to
       // interceptor's holder has been compiled before (see a caller
       // of this method.)
-      CompileCallLoadPropertyWithInterceptor(masm(),
-                                             receiver(),
-                                             holder_reg,
-                                             this->name(),
-                                             interceptor_holder);
+      CompileCallLoadPropertyWithInterceptor(
+          masm(), receiver(), holder_reg, this->name(), interceptor_holder,
+          IC::kLoadPropertyWithInterceptorOnly);
+
       // Check if interceptor provided a value for property.  If it's
       // the case, return immediately.
       Label interceptor_failed;
diff --git a/src/ast.h b/src/ast.h
index e3fc053..4158907 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1604,6 +1604,12 @@
   // Populate the constant elements fixed array.
   void BuildConstantElements(Isolate* isolate);
 
+  enum Flags {
+    kNoFlags = 0,
+    kShallowElements = 1,
+    kDisableMementos = 1 << 1
+  };
+
  protected:
   ArrayLiteral(Isolate* isolate,
                ZoneList<Expression*>* values,
diff --git a/src/debug.cc b/src/debug.cc
index f3c3764..23495c8 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -3137,7 +3137,7 @@
     v8::Local<v8::Function> fun =
         v8::Local<v8::Function>::Cast(api_exec_state->Get(fun_name));
 
-    v8::Handle<v8::Boolean> running = v8::Boolean::New(auto_continue);
+    v8::Handle<v8::Boolean> running = v8::Boolean::New(isolate, auto_continue);
     static const int kArgc = 1;
     v8::Handle<Value> argv[kArgc] = { running };
     cmd_processor = v8::Local<v8::Object>::Cast(
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index fec9ee5..483d1e3 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -1579,7 +1579,8 @@
   // Compute the function template for the native function.
   Handle<String> name = expr->name();
   v8::Handle<v8::FunctionTemplate> fun_template =
-      expr->extension()->GetNativeFunction(v8::Utils::ToLocal(name));
+      expr->extension()->GetNativeFunctionTemplate(
+          reinterpret_cast<v8::Isolate*>(isolate()), v8::Utils::ToLocal(name));
   ASSERT(!fun_template.IsEmpty());
 
   // Instantiate the function and create a shared function info from it.
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index e816471..5675c55 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1262,6 +1262,26 @@
 }
 
 
+Representation HAdd::RepresentationFromInputs() {
+  Representation left_rep = left()->representation();
+  if (left_rep.IsExternal()) {
+    return Representation::External();
+  }
+  return HArithmeticBinaryOperation::RepresentationFromInputs();
+}
+
+
+Representation HAdd::RequiredInputRepresentation(int index) {
+  if (index == 2) {
+    Representation left_rep = left()->representation();
+    if (left_rep.IsExternal()) {
+      return Representation::Integer32();
+    }
+  }
+  return HArithmeticBinaryOperation::RequiredInputRepresentation(index);
+}
+
+
 static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) {
   return arg1->representation().IsSpecialization() &&
     arg2->EqualsInteger32Constant(identity);
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index fba23fa..eac3c51 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -4732,8 +4732,9 @@
 
   // Add is only commutative if two integer values are added and not if two
   // tagged values are added (because it might be a String concatenation).
+  // We also do not commute (pointer + offset).
   virtual bool IsCommutative() const V8_OVERRIDE {
-    return !representation().IsTagged();
+    return !representation().IsTagged() && !representation().IsExternal();
   }
 
   virtual HValue* EnsureAndPropagateNotMinusZero(
@@ -4769,6 +4770,10 @@
     }
   }
 
+  virtual Representation RepresentationFromInputs() V8_OVERRIDE;
+
+  virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE;
+
   DECLARE_CONCRETE_INSTRUCTION(Add)
 
  protected:
@@ -6062,6 +6067,43 @@
   // Create an access for the payload of a Cell or JSGlobalPropertyCell.
   static HObjectAccess ForCellPayload(Isolate* isolate);
 
+  static HObjectAccess ForJSTypedArrayLength() {
+    return HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset);
+  }
+
+  static HObjectAccess ForJSArrayBufferBackingStore() {
+    return HObjectAccess::ForJSObjectOffset(
+        JSArrayBuffer::kBackingStoreOffset, Representation::External());
+  }
+
+  static HObjectAccess ForExternalArrayExternalPointer() {
+    return HObjectAccess::ForJSObjectOffset(
+        ExternalArray::kExternalPointerOffset, Representation::External());
+  }
+
+  static HObjectAccess ForJSArrayBufferViewWeakNext() {
+    return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kWeakNextOffset);
+  }
+
+  static HObjectAccess ForJSArrayBufferWeakFirstView() {
+    return HObjectAccess::ForJSObjectOffset(
+        JSArrayBuffer::kWeakFirstViewOffset);
+  }
+
+  static HObjectAccess ForJSArrayBufferViewBuffer() {
+    return HObjectAccess::ForJSObjectOffset(JSArrayBufferView::kBufferOffset);
+  }
+
+  static HObjectAccess ForJSArrayBufferViewByteOffset() {
+    return HObjectAccess::ForJSObjectOffset(
+        JSArrayBufferView::kByteOffsetOffset);
+  }
+
+  static HObjectAccess ForJSArrayBufferViewByteLength() {
+    return HObjectAccess::ForJSObjectOffset(
+        JSArrayBufferView::kByteLengthOffset);
+  }
+
   void PrintTo(StringStream* stream);
 
   inline bool Equals(HObjectAccess that) const {
@@ -6478,6 +6520,8 @@
       } else if (field_representation().IsDouble() ||
                  field_representation().IsSmi()) {
         return field_representation();
+      } else if (field_representation().IsExternal()) {
+        return Representation::External();
       }
     }
     return Representation::Tagged();
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 3e08b69..634acd7 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -58,6 +58,7 @@
 #include "hydrogen-uint32-analysis.h"
 #include "lithium-allocator.h"
 #include "parser.h"
+#include "runtime.h"
 #include "scopeinfo.h"
 #include "scopes.h"
 #include "stub-cache.h"
@@ -5107,10 +5108,15 @@
     // pass an empty fixed array to the runtime function instead.
     Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
     int literal_index = expr->literal_index();
+    int flags = expr->depth() == 1
+        ? ArrayLiteral::kShallowElements
+        : ArrayLiteral::kNoFlags;
+    flags |= ArrayLiteral::kDisableMementos;
 
     Add<HPushArgument>(Add<HConstant>(literals));
     Add<HPushArgument>(Add<HConstant>(literal_index));
     Add<HPushArgument>(Add<HConstant>(constants));
+    Add<HPushArgument>(Add<HConstant>(flags));
 
     // TODO(mvstanton): Consider a flag to turn off creation of any
     // AllocationMementos for this call: we are in crankshaft and should have
@@ -5118,7 +5124,7 @@
     Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
     literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
                                 Runtime::FunctionForId(function_id),
-                                3);
+                                4);
 
     // De-opt if elements kind changed from boilerplate_elements_kind.
     Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
@@ -8055,6 +8061,42 @@
 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
 
 
+template <class ViewClass>
+void HGraphBuilder::BuildArrayBufferViewInitialization(
+    HValue* obj,
+    HValue* buffer,
+    HValue* byte_offset,
+    HValue* byte_length) {
+
+  for (int offset = ViewClass::kSize;
+       offset < ViewClass::kSizeWithInternalFields;
+       offset += kPointerSize) {
+    Add<HStoreNamedField>(obj,
+        HObjectAccess::ForJSObjectOffset(offset),
+        Add<HConstant>(static_cast<int32_t>(0)));
+  }
+
+  Add<HStoreNamedField>(
+      obj,
+      HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
+  Add<HStoreNamedField>(
+      obj,
+      HObjectAccess::ForJSArrayBufferViewByteOffset(),
+      byte_offset);
+  Add<HStoreNamedField>(
+      obj,
+      HObjectAccess::ForJSArrayBufferViewByteLength(),
+      byte_length);
+
+  HObjectAccess weak_first_view_access =
+      HObjectAccess::ForJSArrayBufferWeakFirstView();
+  Add<HStoreNamedField>(obj,
+      HObjectAccess::ForJSArrayBufferViewWeakNext(),
+      Add<HLoadNamedField>(buffer, weak_first_view_access));
+  Add<HStoreNamedField>(buffer, weak_first_view_access, obj);
+}
+
+
 void HOptimizedGraphBuilder::VisitDataViewInitialize(
     CallRuntime* expr) {
   ZoneList<Expression*>* arguments = expr->arguments();
@@ -8073,31 +8115,127 @@
   CHECK_ALIVE(VisitForValue(arguments->at(3)));
   HValue* byte_length = Pop();
 
-  for (int offset = JSDataView::kSize;
-        offset < JSDataView::kSizeWithInternalFields;
-        offset += kPointerSize) {
-    Add<HStoreNamedField>(obj,
-        HObjectAccess::ForJSObjectOffset(offset),
-        Add<HConstant>(static_cast<int32_t>(0)));
+  BuildArrayBufferViewInitialization<JSDataView>(
+      obj, buffer, byte_offset, byte_length);
+}
+
+
+void HOptimizedGraphBuilder::VisitTypedArrayInitialize(
+    CallRuntime* expr) {
+  ZoneList<Expression*>* arguments = expr->arguments();
+
+  NoObservableSideEffectsScope scope(this);
+  static const int kObjectArg = 0;
+  static const int kArrayIdArg = 1;
+  static const int kBufferArg = 2;
+  static const int kByteOffsetArg = 3;
+  static const int kByteLengthArg = 4;
+  static const int kArgsLength = 5;
+  ASSERT(arguments->length() == kArgsLength);
+
+
+  CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg)));
+  HValue* obj = Pop();
+
+  ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral);
+  Handle<Object> value =
+      static_cast<Literal*>(arguments->at(kArrayIdArg))->value();
+  ASSERT(value->IsSmi());
+  int array_id = Smi::cast(*value)->value();
+
+  CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg)));
+  HValue* buffer = Pop();
+
+  HValue* byte_offset;
+  bool is_zero_byte_offset;
+
+  if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral
+      && Smi::FromInt(0) ==
+      *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) {
+    byte_offset = Add<HConstant>(static_cast<int32_t>(0));
+    is_zero_byte_offset = true;
+  } else {
+    CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg)));
+    byte_offset = Pop();
+    is_zero_byte_offset = false;
   }
 
-  Add<HStoreNamedField>(obj,
-      HObjectAccess::ForJSObjectOffset(JSDataView::kBufferOffset), buffer);
-  Add<HStoreNamedField>(obj,
-      HObjectAccess::ForJSObjectOffset(JSDataView::kByteOffsetOffset),
-      byte_offset);
-  Add<HStoreNamedField>(obj,
-      HObjectAccess::ForJSObjectOffset(JSDataView::kByteLengthOffset),
-      byte_length);
+  CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg)));
+  HValue* byte_length = Pop();
 
-  Add<HStoreNamedField>(obj,
-      HObjectAccess::ForJSObjectOffset(JSDataView::kWeakNextOffset),
-      Add<HLoadNamedField>(buffer,
-          HObjectAccess::ForJSObjectOffset(
-            JSArrayBuffer::kWeakFirstViewOffset)));
-  Add<HStoreNamedField>(buffer,
-      HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset),
-      obj);
+  IfBuilder byte_offset_smi(this);
+
+  if (!is_zero_byte_offset) {
+    byte_offset_smi.If<HIsSmiAndBranch>(byte_offset);
+    byte_offset_smi.Then();
+  }
+
+  { //  byte_offset is Smi.
+    BuildArrayBufferViewInitialization<JSTypedArray>(
+        obj, buffer, byte_offset, byte_length);
+
+    ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
+    size_t element_size = 1;  // Bogus initialization.
+    Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size);
+
+    HInstruction* length = AddUncasted<HDiv>(byte_length,
+        Add<HConstant>(static_cast<int32_t>(element_size)));
+
+    Add<HStoreNamedField>(obj,
+        HObjectAccess::ForJSTypedArrayLength(),
+        length);
+
+    HValue* elements =
+        Add<HAllocate>(
+            Add<HConstant>(ExternalArray::kAlignedSize),
+            HType::JSArray(),
+            NOT_TENURED,
+            static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type));
+
+    Handle<Map> external_array_map(
+        isolate()->heap()->MapForExternalArrayType(array_type));
+    Add<HStoreNamedField>(elements,
+        HObjectAccess::ForMap(),
+        Add<HConstant>(external_array_map));
+
+    HValue* backing_store = Add<HLoadNamedField>(
+        buffer, HObjectAccess::ForJSArrayBufferBackingStore());
+
+    HValue* typed_array_start;
+    if (is_zero_byte_offset) {
+      typed_array_start = backing_store;
+    } else {
+      HInstruction* external_pointer =
+          AddUncasted<HAdd>(backing_store, byte_offset);
+      // Arguments are checked prior to call to TypedArrayInitialize,
+      // including byte_offset.
+      external_pointer->ClearFlag(HValue::kCanOverflow);
+      typed_array_start = external_pointer;
+    }
+
+    Add<HStoreNamedField>(elements,
+        HObjectAccess::ForExternalArrayExternalPointer(),
+        typed_array_start);
+    Add<HStoreNamedField>(elements,
+        HObjectAccess::ForFixedArrayLength(),
+        length);
+    Add<HStoreNamedField>(
+        obj, HObjectAccess::ForElementsPointer(), elements);
+  }
+
+  if (!is_zero_byte_offset) {
+    byte_offset_smi.Else();
+    { //  byte_offset is not Smi.
+      Push(Add<HPushArgument>(obj));
+      VisitArgument(arguments->at(kArrayIdArg));
+      Push(Add<HPushArgument>(buffer));
+      Push(Add<HPushArgument>(byte_offset));
+      Push(Add<HPushArgument>(byte_length));
+      Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength);
+      Drop(kArgsLength);
+    }
+  }
+  byte_offset_smi.End();
 }
 
 
@@ -8116,6 +8254,16 @@
       return VisitDataViewInitialize(expr);
   }
 
+  if (function->function_id == Runtime::kTypedArrayInitialize) {
+    return VisitTypedArrayInitialize(expr);
+  }
+
+  if (function->function_id == Runtime::kMaxSmi) {
+    ASSERT(expr->arguments()->length() == 0);
+    HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue));
+    return ast_context()->ReturnInstruction(max_smi, expr->id());
+  }
+
   if (function->intrinsic_type == Runtime::INLINE) {
     ASSERT(expr->name()->length() > 0);
     ASSERT(expr->name()->Get(0) == '_');
@@ -9175,7 +9323,7 @@
 
 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
     Handle<JSObject> boilerplate_object,
-    AllocationSiteContext* site_context) {
+    AllocationSiteUsageContext* site_context) {
   NoObservableSideEffectsScope no_effects(this);
   InstanceType instance_type = boilerplate_object->map()->instance_type();
   ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
@@ -9268,7 +9416,7 @@
 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
     Handle<JSObject> boilerplate_object,
     HInstruction* object,
-    AllocationSiteContext* site_context) {
+    AllocationSiteUsageContext* site_context) {
   Handle<DescriptorArray> descriptors(
       boilerplate_object->map()->instance_descriptors());
   int limit = boilerplate_object->map()->NumberOfOwnDescriptors();
@@ -9340,7 +9488,7 @@
     Handle<JSObject> boilerplate_object,
     Handle<FixedArrayBase> elements,
     HValue* object_elements,
-    AllocationSiteContext* site_context) {
+    AllocationSiteUsageContext* site_context) {
   ElementsKind kind = boilerplate_object->map()->elements_kind();
   int elements_length = elements->length();
   HValue* object_elements_length = Add<HConstant>(elements_length);
@@ -9381,7 +9529,7 @@
     Handle<FixedArrayBase> elements,
     ElementsKind kind,
     HValue* object_elements,
-    AllocationSiteContext* site_context) {
+    AllocationSiteUsageContext* site_context) {
   HInstruction* boilerplate_elements = Add<HConstant>(elements);
   int elements_length = elements->length();
   Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
diff --git a/src/hydrogen.h b/src/hydrogen.h
index e0c5066..bd42896 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1736,6 +1736,12 @@
     position_ = position;
   }
 
+  template <typename ViewClass>
+  void BuildArrayBufferViewInitialization(HValue* obj,
+                                          HValue* buffer,
+                                          HValue* byte_offset,
+                                          HValue* byte_length);
+
  private:
   HGraphBuilder();
 
@@ -2195,6 +2201,8 @@
                                        SmallMapList* types,
                                        Handle<String> name);
 
+  void VisitTypedArrayInitialize(CallRuntime* expr);
+
   bool IsCallNewArrayInlineable(CallNew* expr);
   void BuildInlinedCallNewArray(CallNew* expr);
 
@@ -2403,7 +2411,7 @@
   HInstruction* BuildThisFunction();
 
   HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
-                                 AllocationSiteContext* site_context);
+                                 AllocationSiteUsageContext* site_context);
 
   void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
                              HInstruction* object);
@@ -2414,12 +2422,12 @@
 
   void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
                                    HInstruction* object,
-                                   AllocationSiteContext* site_context);
+                                   AllocationSiteUsageContext* site_context);
 
   void BuildEmitElements(Handle<JSObject> boilerplate_object,
                          Handle<FixedArrayBase> elements,
                          HValue* object_elements,
-                         AllocationSiteContext* site_context);
+                         AllocationSiteUsageContext* site_context);
 
   void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
                                  ElementsKind kind,
@@ -2428,7 +2436,7 @@
   void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
                            ElementsKind kind,
                            HValue* object_elements,
-                           AllocationSiteContext* site_context);
+                           AllocationSiteUsageContext* site_context);
 
   void AddCheckPrototypeMaps(Handle<JSObject> holder,
                              Handle<Map> receiver_map);
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index ed7b71f..6ed0bc6 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -638,13 +638,6 @@
     set_target_address_at(instruction_payload, target);
   }
 
-  // This sets the branch destination (which is in the instruction on x86).
-  // This is for calls and branches to runtime code.
-  inline static void set_external_target_at(Address instruction_payload,
-                                            Address target) {
-    set_target_address_at(instruction_payload, target);
-  }
-
   static const int kSpecialTargetSize = kPointerSize;
 
   // Distance between the address of the code target in the call instruction
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index f06cc5b..715feca 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -82,7 +82,7 @@
   descriptor->register_param_count_ = 3;
   descriptor->register_params_ = registers;
   descriptor->deoptimization_handler_ =
-      Runtime::FunctionForId(Runtime::kCreateArrayLiteral)->entry;
+      Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry;
 }
 
 
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index e067c90..909294e 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1705,6 +1705,10 @@
   Comment cmnt(masm_, "[ ArrayLiteral");
 
   expr->BuildConstantElements(isolate());
+  int flags = expr->depth() == 1
+      ? ArrayLiteral::kShallowElements
+      : ArrayLiteral::kNoFlags;
+
   ZoneList<Expression*>* subexprs = expr->values();
   int length = subexprs->length();
   Handle<FixedArray> constant_elements = expr->constant_elements();
@@ -1737,7 +1741,8 @@
     __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
     __ push(Immediate(Smi::FromInt(expr->literal_index())));
     __ push(Immediate(constant_elements));
-    __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
+    __ push(Immediate(Smi::FromInt(flags)));
+    __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
   } else {
     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
            FLAG_smi_only_arrays);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 5343773..921b5aa 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1653,6 +1653,21 @@
     return result;
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::ADD, instr);
+  } else if (instr->representation().IsExternal()) {
+    ASSERT(instr->left()->representation().IsExternal());
+    ASSERT(instr->right()->representation().IsInteger32());
+    ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
+    bool use_lea = LAddI::UseLea(instr);
+    LOperand* left = UseRegisterAtStart(instr->left());
+    HValue* right_candidate = instr->right();
+    LOperand* right = use_lea
+        ? UseRegisterOrConstantAtStart(right_candidate)
+        : UseOrConstantAtStart(right_candidate);
+    LAddI* add = new(zone()) LAddI(left, right);
+    LInstruction* result = use_lea
+        ? DefineAsRegister(add)
+        : DefineSameAsFirst(add);
+    return result;
   } else {
     return DoArithmeticT(Token::ADD, instr);
   }
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index d26210d..1c98c98 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -405,11 +405,11 @@
     Register receiver,
     Register holder,
     Register name,
-    Handle<JSObject> holder_obj) {
+    Handle<JSObject> holder_obj,
+    IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
   __ CallExternalReference(
-      ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
-                        masm->isolate()),
+      ExternalReference(IC_Utility(id), masm->isolate()),
       StubCache::kInterceptorArgsLength);
 }
 
@@ -797,12 +797,9 @@
     // Save the name_ register across the call.
     __ push(name_);
 
-    PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder);
-
-    __ CallExternalReference(
-        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
-                          masm->isolate()),
-        StubCache::kInterceptorArgsLength);
+    CompileCallLoadPropertyWithInterceptor(
+        masm, receiver, holder, name_, interceptor_holder,
+        IC::kLoadPropertyWithInterceptorForCall);
 
     // Restore the name_ register.
     __ pop(name_);
@@ -820,11 +817,9 @@
       __ push(holder);  // Save the holder.
       __ push(name_);  // Save the name.
 
-      CompileCallLoadPropertyWithInterceptor(masm,
-                                             receiver,
-                                             holder,
-                                             name_,
-                                             holder_obj);
+      CompileCallLoadPropertyWithInterceptor(
+          masm, receiver, holder, name_, holder_obj,
+          IC::kLoadPropertyWithInterceptorOnly);
 
       __ pop(name_);  // Restore the name.
       __ pop(receiver);  // Restore the holder.
@@ -1553,11 +1548,9 @@
       // Invoke an interceptor.  Note: map checks from receiver to
       // interceptor's holder has been compiled before (see a caller
       // of this method.)
-      CompileCallLoadPropertyWithInterceptor(masm(),
-                                             receiver(),
-                                             holder_reg,
-                                             this->name(),
-                                             interceptor_holder);
+      CompileCallLoadPropertyWithInterceptor(
+          masm(), receiver(), holder_reg, this->name(), interceptor_holder,
+          IC::kLoadPropertyWithInterceptorOnly);
 
       // Check if interceptor provided a value for property.  If it's
       // the case, return immediately.
diff --git a/src/math.js b/src/math.js
index fb7d306..5cbe94a 100644
--- a/src/math.js
+++ b/src/math.js
@@ -74,7 +74,7 @@
 
 // ECMA 262 - 15.8.2.6
 function MathCeil(x) {
-  return %Math_ceil(TO_NUMBER_INLINE(x));
+  return -MathFloor(-x);
 }
 
 // ECMA 262 - 15.8.2.7
@@ -348,6 +348,8 @@
     "imul", MathImul
   ));
 
+  %SetInlineBuiltinFlag(MathCeil);
+  %SetInlineBuiltinFlag(MathRandom);
   %SetInlineBuiltinFlag(MathSin);
   %SetInlineBuiltinFlag(MathCos);
   %SetInlineBuiltinFlag(MathTan);
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index 49cce62..d9ef46c 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -537,13 +537,6 @@
         target);
   }
 
-  // This sets the branch destination.
-  // This is for calls and branches to runtime code.
-  inline static void set_external_target_at(Address instruction_payload,
-                                            Address target) {
-    set_target_address_at(instruction_payload, target);
-  }
-
   // Size of an instruction.
   static const int kInstrSize = sizeof(Instr);
 
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 47afeb4..0c5e35c 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -78,7 +78,7 @@
   descriptor->register_param_count_ = 3;
   descriptor->register_params_ = registers;
   descriptor->deoptimization_handler_ =
-      Runtime::FunctionForId(Runtime::kCreateArrayLiteral)->entry;
+      Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry;
 }
 
 
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 486eb9d..8b16e6c 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -1780,6 +1780,10 @@
   Comment cmnt(masm_, "[ ArrayLiteral");
 
   expr->BuildConstantElements(isolate());
+  int flags = expr->depth() == 1
+      ? ArrayLiteral::kShallowElements
+      : ArrayLiteral::kNoFlags;
+
   ZoneList<Expression*>* subexprs = expr->values();
   int length = subexprs->length();
 
@@ -1808,8 +1812,9 @@
         1, a1, a2);
   } else if (expr->depth() > 1 || Serializer::enabled() ||
              length > FastCloneShallowArrayStub::kMaximumClonedLength) {
-    __ Push(a3, a2, a1);
-    __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
+    __ li(a0, Operand(Smi::FromInt(flags)));
+    __ Push(a3, a2, a1, a0);
+    __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
   } else {
     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
            FLAG_smi_only_arrays);
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 34e5838..d26da4a 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -1587,6 +1587,15 @@
       result = AssignEnvironment(result);
     }
     return result;
+  } else if (instr->representation().IsExternal()) {
+    ASSERT(instr->left()->representation().IsExternal());
+    ASSERT(instr->right()->representation().IsInteger32());
+    ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
+    LOperand* left = UseRegisterAtStart(instr->left());
+    LOperand* right = UseOrConstantAtStart(instr->right());
+    LAddI* add = new(zone()) LAddI(left, right);
+    LInstruction* result = DefineAsRegister(add);
+    return result;
   } else if (instr->representation().IsDouble()) {
     if (kArchVariant == kMips32r2) {
       if (instr->left()->IsMul())
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index a477250..e743701 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -785,17 +785,12 @@
     Register receiver,
     Register holder,
     Register name,
-    Handle<JSObject> holder_obj) {
+    Handle<JSObject> holder_obj,
+    IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-
-  ExternalReference ref =
-      ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
-          masm->isolate());
-  __ PrepareCEntryArgs(StubCache::kInterceptorArgsLength);
-  __ PrepareCEntryFunction(ref);
-
-  CEntryStub stub(1);
-  __ CallStub(&stub);
+  __ CallExternalReference(
+      ExternalReference(IC_Utility(id), masm->isolate()),
+      StubCache::kInterceptorArgsLength);
 }
 
 
@@ -1101,13 +1096,10 @@
     // Save the name_ register across the call.
     __ push(name_);
 
-    PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder);
+    CompileCallLoadPropertyWithInterceptor(
+        masm, receiver, holder, name_, interceptor_holder,
+        IC::kLoadPropertyWithInterceptorForCall);
 
-    __ CallExternalReference(
-          ExternalReference(
-              IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
-              masm->isolate()),
-          StubCache::kInterceptorArgsLength);
     // Restore the name_ register.
     __ pop(name_);
     // Leave the internal frame.
@@ -1123,11 +1115,9 @@
       FrameScope scope(masm, StackFrame::INTERNAL);
 
       __ Push(holder, name_);
-      CompileCallLoadPropertyWithInterceptor(masm,
-                                             receiver,
-                                             holder,
-                                             name_,
-                                             holder_obj);
+      CompileCallLoadPropertyWithInterceptor(
+          masm, receiver, holder, name_, holder_obj,
+          IC::kLoadPropertyWithInterceptorOnly);
       __ pop(name_);  // Restore the name.
       __ pop(receiver);  // Restore the holder.
     }
@@ -1496,11 +1486,10 @@
       // Invoke an interceptor.  Note: map checks from receiver to
       // interceptor's holder has been compiled before (see a caller
       // of this method).
-      CompileCallLoadPropertyWithInterceptor(masm(),
-                                             receiver(),
-                                             holder_reg,
-                                             this->name(),
-                                             interceptor_holder);
+      CompileCallLoadPropertyWithInterceptor(
+          masm(), receiver(), holder_reg, this->name(), interceptor_holder,
+          IC::kLoadPropertyWithInterceptorOnly);
+
       // Check if interceptor provided a value for property.  If it's
       // the case, return immediately.
       Label interceptor_failed;
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 9f1b939..512f532 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -862,8 +862,13 @@
   shared()->name()->Print(out);
   PrintF(out, "\n - context = ");
   context()->ShortPrint(out);
-  PrintF(out, "\n - literals = ");
-  literals()->ShortPrint(out);
+  if (shared()->bound()) {
+    PrintF(out, "\n - bindings = ");
+    function_bindings()->ShortPrint(out);
+  } else {
+    PrintF(out, "\n - literals = ");
+    literals()->ShortPrint(out);
+  }
   PrintF(out, "\n - code = ");
   code()->ShortPrint(out);
   PrintF(out, "\n");
diff --git a/src/objects.cc b/src/objects.cc
index 2283581..6e25e62 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -5656,14 +5656,6 @@
 }
 
 
-Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
-                                Handle<AllocationSite> site) {
-  Isolate* isolate = object->GetIsolate();
-  CALL_HEAP_FUNCTION(isolate,
-                     isolate->heap()->CopyJSObject(*object, *site), JSObject);
-}
-
-
 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
   Isolate* isolate = object->GetIsolate();
   CALL_HEAP_FUNCTION(isolate,
@@ -5671,258 +5663,233 @@
 }
 
 
+template<class ContextObject>
 class JSObjectWalkVisitor {
  public:
-  explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) :
-      site_context_(site_context) {}
-  virtual ~JSObjectWalkVisitor() {}
+  JSObjectWalkVisitor(ContextObject* site_context, bool copying,
+                      JSObject::DeepCopyHints hints)
+    : site_context_(site_context),
+      copying_(copying),
+      hints_(hints) {}
 
-  Handle<JSObject> Visit(Handle<JSObject> object) {
-    return StructureWalk(object);
-  }
-
-  virtual bool is_copying() = 0;
-
- protected:
   Handle<JSObject> StructureWalk(Handle<JSObject> object);
 
-  // The returned handle will be used for the object in all subsequent usages.
-  // This allows VisitObject to make a copy of the object if desired.
-  virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0;
-  virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
-                                                  Handle<JSObject> value) = 0;
-
-  AllocationSiteContext* site_context() { return site_context_; }
-
- private:
-  AllocationSiteContext* site_context_;
-};
-
-
-class JSObjectCopyVisitor: public JSObjectWalkVisitor {
- public:
-  explicit JSObjectCopyVisitor(AllocationSiteContext* site_context)
-      : JSObjectWalkVisitor(site_context) {}
-
-  virtual bool is_copying() V8_OVERRIDE { return true; }
-
-  // The returned handle will be used for the object in all
-  // subsequent usages. This allows VisitObject to make a copy
-  // of the object if desired.
-  virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
-    // Only create a memento if
-    // 1) we have a JSArray, and
-    // 2) the elements kind is palatable
-    // 3) allow_mementos is true
-    Handle<JSObject> copy;
-    if (site_context()->activated() &&
-        AllocationSite::CanTrack(object->map()->instance_type()) &&
-        AllocationSite::GetMode(object->GetElementsKind()) ==
-        TRACK_ALLOCATION_SITE) {
-      copy = JSObject::Copy(object, site_context()->current());
-    } else {
-      copy = JSObject::Copy(object);
-    }
-
-    return copy;
-  }
-
-  virtual Handle<JSObject> VisitElementOrProperty(
-      Handle<JSObject> object,
-      Handle<JSObject> value) V8_OVERRIDE {
+ protected:
+  inline Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
+                                                 Handle<JSObject> value) {
     Handle<AllocationSite> current_site = site_context()->EnterNewScope();
     Handle<JSObject> copy_of_value = StructureWalk(value);
     site_context()->ExitScope(current_site, value);
     return copy_of_value;
   }
+
+  inline ContextObject* site_context() { return site_context_; }
+  inline Isolate* isolate() { return site_context()->isolate(); }
+
+  inline bool copying() const { return copying_; }
+
+ private:
+  ContextObject* site_context_;
+  const bool copying_;
+  const JSObject::DeepCopyHints hints_;
 };
 
 
-class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor {
- public:
-  explicit JSObjectCreateAllocationSitesVisitor(
-      AllocationSiteContext* site_context)
-      : JSObjectWalkVisitor(site_context) {}
+template <class ContextObject>
+Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
+    Handle<JSObject> object) {
+  Isolate* isolate = this->isolate();
+  bool copying = this->copying();
+  bool shallow = hints_ == JSObject::kObjectIsShallowArray;
 
-  virtual bool is_copying() V8_OVERRIDE { return false; }
+  if (!shallow) {
+    StackLimitCheck check(isolate);
 
-  // The returned handle will be used for the object in all
-  // subsequent usages. This allows VisitObject to make a copy
-  // of the object if desired.
-  virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
-    return object;
-  }
-
-  virtual Handle<JSObject> VisitElementOrProperty(
-      Handle<JSObject> object,
-      Handle<JSObject> value) V8_OVERRIDE {
-    Handle<AllocationSite> current_site = site_context()->EnterNewScope();
-    value = StructureWalk(value);
-    site_context()->ExitScope(current_site, value);
-    return value;
-  }
-};
-
-
-Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) {
-  bool copying = is_copying();
-  Isolate* isolate = object->GetIsolate();
-  StackLimitCheck check(isolate);
-  if (check.HasOverflowed()) {
-    isolate->StackOverflow();
-    return Handle<JSObject>::null();
+    if (check.HasOverflowed()) {
+      isolate->StackOverflow();
+      return Handle<JSObject>::null();
+    }
   }
 
   if (object->map()->is_deprecated()) {
     JSObject::MigrateInstance(object);
   }
 
-  Handle<JSObject> copy = VisitObject(object);
+  Handle<JSObject> copy;
+  if (copying) {
+    Handle<AllocationSite> site_to_pass;
+    if (site_context()->activated() &&
+        AllocationSite::CanTrack(object->map()->instance_type()) &&
+        AllocationSite::GetMode(object->GetElementsKind()) ==
+        TRACK_ALLOCATION_SITE) {
+      site_to_pass = site_context()->current();
+    }
+    CALL_AND_RETRY_OR_DIE(isolate,
+                          isolate->heap()->CopyJSObject(*object,
+                              site_to_pass.is_null() ? NULL : *site_to_pass),
+                          { copy = Handle<JSObject>(JSObject::cast(__object__),
+                                                    isolate);
+                            break;
+                          },
+                          return Handle<JSObject>());
+  } else {
+    copy = object;
+  }
+
   ASSERT(copying || copy.is_identical_to(object));
 
-  HandleScope scope(isolate);
-
-  // Deep copy local properties.
-  if (copy->HasFastProperties()) {
-    Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
-    int limit = copy->map()->NumberOfOwnDescriptors();
-    for (int i = 0; i < limit; i++) {
-      PropertyDetails details = descriptors->GetDetails(i);
-      if (details.type() != FIELD) continue;
-      int index = descriptors->GetFieldIndex(i);
-      Handle<Object> value(object->RawFastPropertyAt(index), isolate);
-      if (value->IsJSObject()) {
-        value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value));
-        RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>());
-      } else {
-        Representation representation = details.representation();
-        value = NewStorageFor(isolate, value, representation);
-      }
-      if (copying) {
-        copy->FastPropertyAtPut(index, *value);
-      }
-    }
-  } else {
-    Handle<FixedArray> names =
-        isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties());
-    copy->GetLocalPropertyNames(*names, 0);
-    for (int i = 0; i < names->length(); i++) {
-      ASSERT(names->get(i)->IsString());
-      Handle<String> key_string(String::cast(names->get(i)));
-      PropertyAttributes attributes =
-          copy->GetLocalPropertyAttribute(*key_string);
-      // Only deep copy fields from the object literal expression.
-      // In particular, don't try to copy the length attribute of
-      // an array.
-      if (attributes != NONE) continue;
-      Handle<Object> value(
-          copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
-          isolate);
-      if (value->IsJSObject()) {
-        Handle<JSObject> result = VisitElementOrProperty(
-            copy, Handle<JSObject>::cast(value));
-        RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-        if (copying) {
-          // Creating object copy for literals. No strict mode needed.
-          CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
-              copy, key_string, result, NONE, kNonStrictMode));
-        }
-      }
-    }
+  ElementsKind kind = copy->GetElementsKind();
+  if (copying && IsFastSmiOrObjectElementsKind(kind) &&
+      FixedArray::cast(copy->elements())->map() ==
+        isolate->heap()->fixed_cow_array_map()) {
+    isolate->counters()->cow_arrays_created_runtime()->Increment();
   }
 
-  // Deep copy local elements.
-  // Pixel elements cannot be created using an object literal.
-  ASSERT(!copy->HasExternalArrayElements());
-  switch (copy->GetElementsKind()) {
-    case FAST_SMI_ELEMENTS:
-    case FAST_ELEMENTS:
-    case FAST_HOLEY_SMI_ELEMENTS:
-    case FAST_HOLEY_ELEMENTS: {
-      Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
-      if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
-        if (copying) {
-          isolate->counters()->cow_arrays_created_runtime()->Increment();
+  if (!shallow) {
+    HandleScope scope(isolate);
+
+    // Deep copy local properties.
+    if (copy->HasFastProperties()) {
+      Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
+      int limit = copy->map()->NumberOfOwnDescriptors();
+      for (int i = 0; i < limit; i++) {
+        PropertyDetails details = descriptors->GetDetails(i);
+        if (details.type() != FIELD) continue;
+        int index = descriptors->GetFieldIndex(i);
+        Handle<Object> value(object->RawFastPropertyAt(index), isolate);
+        if (value->IsJSObject()) {
+          value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value));
+          RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>());
+        } else {
+          Representation representation = details.representation();
+          value = NewStorageFor(isolate, value, representation);
         }
+        if (copying) {
+          copy->FastPropertyAtPut(index, *value);
+        }
+      }
+    } else {
+      Handle<FixedArray> names =
+          isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties());
+      copy->GetLocalPropertyNames(*names, 0);
+      for (int i = 0; i < names->length(); i++) {
+        ASSERT(names->get(i)->IsString());
+        Handle<String> key_string(String::cast(names->get(i)));
+        PropertyAttributes attributes =
+            copy->GetLocalPropertyAttribute(*key_string);
+        // Only deep copy fields from the object literal expression.
+        // In particular, don't try to copy the length attribute of
+        // an array.
+        if (attributes != NONE) continue;
+        Handle<Object> value(
+            copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
+            isolate);
+        if (value->IsJSObject()) {
+          Handle<JSObject> result = VisitElementOrProperty(
+              copy, Handle<JSObject>::cast(value));
+          RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
+          if (copying) {
+            // Creating object copy for literals. No strict mode needed.
+            CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty(
+                copy, key_string, result, NONE, kNonStrictMode));
+          }
+        }
+      }
+    }
+
+    // Deep copy local elements.
+    // Pixel elements cannot be created using an object literal.
+    ASSERT(!copy->HasExternalArrayElements());
+    switch (kind) {
+      case FAST_SMI_ELEMENTS:
+      case FAST_ELEMENTS:
+      case FAST_HOLEY_SMI_ELEMENTS:
+      case FAST_HOLEY_ELEMENTS: {
+        Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
+        if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
 #ifdef DEBUG
-        for (int i = 0; i < elements->length(); i++) {
-          ASSERT(!elements->get(i)->IsJSObject());
-        }
+          for (int i = 0; i < elements->length(); i++) {
+            ASSERT(!elements->get(i)->IsJSObject());
+          }
 #endif
-      } else {
-        for (int i = 0; i < elements->length(); i++) {
-          Handle<Object> value(elements->get(i), isolate);
-          ASSERT(value->IsSmi() ||
-                 value->IsTheHole() ||
-                 (IsFastObjectElementsKind(copy->GetElementsKind())));
-          if (value->IsJSObject()) {
-            Handle<JSObject> result = VisitElementOrProperty(
-                copy, Handle<JSObject>::cast(value));
-            RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-            if (copying) {
-              elements->set(i, *result);
+        } else {
+          for (int i = 0; i < elements->length(); i++) {
+            Handle<Object> value(elements->get(i), isolate);
+            ASSERT(value->IsSmi() ||
+                   value->IsTheHole() ||
+                   (IsFastObjectElementsKind(copy->GetElementsKind())));
+            if (value->IsJSObject()) {
+              Handle<JSObject> result = VisitElementOrProperty(
+                  copy, Handle<JSObject>::cast(value));
+              RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
+              if (copying) {
+                elements->set(i, *result);
+              }
             }
           }
         }
+        break;
       }
-      break;
-    }
-    case DICTIONARY_ELEMENTS: {
-      Handle<SeededNumberDictionary> element_dictionary(
-          copy->element_dictionary());
-      int capacity = element_dictionary->Capacity();
-      for (int i = 0; i < capacity; i++) {
-        Object* k = element_dictionary->KeyAt(i);
-        if (element_dictionary->IsKey(k)) {
-          Handle<Object> value(element_dictionary->ValueAt(i), isolate);
-          if (value->IsJSObject()) {
-            Handle<JSObject> result = VisitElementOrProperty(
-                copy, Handle<JSObject>::cast(value));
-            RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
-            if (copying) {
-              element_dictionary->ValueAtPut(i, *result);
+      case DICTIONARY_ELEMENTS: {
+        Handle<SeededNumberDictionary> element_dictionary(
+            copy->element_dictionary());
+        int capacity = element_dictionary->Capacity();
+        for (int i = 0; i < capacity; i++) {
+          Object* k = element_dictionary->KeyAt(i);
+          if (element_dictionary->IsKey(k)) {
+            Handle<Object> value(element_dictionary->ValueAt(i), isolate);
+            if (value->IsJSObject()) {
+              Handle<JSObject> result = VisitElementOrProperty(
+                  copy, Handle<JSObject>::cast(value));
+              RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
+              if (copying) {
+                element_dictionary->ValueAtPut(i, *result);
+              }
             }
           }
         }
+        break;
       }
-      break;
+      case NON_STRICT_ARGUMENTS_ELEMENTS:
+        UNIMPLEMENTED();
+        break;
+      case EXTERNAL_PIXEL_ELEMENTS:
+      case EXTERNAL_BYTE_ELEMENTS:
+      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+      case EXTERNAL_SHORT_ELEMENTS:
+      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+      case EXTERNAL_INT_ELEMENTS:
+      case EXTERNAL_UNSIGNED_INT_ELEMENTS:
+      case EXTERNAL_FLOAT_ELEMENTS:
+      case EXTERNAL_DOUBLE_ELEMENTS:
+      case FAST_DOUBLE_ELEMENTS:
+      case FAST_HOLEY_DOUBLE_ELEMENTS:
+        // No contained objects, nothing to do.
+        break;
     }
-    case NON_STRICT_ARGUMENTS_ELEMENTS:
-      UNIMPLEMENTED();
-      break;
-    case EXTERNAL_PIXEL_ELEMENTS:
-    case EXTERNAL_BYTE_ELEMENTS:
-    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
-    case EXTERNAL_SHORT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
-    case EXTERNAL_INT_ELEMENTS:
-    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
-    case EXTERNAL_FLOAT_ELEMENTS:
-    case EXTERNAL_DOUBLE_ELEMENTS:
-    case FAST_DOUBLE_ELEMENTS:
-    case FAST_HOLEY_DOUBLE_ELEMENTS:
-      // No contained objects, nothing to do.
-      break;
   }
+
   return copy;
 }
 
 
-Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object,
-                                    AllocationSiteContext* site_context) {
-  JSObjectCreateAllocationSitesVisitor v(site_context);
-  Handle<JSObject> result = v.Visit(object);
-  ASSERT(!v.is_copying() &&
-         (result.is_null() || result.is_identical_to(object)));
+Handle<JSObject> JSObject::DeepWalk(
+    Handle<JSObject> object,
+    AllocationSiteCreationContext* site_context) {
+  JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false,
+                                                       kNoHints);
+  Handle<JSObject> result = v.StructureWalk(object);
+  ASSERT(result.is_null() || result.is_identical_to(object));
   return result;
 }
 
 
 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object,
-                                    AllocationSiteContext* site_context) {
-  JSObjectCopyVisitor v(site_context);
-  Handle<JSObject> copy = v.Visit(object);
-  ASSERT(v.is_copying() && !copy.is_identical_to(object));
+                                    AllocationSiteUsageContext* site_context,
+                                    DeepCopyHints hints) {
+  JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints);
+  Handle<JSObject> copy = v.StructureWalk(object);
+  ASSERT(!copy.is_identical_to(object));
   return copy;
 }
 
diff --git a/src/objects.h b/src/objects.h
index 93d35bf..2ae1429 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -861,7 +861,8 @@
 
 class AccessorPair;
 class AllocationSite;
-class AllocationSiteContext;
+class AllocationSiteCreationContext;
+class AllocationSiteUsageContext;
 class DictionaryElementsAccessor;
 class ElementsAccessor;
 class Failure;
@@ -2521,13 +2522,17 @@
   static void SetObserved(Handle<JSObject> object);
 
   // Copy object.
-  static Handle<JSObject> Copy(Handle<JSObject> object,
-                               Handle<AllocationSite> site);
+  enum DeepCopyHints {
+    kNoHints = 0,
+    kObjectIsShallowArray = 1
+  };
+
   static Handle<JSObject> Copy(Handle<JSObject> object);
   static Handle<JSObject> DeepCopy(Handle<JSObject> object,
-                                   AllocationSiteContext* site_context);
+                                   AllocationSiteUsageContext* site_context,
+                                   DeepCopyHints hints = kNoHints);
   static Handle<JSObject> DeepWalk(Handle<JSObject> object,
-                                   AllocationSiteContext* site_context);
+                                   AllocationSiteCreationContext* site_context);
 
   // Casting.
   static inline JSObject* cast(Object* obj);
diff --git a/src/property-details.h b/src/property-details.h
index 36f1406..617e9b2 100644
--- a/src/property-details.h
+++ b/src/property-details.h
@@ -131,6 +131,10 @@
   }
 
   bool is_more_general_than(const Representation& other) const {
+    if (kind_ == kExternal && other.kind_ == kNone) return true;
+    if (kind_ == kExternal && other.kind_ == kExternal) return false;
+    if (kind_ == kNone && other.kind_ == kExternal) return false;
+
     ASSERT(kind_ != kExternal);
     ASSERT(other.kind_ != kExternal);
     if (IsHeapObject()) return other.IsDouble() || other.IsNone();
diff --git a/src/runtime.cc b/src/runtime.cc
index 092e91e..fbe4426 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -554,24 +554,52 @@
 }
 
 
+static MaybeObject* CreateArrayLiteralImpl(Isolate* isolate,
+                                           Handle<FixedArray> literals,
+                                           int literals_index,
+                                           Handle<FixedArray> elements,
+                                           int flags) {
+  Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
+      literals_index, elements);
+  RETURN_IF_EMPTY_HANDLE(isolate, site);
+
+  bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
+  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
+  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
+  usage_context.EnterNewScope();
+  JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
+      ? JSObject::kNoHints
+      : JSObject::kObjectIsShallowArray;
+  Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
+                                             hints);
+  usage_context.ExitScope(site, boilerplate);
+  RETURN_IF_EMPTY_HANDLE(isolate, copy);
+  return *copy;
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
   HandleScope scope(isolate);
+  ASSERT(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
+  CONVERT_SMI_ARG_CHECKED(flags, 3);
+
+  return CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
+                                flags);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralStubBailout) {
+  HandleScope scope(isolate);
   ASSERT(args.length() == 3);
   CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
   CONVERT_SMI_ARG_CHECKED(literals_index, 1);
   CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
 
-  Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
-      literals_index, elements);
-  RETURN_IF_EMPTY_HANDLE(isolate, site);
-
-  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
-  AllocationSiteUsageContext usage_context(isolate, site, true);
-  usage_context.EnterNewScope();
-  Handle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context);
-  usage_context.ExitScope(site, boilerplate);
-  RETURN_IF_EMPTY_HANDLE(isolate, copy);
-  return *copy;
+  return CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
+                                ArrayLiteral::kShallowElements);
 }
 
 
@@ -835,20 +863,7 @@
 }
 
 
-enum TypedArrayId {
-  // arrayIds below should be synchromized with typedarray.js natives.
-  ARRAY_ID_UINT8 = 1,
-  ARRAY_ID_INT8 = 2,
-  ARRAY_ID_UINT16 = 3,
-  ARRAY_ID_INT16 = 4,
-  ARRAY_ID_UINT32 = 5,
-  ARRAY_ID_INT32 = 6,
-  ARRAY_ID_FLOAT32 = 7,
-  ARRAY_ID_FLOAT64 = 8,
-  ARRAY_ID_UINT8C = 9
-};
-
-static void ArrayIdToTypeAndSize(
+void Runtime::ArrayIdToTypeAndSize(
     int arrayId, ExternalArrayType* array_type, size_t* element_size) {
   switch (arrayId) {
     case ARRAY_ID_UINT8:
@@ -910,7 +925,7 @@
 
   ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
   size_t element_size = 1;  // Bogus initialization.
-  ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
+  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
 
   holder->set_buffer(*buffer);
   holder->set_byte_offset(*byte_offset_object);
@@ -962,7 +977,7 @@
 
   ExternalArrayType array_type = kExternalByteArray;  // Bogus initialization.
   size_t element_size = 1;  // Bogus initialization.
-  ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
+  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
 
   Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
   size_t length = NumberToSize(isolate, *length_obj);
@@ -7686,16 +7701,6 @@
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_ceil) {
-  SealHandleScope shs(isolate);
-  ASSERT(args.length() == 1);
-  isolate->counters()->math_ceil()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return isolate->heap()->NumberFromDouble(ceiling(x));
-}
-
-
 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
   SealHandleScope shs(isolate);
   ASSERT(args.length() == 1);
diff --git a/src/runtime.h b/src/runtime.h
index 43d4065..62c52a7 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -179,7 +179,6 @@
   F(Math_asin, 1, 1) \
   F(Math_atan, 1, 1) \
   F(Math_atan2, 2, 1) \
-  F(Math_ceil, 1, 1) \
   F(Math_cos, 1, 1) \
   F(Math_exp, 1, 1) \
   F(Math_floor, 1, 1) \
@@ -300,7 +299,8 @@
   /* Literals */ \
   F(MaterializeRegExpLiteral, 4, 1)\
   F(CreateObjectLiteral, 4, 1) \
-  F(CreateArrayLiteral, 3, 1) \
+  F(CreateArrayLiteral, 4, 1) \
+  F(CreateArrayLiteralStubBailout, 3, 1) \
   \
   /* Harmony generators */ \
   F(CreateJSGeneratorObject, 0, 1) \
@@ -829,6 +829,22 @@
       Isolate* isolate,
       JSArrayBuffer* phantom_array_buffer);
 
+  enum TypedArrayId {
+    // arrayIds below should be synchromized with typedarray.js natives.
+    ARRAY_ID_UINT8 = 1,
+    ARRAY_ID_INT8 = 2,
+    ARRAY_ID_UINT16 = 3,
+    ARRAY_ID_INT16 = 4,
+    ARRAY_ID_UINT32 = 5,
+    ARRAY_ID_INT32 = 6,
+    ARRAY_ID_FLOAT32 = 7,
+    ARRAY_ID_FLOAT64 = 8,
+    ARRAY_ID_UINT8C = 9
+  };
+
+  static void ArrayIdToTypeAndSize(int array_id,
+      ExternalArrayType *type, size_t *element_size);
+
   // Helper functions used stubs.
   static void PerformGC(Object* result, Isolate* isolate);
 
diff --git a/src/typedarray.js b/src/typedarray.js
index fc3a608..ed9de23 100644
--- a/src/typedarray.js
+++ b/src/typedarray.js
@@ -78,7 +78,8 @@
       var newLength = ToPositiveInteger(length, "invalid_typed_array_length");
       newByteLength = newLength * ELEMENT_SIZE;
     }
-    if (offset + newByteLength > bufferByteLength) {
+    if ((offset + newByteLength > bufferByteLength)
+        || (newLength > %MaxSmi())) {
       throw MakeRangeError("invalid_typed_array_length");
     }
     %TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength);
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 54e8100..9178046 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -242,7 +242,6 @@
   SC(math_asin, V8.MathAsin)                                          \
   SC(math_atan, V8.MathAtan)                                          \
   SC(math_atan2, V8.MathAtan2)                                        \
-  SC(math_ceil, V8.MathCeil)                                          \
   SC(math_cos, V8.MathCos)                                            \
   SC(math_exp, V8.MathExp)                                            \
   SC(math_floor, V8.MathFloor)                                        \
diff --git a/src/version.cc b/src/version.cc
index ce766ce..e03ed8d 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     23
-#define BUILD_NUMBER      11
+#define BUILD_NUMBER      12
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index ac69a24..709b61b 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -586,13 +586,6 @@
     set_target_address_at(instruction_payload, target);
   }
 
-  // This sets the branch destination (which is a load instruction on x64).
-  // This is for calls and branches to runtime code.
-  inline static void set_external_target_at(Address instruction_payload,
-                                            Address target) {
-    *reinterpret_cast<Address*>(instruction_payload) = target;
-  }
-
   inline Handle<Object> code_target_object_handle_at(Address pc);
   inline Address runtime_entry_at(Address pc);
   // Number of bytes taken up by the branch target in the code.
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 8712e27..4fb3a70 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -78,7 +78,7 @@
   descriptor->register_param_count_ = 3;
   descriptor->register_params_ = registers;
   descriptor->deoptimization_handler_ =
-      Runtime::FunctionForId(Runtime::kCreateArrayLiteral)->entry;
+      Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry;
 }
 
 
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index a62fde0..ed4c3ad 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1726,6 +1726,10 @@
   Comment cmnt(masm_, "[ ArrayLiteral");
 
   expr->BuildConstantElements(isolate());
+  int flags = expr->depth() == 1
+      ? ArrayLiteral::kShallowElements
+      : ArrayLiteral::kNoFlags;
+
   ZoneList<Expression*>* subexprs = expr->values();
   int length = subexprs->length();
   Handle<FixedArray> constant_elements = expr->constant_elements();
@@ -1758,7 +1762,8 @@
     __ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
     __ Push(Smi::FromInt(expr->literal_index()));
     __ Push(constant_elements);
-    __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
+    __ Push(Smi::FromInt(flags));
+    __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
   } else {
     ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind) ||
            FLAG_smi_only_arrays);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index cf0632e..e56bb54 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1781,14 +1781,22 @@
   LOperand* left = instr->left();
   LOperand* right = instr->right();
 
+  Representation target_rep = instr->hydrogen()->representation();
+  bool is_q = target_rep.IsSmi() || target_rep.IsExternal();
+
   if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
     if (right->IsConstantOperand()) {
       int32_t offset = ToInteger32(LConstantOperand::cast(right));
-      __ leal(ToRegister(instr->result()),
-              MemOperand(ToRegister(left), offset));
+      if (is_q) {
+        __ lea(ToRegister(instr->result()),
+               MemOperand(ToRegister(left), offset));
+      } else {
+        __ leal(ToRegister(instr->result()),
+                MemOperand(ToRegister(left), offset));
+      }
     } else {
       Operand address(ToRegister(left), ToRegister(right), times_1, 0);
-      if (instr->hydrogen()->representation().IsSmi()) {
+      if (is_q) {
         __ lea(ToRegister(instr->result()), address);
       } else {
         __ leal(ToRegister(instr->result()), address);
@@ -1796,16 +1804,21 @@
     }
   } else {
     if (right->IsConstantOperand()) {
-      __ addl(ToRegister(left),
-              Immediate(ToInteger32(LConstantOperand::cast(right))));
+      if (is_q) {
+        __ addq(ToRegister(left),
+                Immediate(ToInteger32(LConstantOperand::cast(right))));
+      } else {
+        __ addl(ToRegister(left),
+                Immediate(ToInteger32(LConstantOperand::cast(right))));
+      }
     } else if (right->IsRegister()) {
-      if (instr->hydrogen_value()->representation().IsSmi()) {
+      if (is_q) {
         __ addq(ToRegister(left), ToRegister(right));
       } else {
         __ addl(ToRegister(left), ToRegister(right));
       }
     } else {
-      if (instr->hydrogen_value()->representation().IsSmi()) {
+      if (is_q) {
         __ addq(ToRegister(left), ToOperand(right));
       } else {
         __ addl(ToRegister(left), ToOperand(right));
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index fa1bdaa..78bc5bb 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1557,6 +1557,21 @@
       result = AssignEnvironment(result);
     }
     return result;
+  } else if (instr->representation().IsExternal()) {
+    ASSERT(instr->left()->representation().IsExternal());
+    ASSERT(instr->right()->representation().IsInteger32());
+    ASSERT(!instr->CheckFlag(HValue::kCanOverflow));
+    bool use_lea = LAddI::UseLea(instr);
+    LOperand* left = UseRegisterAtStart(instr->left());
+    HValue* right_candidate = instr->right();
+    LOperand* right = use_lea
+        ? UseRegisterOrConstantAtStart(right_candidate)
+        : UseOrConstantAtStart(right_candidate);
+    LAddI* add = new(zone()) LAddI(left, right);
+    LInstruction* result = use_lea
+        ? DefineAsRegister(add)
+        : DefineSameAsFirst(add);
+    return result;
   } else if (instr->representation().IsDouble()) {
     return DoArithmeticD(Token::ADD, instr);
   } else {
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 57c6a35..e64698c 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -379,17 +379,12 @@
     Register receiver,
     Register holder,
     Register name,
-    Handle<JSObject> holder_obj) {
+    Handle<JSObject> holder_obj,
+    IC::UtilityId id) {
   PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
-
-  ExternalReference ref =
-      ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
-                        masm->isolate());
-  __ Set(rax, StubCache::kInterceptorArgsLength);
-  __ LoadAddress(rbx, ref);
-
-  CEntryStub stub(1);
-  __ CallStub(&stub);
+  __ CallExternalReference(
+      ExternalReference(IC_Utility(id), masm->isolate()),
+      StubCache::kInterceptorArgsLength);
 }
 
 
@@ -794,12 +789,9 @@
     // Save the name_ register across the call.
     __ push(name_);
 
-    PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder);
-
-    __ CallExternalReference(
-        ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
-                          masm->isolate()),
-        StubCache::kInterceptorArgsLength);
+    CompileCallLoadPropertyWithInterceptor(
+        masm, receiver, holder, name_, interceptor_holder,
+        IC::kLoadPropertyWithInterceptorForCall);
 
     // Restore the name_ register.
     __ pop(name_);
@@ -817,11 +809,9 @@
       __ push(holder);  // Save the holder.
       __ push(name_);  // Save the name.
 
-      CompileCallLoadPropertyWithInterceptor(masm,
-                                             receiver,
-                                             holder,
-                                             name_,
-                                             holder_obj);
+      CompileCallLoadPropertyWithInterceptor(
+          masm, receiver, holder, name_, holder_obj,
+          IC::kLoadPropertyWithInterceptorOnly);
 
       __ pop(name_);  // Restore the name.
       __ pop(receiver);  // Restore the holder.
@@ -1501,11 +1491,9 @@
       // Invoke an interceptor.  Note: map checks from receiver to
       // interceptor's holder has been compiled before (see a caller
       // of this method.)
-      CompileCallLoadPropertyWithInterceptor(masm(),
-                                             receiver(),
-                                             holder_reg,
-                                             this->name(),
-                                             interceptor_holder);
+      CompileCallLoadPropertyWithInterceptor(
+          masm(), receiver(), holder_reg, this->name(), interceptor_holder,
+          IC::kLoadPropertyWithInterceptorOnly);
 
       // Check if interceptor provided a value for property.  If it's
       // the case, return immediately.