Version 3.2.5

Fixed build with Irregexp interpreter (issue 1266). 

Added Crankshaft support for external arrays.

Fixed two potential crash bugs.



git-svn-id: http://v8.googlecode.com/svn/trunk@7385 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index 32381dc..dcf8e17 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -55,45 +55,45 @@
 
 // TODO(isolates): avoid repeated TLS reads in function prologues.
 #ifdef ENABLE_VMSTATE_TRACKING
-#define ENTER_V8                                        \
-  ASSERT(i::Isolate::Current()->IsInitialized());                           \
-  i::VMState __state__(i::Isolate::Current(), i::OTHER)
-#define LEAVE_V8 \
-  i::VMState __state__(i::Isolate::Current(), i::EXTERNAL)
+#define ENTER_V8(isolate)                                        \
+  ASSERT((isolate)->IsInitialized());                           \
+  i::VMState __state__((isolate), i::OTHER)
+#define LEAVE_V8(isolate) \
+  i::VMState __state__((isolate), i::EXTERNAL)
 #else
-#define ENTER_V8 ((void) 0)
-#define LEAVE_V8 ((void) 0)
+#define ENTER_V8(isolate) ((void) 0)
+#define LEAVE_V8(isolate) ((void) 0)
 #endif
 
 namespace v8 {
 
 #define ON_BAILOUT(isolate, location, code)                        \
   if (IsDeadCheck(isolate, location) ||                            \
-            v8::V8::IsExecutionTerminating()) {                    \
+      IsExecutionTerminatingCheck(isolate)) {                      \
     code;                                                          \
     UNREACHABLE();                                                 \
   }
 
 
-#define EXCEPTION_PREAMBLE()                                                \
-  i::Isolate::Current()->handle_scope_implementer()->IncrementCallDepth();  \
-  ASSERT(!i::Isolate::Current()->external_caught_exception());              \
+#define EXCEPTION_PREAMBLE(isolate)                                         \
+  (isolate)->handle_scope_implementer()->IncrementCallDepth();              \
+  ASSERT(!(isolate)->external_caught_exception());                          \
   bool has_pending_exception = false
 
 
-#define EXCEPTION_BAILOUT_CHECK(value)                                         \
+#define EXCEPTION_BAILOUT_CHECK(isolate, value)                                \
   do {                                                                         \
     i::HandleScopeImplementer* handle_scope_implementer =                      \
-        isolate->handle_scope_implementer();                                   \
+        (isolate)->handle_scope_implementer();                                 \
     handle_scope_implementer->DecrementCallDepth();                            \
     if (has_pending_exception) {                                               \
       if (handle_scope_implementer->CallDepthIsZero() &&                       \
-          i::Isolate::Current()->is_out_of_memory()) {                         \
+          (isolate)->is_out_of_memory()) {                                     \
         if (!handle_scope_implementer->ignore_out_of_memory())                 \
           i::V8::FatalProcessOutOfMemory(NULL);                                \
       }                                                                        \
       bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();   \
-      i::Isolate::Current()->OptionalRescheduleException(call_depth_is_zero);  \
+      (isolate)->OptionalRescheduleException(call_depth_is_zero);              \
       return value;                                                            \
     }                                                                          \
   } while (false)
@@ -191,11 +191,12 @@
   heap_stats.os_error = &os_error;
   int end_marker;
   heap_stats.end_marker = &end_marker;
-  HEAP->RecordStats(&heap_stats, take_snapshot);
+  i::Isolate* isolate = i::Isolate::Current();
+  isolate->heap()->RecordStats(&heap_stats, take_snapshot);
   i::V8::SetFatalError();
   FatalErrorCallback callback = GetFatalErrorHandler();
   {
-    LEAVE_V8;
+    LEAVE_V8(isolate);
     callback(location, "Allocation failed - process out of memory");
   }
   // If the callback returns, we stop execution.
@@ -255,6 +256,16 @@
 }
 
 
+static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
+  if (!isolate->IsInitialized()) return false;
+  if (isolate->has_scheduled_exception()) {
+    return isolate->scheduled_exception() ==
+        isolate->heap()->termination_exception();
+  }
+  return false;
+}
+
+
 static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {
   return obj.IsEmpty() ? ReportEmptyHandle(location) : false;
 }
@@ -282,11 +293,6 @@
   return ApiCheck(InitializeHelper(), location, "Error initializing V8");
 }
 
-static inline bool EnsureInitialized(const char* location) {
-  i::Isolate* isolate = i::Isolate::UncheckedCurrent();
-  return EnsureInitializedForIsolate(isolate, location);
-}
-
 // Some initializing API functions are called early and may be
 // called on a thread different from static initializer thread.
 // If Isolate API is used, Isolate::Enter() will initialize TLS so
@@ -319,32 +325,6 @@
 #endif
 
 
-v8::Handle<v8::Primitive> ImplementationUtilities::Undefined() {
-  if (!EnsureInitialized("v8::Undefined()")) return v8::Handle<v8::Primitive>();
-  return v8::Handle<Primitive>(ToApi<Primitive>(FACTORY->undefined_value()));
-}
-
-
-v8::Handle<v8::Primitive> ImplementationUtilities::Null() {
-  i::Isolate* isolate = i::Isolate::UncheckedCurrent();
-  if (!EnsureInitializedForIsolate(isolate, "v8::Null()"))
-      return v8::Handle<v8::Primitive>();
-  return v8::Handle<Primitive>(
-      ToApi<Primitive>(isolate->factory()->null_value()));
-}
-
-
-v8::Handle<v8::Boolean> ImplementationUtilities::True() {
-  if (!EnsureInitialized("v8::True()")) return v8::Handle<v8::Boolean>();
-  return v8::Handle<v8::Boolean>(ToApi<Boolean>(FACTORY->true_value()));
-}
-
-
-v8::Handle<v8::Boolean> ImplementationUtilities::False() {
-  if (!EnsureInitialized("v8::False()")) return v8::Handle<v8::Boolean>();
-  return v8::Handle<v8::Boolean>(ToApi<Boolean>(FACTORY->false_value()));
-}
-
 void V8::SetFlagsFromString(const char* str, int length) {
   i::FlagList::SetFlagsFromString(str, length);
 }
@@ -360,11 +340,11 @@
   if (IsDeadCheck(isolate, "v8::ThrowException()")) {
     return v8::Handle<Value>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   // If we're passed an empty handle, we throw an undefined exception
   // to deal more gracefully with out of memory situations.
   if (value.IsEmpty()) {
-    isolate->ScheduleThrow(HEAP->undefined_value());
+    isolate->ScheduleThrow(isolate->heap()->undefined_value());
   } else {
     isolate->ScheduleThrow(*Utils::OpenHandle(*value));
   }
@@ -404,29 +384,41 @@
 
 v8::Handle<Primitive> Undefined() {
   i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate,  "Undefined");
-  return ImplementationUtilities::Undefined();
+  if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) {
+    return v8::Handle<v8::Primitive>();
+  }
+  return v8::Handle<Primitive>(ToApi<Primitive>(
+      isolate->factory()->undefined_value()));
 }
 
 
 v8::Handle<Primitive> Null() {
   i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "Null");
-  return ImplementationUtilities::Null();
+  if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) {
+    return v8::Handle<v8::Primitive>();
+  }
+  return v8::Handle<Primitive>(
+      ToApi<Primitive>(isolate->factory()->null_value()));
 }
 
 
 v8::Handle<Boolean> True() {
   i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "True");
-  return ImplementationUtilities::True();
+  if (!EnsureInitializedForIsolate(isolate, "v8::True()")) {
+    return v8::Handle<Boolean>();
+  }
+  return v8::Handle<Boolean>(
+      ToApi<Boolean>(isolate->factory()->true_value()));
 }
 
 
 v8::Handle<Boolean> False() {
   i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "False");
-  return ImplementationUtilities::False();
+  if (!EnsureInitializedForIsolate(isolate, "v8::False()")) {
+    return v8::Handle<Boolean>();
+  }
+  return v8::Handle<Boolean>(
+      ToApi<Boolean>(isolate->factory()->false_value()));
 }
 
 
@@ -550,7 +542,8 @@
 
 
 int HandleScope::NumberOfHandles() {
-  EnsureInitialized("HandleScope::NumberOfHandles");
+  EnsureInitializedForIsolate(
+      i::Isolate::Current(), "HandleScope::NumberOfHandles");
   return i::HandleScope::NumberOfHandles();
 }
 
@@ -571,7 +564,8 @@
   // TODO(isolates): Context should have a pointer to isolate.
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::Context::Enter()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
+
   i::Handle<i::Context> env = Utils::OpenHandle(this);
   isolate->handle_scope_implementer()->EnterContext(env);
 
@@ -602,7 +596,7 @@
   // TODO(isolates): Context should have a pointer to isolate.
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::Context::SetData()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   {
     i::HandleScope scope(isolate);
     i::Handle<i::Context> env = Utils::OpenHandle(this);
@@ -621,7 +615,7 @@
   if (IsDeadCheck(isolate, "v8::Context::GetData()")) {
     return v8::Local<Value>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* raw_result = NULL;
   {
     i::HandleScope scope(isolate);
@@ -673,10 +667,11 @@
 // NeanderObject constructor.  When you add one to the site calling the
 // constructor you should check that you ensured the VM was not dead first.
 NeanderObject::NeanderObject(int size) {
-  EnsureInitialized("v8::Nowhere");
-  ENTER_V8;
-  value_ = FACTORY->NewNeanderObject();
-  i::Handle<i::FixedArray> elements = FACTORY->NewFixedArray(size);
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::Nowhere");
+  ENTER_V8(isolate);
+  value_ = isolate->factory()->NewNeanderObject();
+  i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
   value_->set_elements(*elements);
 }
 
@@ -740,7 +735,7 @@
                    v8::PropertyAttribute attribute) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::Template::Set()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
   if (list->IsUndefined()) {
@@ -763,11 +758,11 @@
 
 
 Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::FunctionTemplate::PrototypeTemplate()")) {
     return Local<ObjectTemplate>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template());
   if (result->IsUndefined()) {
     result = Utils::OpenHandle(*ObjectTemplate::New());
@@ -778,9 +773,9 @@
 
 
 void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::FunctionTemplate::Inherit()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
 }
 
@@ -790,7 +785,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::FunctionTemplate::New()");
   LOG_API(isolate, "FunctionTemplate::New");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Struct> struct_obj =
       isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
   i::Handle<i::FunctionTemplateInfo> obj =
@@ -817,7 +812,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Signature::New()");
   LOG_API(isolate, "Signature::New");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Struct> struct_obj =
       isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
   i::Handle<i::SignatureInfo> obj =
@@ -845,7 +840,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()");
   LOG_API(isolate, "TypeSwitch::New");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
   for (int i = 0; i < argc; i++)
     vector->set(i, *Utils::OpenHandle(*types[i]));
@@ -880,9 +875,9 @@
 
 void FunctionTemplate::SetCallHandler(InvocationCallback callback,
                                       v8::Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::Struct> struct_obj =
       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
@@ -924,12 +919,12 @@
       v8::Handle<Value> data,
       v8::AccessControl settings,
       v8::PropertyAttribute attributes) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate,
                   "v8::FunctionTemplate::AddInstancePropertyAccessor()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
 
   i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(name,
@@ -946,11 +941,11 @@
 
 
 Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::FunctionTemplate::InstanceTemplate()")
       || EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this))
     return Local<ObjectTemplate>();
-  ENTER_V8;
+  ENTER_V8(isolate);
   if (Utils::OpenHandle(this)->instance_template()->IsUndefined()) {
     Local<ObjectTemplate> templ =
         ObjectTemplate::New(v8::Handle<FunctionTemplate>(this));
@@ -963,19 +958,19 @@
 
 
 void FunctionTemplate::SetClassName(Handle<String> name) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetClassName()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
 }
 
 
 void FunctionTemplate::SetHiddenPrototype(bool value) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetHiddenPrototype()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   Utils::OpenHandle(this)->set_hidden_prototype(value);
 }
 
@@ -987,12 +982,12 @@
       NamedPropertyDeleter remover,
       NamedPropertyEnumerator enumerator,
       Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate,
                   "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::Struct> struct_obj =
       isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
@@ -1018,12 +1013,12 @@
       IndexedPropertyDeleter remover,
       IndexedPropertyEnumerator enumerator,
       Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate,
         "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::Struct> struct_obj =
       isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
@@ -1045,12 +1040,12 @@
 void FunctionTemplate::SetInstanceCallAsFunctionHandler(
       InvocationCallback callback,
       Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate,
                   "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::Struct> struct_obj =
       isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
@@ -1079,9 +1074,9 @@
   }
   EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()");
   LOG_API(isolate, "ObjectTemplate::New");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Struct> struct_obj =
-    isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
+      isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
   i::Handle<i::ObjectTemplateInfo> obj =
       i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
   InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
@@ -1110,9 +1105,9 @@
                                  v8::Handle<Value> data,
                                  AccessControl settings,
                                  PropertyAttribute attribute) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessor()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   EnsureConstructor(this);
   i::FunctionTemplateInfo* constructor =
@@ -1133,12 +1128,12 @@
                                              NamedPropertyDeleter remover,
                                              NamedPropertyEnumerator enumerator,
                                              Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
     return;
   }
-  ENTER_V8;
-  HandleScope scope;
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
   EnsureConstructor(this);
   i::FunctionTemplateInfo* constructor =
       i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
@@ -1153,9 +1148,9 @@
 
 
 void ObjectTemplate::MarkAsUndetectable() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUndetectable()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   EnsureConstructor(this);
   i::FunctionTemplateInfo* constructor =
@@ -1170,11 +1165,11 @@
       IndexedSecurityCallback indexed_callback,
       Handle<Value> data,
       bool turned_on_by_default) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetAccessCheckCallbacks()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   EnsureConstructor(this);
 
@@ -1204,11 +1199,11 @@
       IndexedPropertyDeleter remover,
       IndexedPropertyEnumerator enumerator,
       Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   EnsureConstructor(this);
   i::FunctionTemplateInfo* constructor =
@@ -1225,12 +1220,12 @@
 
 void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
                                               Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate,
                   "v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   EnsureConstructor(this);
   i::FunctionTemplateInfo* constructor =
@@ -1241,7 +1236,7 @@
 
 
 int ObjectTemplate::InternalFieldCount() {
-  if (IsDeadCheck(i::Isolate::Current(),
+  if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
                   "v8::ObjectTemplate::InternalFieldCount()")) {
     return 0;
   }
@@ -1250,7 +1245,7 @@
 
 
 void ObjectTemplate::SetInternalFieldCount(int value) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetInternalFieldCount()")) {
     return;
   }
@@ -1259,7 +1254,7 @@
                 "Invalid internal field count")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   if (value > 0) {
     // The internal field count is set by the constructor function's
     // construct code, so we ensure that there is a constructor
@@ -1324,7 +1319,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
   LOG_API(isolate, "Script::New");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::String> str = Utils::OpenHandle(*source);
   i::Handle<i::Object> name_obj;
   int line_offset = 0;
@@ -1340,7 +1335,7 @@
       column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
     }
   }
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
   // We assert that the pre-data is sane, even though we can actually
   // handle it if it turns out not to be in release mode.
@@ -1359,7 +1354,7 @@
                            Utils::OpenHandle(*script_data),
                            i::NOT_NATIVES_CODE);
   has_pending_exception = result.is_null();
-  EXCEPTION_BAILOUT_CHECK(Local<Script>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
   return Local<Script>(ToApi<Script>(result));
 }
 
@@ -1378,7 +1373,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>());
   LOG_API(isolate, "Script::Compile");
-  ENTER_V8;
+  ENTER_V8(isolate);
   Local<Script> generic = New(source, origin, pre_data, script_data);
   if (generic.IsEmpty())
     return generic;
@@ -1388,7 +1383,7 @@
   i::Handle<i::JSFunction> result =
       isolate->factory()->NewFunctionFromSharedFunctionInfo(
           function,
-          i::Isolate::Current()->global_context());
+          isolate->global_context());
   return Local<Script>(ToApi<Script>(result));
 }
 
@@ -1405,29 +1400,29 @@
   i::Isolate* isolate = i::Isolate::Current();
   ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
   LOG_API(isolate, "Script::Run");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* raw_result = NULL;
   {
-    HandleScope scope;
+    i::HandleScope scope(isolate);
     i::Handle<i::Object> obj = Utils::OpenHandle(this);
     i::Handle<i::JSFunction> fun;
     if (obj->IsSharedFunctionInfo()) {
       i::Handle<i::SharedFunctionInfo>
-          function_info(i::SharedFunctionInfo::cast(*obj));
+          function_info(i::SharedFunctionInfo::cast(*obj), isolate);
       fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(
-          function_info, i::Isolate::Current()->global_context());
+          function_info, isolate->global_context());
     } else {
-      fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj));
+      fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
     }
-    EXCEPTION_PREAMBLE();
+    EXCEPTION_PREAMBLE(isolate);
     i::Handle<i::Object> receiver(
-        i::Isolate::Current()->context()->global_proxy());
+        isolate->context()->global_proxy(), isolate);
     i::Handle<i::Object> result =
         i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<Value>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
     raw_result = *result;
   }
-  i::Handle<i::Object> result(raw_result);
+  i::Handle<i::Object> result(raw_result, isolate);
   return Utils::ToLocal(result);
 }
 
@@ -1493,13 +1488,14 @@
 
 
 v8::TryCatch::~TryCatch() {
+  i::Isolate* isolate = i::Isolate::Current();
   if (rethrow_) {
     v8::HandleScope scope;
     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
-    i::Isolate::Current()->UnregisterTryCatchHandler(this);
+    isolate->UnregisterTryCatchHandler(this);
     v8::ThrowException(exc);
   } else {
-    i::Isolate::Current()->UnregisterTryCatchHandler(this);
+    isolate->UnregisterTryCatchHandler(this);
   }
 }
 
@@ -1578,9 +1574,9 @@
 
 
 Local<String> Message::Get() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(obj);
@@ -1590,11 +1586,11 @@
 
 
 v8::Handle<Value> Message::GetScriptResourceName() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceName()")) {
     return Local<String>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1607,11 +1603,11 @@
 
 
 v8::Handle<Value> Message::GetScriptData() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Message::GetScriptResourceData()")) {
     return Local<Value>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1624,11 +1620,11 @@
 
 
 v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Message::GetStackTrace()")) {
     return Local<v8::StackTrace>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1670,24 +1666,24 @@
 
 
 int Message::GetLineNumber() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
 
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result = CallV8HeapFunction("GetLineNumber",
                                                    Utils::OpenHandle(this),
                                                    &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(0);
+  EXCEPTION_BAILOUT_CHECK(isolate, 0);
   return static_cast<int>(result->Number());
 }
 
 
 int Message::GetStartPosition() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Message::GetStartPosition()")) return 0;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1696,9 +1692,9 @@
 
 
 int Message::GetEndPosition() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Message::GetEndPosition()")) return 0;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
@@ -1707,35 +1703,35 @@
 
 
 int Message::GetStartColumn() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Message::GetStartColumn()")) {
     return kNoColumnInfo;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
       "GetPositionInLine",
       data_obj,
       &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(0);
+  EXCEPTION_BAILOUT_CHECK(isolate, 0);
   return static_cast<int>(start_col_obj->Number());
 }
 
 
 int Message::GetEndColumn() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Message::GetEndColumn()")) return kNoColumnInfo;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> start_col_obj = CallV8HeapFunction(
       "GetPositionInLine",
       data_obj,
       &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(0);
+  EXCEPTION_BAILOUT_CHECK(isolate, 0);
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(data_obj);
   int start = message->start_position();
@@ -1745,15 +1741,15 @@
 
 
 Local<String> Message::GetSourceLine() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
                                                    Utils::OpenHandle(this),
                                                    &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::String>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
   if (result->IsString()) {
     return scope.Close(Utils::ToLocal(i::Handle<i::String>::cast(result)));
   } else {
@@ -1765,7 +1761,7 @@
 void Message::PrintCurrentStackTrace(FILE* out) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::Message::PrintCurrentStackTrace()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   isolate->PrintCurrentStackTrace(out);
 }
 
@@ -1773,11 +1769,11 @@
 // --- S t a c k T r a c e ---
 
 Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackTrace::GetFrame()")) {
     return Local<StackFrame>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSArray> self = Utils::OpenHandle(this);
   i::Object* raw_object = self->GetElementNoExceptionThrown(index);
@@ -1787,17 +1783,17 @@
 
 
 int StackTrace::GetFrameCount() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackTrace::GetFrameCount()")) return -1;
-  ENTER_V8;
+  ENTER_V8(isolate);
   return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
 }
 
 
 Local<Array> StackTrace::AsArray() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackTrace::AsArray()")) Local<Array>();
-  ENTER_V8;
+  ENTER_V8(isolate);
   return Utils::ToLocal(Utils::OpenHandle(this));
 }
 
@@ -1808,7 +1804,7 @@
   if (IsDeadCheck(isolate, "v8::StackTrace::CurrentStackTrace()")) {
     Local<StackTrace>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSArray> stackTrace =
       isolate->CaptureCurrentStackTrace(frame_limit, options);
   return Utils::StackTraceToLocal(stackTrace);
@@ -1818,11 +1814,11 @@
 // --- S t a c k F r a m e ---
 
 int StackFrame::GetLineNumber() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::GetLineNumber()")) {
     return Message::kNoLineNumberInfo;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> line = GetProperty(self, "lineNumber");
@@ -1834,11 +1830,11 @@
 
 
 int StackFrame::GetColumn() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::GetColumn()")) {
     return Message::kNoColumnInfo;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> column = GetProperty(self, "column");
@@ -1850,11 +1846,11 @@
 
 
 Local<String> StackFrame::GetScriptName() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptName()")) {
     return Local<String>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> name = GetProperty(self, "scriptName");
@@ -1866,11 +1862,11 @@
 
 
 Local<String> StackFrame::GetScriptNameOrSourceURL() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::GetScriptNameOrSourceURL()")) {
     return Local<String>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
@@ -1882,11 +1878,11 @@
 
 
 Local<String> StackFrame::GetFunctionName() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::GetFunctionName()")) {
     return Local<String>();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> name = GetProperty(self, "functionName");
@@ -1898,9 +1894,9 @@
 
 
 bool StackFrame::IsEval() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::IsEval()")) return false;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> is_eval = GetProperty(self, "isEval");
@@ -1909,9 +1905,9 @@
 
 
 bool StackFrame::IsConstructor() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::StackFrame::IsConstructor()")) return false;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> is_constructor = GetProperty(self, "isConstructor");
@@ -2022,9 +2018,10 @@
 
 
 bool Value::IsDate() const {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsDate()")) return false;
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Value::IsDate()")) return false;
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
-  return obj->HasSpecificClassOf(HEAP->Date_symbol());
+  return obj->HasSpecificClassOf(isolate->heap()->Date_symbol());
 }
 
 
@@ -2036,74 +2033,76 @@
 
 
 Local<String> Value::ToString() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Value::ToString()")) {
-    return Local<String>();
-  }
-  LOG_API(isolate, "ToString");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> str;
   if (obj->IsString()) {
     str = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToString()")) {
+      return Local<String>();
+    }
+    LOG_API(isolate, "ToString");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     str = i::Execution::ToString(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<String>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
   }
   return Local<String>(ToApi<String>(str));
 }
 
 
 Local<String> Value::ToDetailString() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
-    return Local<String>();
-  }
-  LOG_API(isolate, "ToDetailString");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> str;
   if (obj->IsString()) {
     str = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToDetailString()")) {
+      return Local<String>();
+    }
+    LOG_API(isolate, "ToDetailString");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     str = i::Execution::ToDetailString(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<String>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
   }
   return Local<String>(ToApi<String>(str));
 }
 
 
 Local<v8::Object> Value::ToObject() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::ToObject()")) return Local<v8::Object>();
-  LOG_API(isolate, "ToObject");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> val;
   if (obj->IsJSObject()) {
     val = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToObject()")) {
+      return Local<v8::Object>();
+    }
+    LOG_API(isolate, "ToObject");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     val = i::Execution::ToObject(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
   }
   return Local<v8::Object>(ToApi<Object>(val));
 }
 
 
 Local<Boolean> Value::ToBoolean() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Value::ToBoolean()")) {
-    return Local<Boolean>();
-  }
-  LOG_API(isolate, "ToBoolean");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   if (obj->IsBoolean()) {
     return Local<Boolean>(ToApi<Boolean>(obj));
   } else {
-    ENTER_V8;
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToBoolean()")) {
+      return Local<Boolean>();
+    }
+    LOG_API(isolate, "ToBoolean");
+    ENTER_V8(isolate);
     i::Handle<i::Object> val = i::Execution::ToBoolean(obj);
     return Local<Boolean>(ToApi<Boolean>(val));
   }
@@ -2111,36 +2110,38 @@
 
 
 Local<Number> Value::ToNumber() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) return Local<Number>();
-  LOG_API(isolate, "ToNumber");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsNumber()) {
     num = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToNumber()")) {
+      return Local<Number>();
+    }
+    LOG_API(isolate, "ToNumber");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     num = i::Execution::ToNumber(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<Number>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
   }
   return Local<Number>(ToApi<Number>(num));
 }
 
 
 Local<Integer> Value::ToInteger() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
-  LOG_API(isolate, "ToInteger");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsSmi()) {
     num = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToInteger()")) return Local<Integer>();
+    LOG_API(isolate, "ToInteger");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     num = i::Execution::ToInteger(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<Integer>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
   }
   return Local<Integer>(ToApi<Integer>(num));
 }
@@ -2210,9 +2211,10 @@
 
 
 void v8::Date::CheckCast(v8::Value* that) {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Date::Cast()")) return;
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Date::Cast()")) return;
   i::Handle<i::Object> obj = Utils::OpenHandle(that);
-  ApiCheck(obj->HasSpecificClassOf(HEAP->Date_symbol()),
+  ApiCheck(obj->HasSpecificClassOf(isolate->heap()->Date_symbol()),
            "v8::Date::Cast()",
            "Could not convert to date");
 }
@@ -2228,14 +2230,14 @@
 
 
 bool Value::BooleanValue() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
-  LOG_API(isolate, "BooleanValue");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   if (obj->IsBoolean()) {
     return obj->IsTrue();
   } else {
-    ENTER_V8;
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::BooleanValue()")) return false;
+    LOG_API(isolate, "BooleanValue");
+    ENTER_V8(isolate);
     i::Handle<i::Object> value = i::Execution::ToBoolean(obj);
     return value->IsTrue();
   }
@@ -2243,38 +2245,38 @@
 
 
 double Value::NumberValue() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
-    return i::OS::nan_value();
-  }
-  LOG_API(isolate, "NumberValue");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsNumber()) {
     num = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::NumberValue()")) {
+      return i::OS::nan_value();
+    }
+    LOG_API(isolate, "NumberValue");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     num = i::Execution::ToNumber(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(i::OS::nan_value());
+    EXCEPTION_BAILOUT_CHECK(isolate, i::OS::nan_value());
   }
   return num->Number();
 }
 
 
 int64_t Value::IntegerValue() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
-  LOG_API(isolate, "IntegerValue");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsNumber()) {
     num = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::IntegerValue()")) return 0;
+    LOG_API(isolate, "IntegerValue");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     num = i::Execution::ToInteger(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(0);
+    EXCEPTION_BAILOUT_CHECK(isolate, 0);
   }
   if (num->IsSmi()) {
     return i::Smi::cast(*num)->value();
@@ -2285,55 +2287,55 @@
 
 
 Local<Int32> Value::ToInt32() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
-  LOG_API(isolate, "ToInt32");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsSmi()) {
     num = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToInt32()")) return Local<Int32>();
+    LOG_API(isolate, "ToInt32");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     num = i::Execution::ToInt32(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<Int32>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
   }
   return Local<Int32>(ToApi<Int32>(num));
 }
 
 
 Local<Uint32> Value::ToUint32() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
-  LOG_API(isolate, "ToUInt32");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsSmi()) {
     num = obj;
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::ToUint32()")) return Local<Uint32>();
+    LOG_API(isolate, "ToUInt32");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     num = i::Execution::ToUint32(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<Uint32>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
   }
   return Local<Uint32>(ToApi<Uint32>(num));
 }
 
 
 Local<Uint32> Value::ToArrayIndex() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
-  LOG_API(isolate, "ToArrayIndex");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   if (obj->IsSmi()) {
     if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
     return Local<Uint32>();
   }
-  ENTER_V8;
-  EXCEPTION_PREAMBLE();
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Value::ToArrayIndex()")) return Local<Uint32>();
+  LOG_API(isolate, "ToArrayIndex");
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> string_obj =
       i::Execution::ToString(obj, &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<Uint32>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
   i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
   uint32_t index;
   if (str->AsArrayIndex(&index)) {
@@ -2350,19 +2352,18 @@
 
 
 int32_t Value::Int32Value() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
-  LOG_API(isolate, "Int32Value");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   if (obj->IsSmi()) {
     return i::Smi::cast(*obj)->value();
   } else {
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::Int32Value()")) return 0;
     LOG_API(isolate, "Int32Value (slow)");
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     i::Handle<i::Object> num =
         i::Execution::ToInt32(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(0);
+    EXCEPTION_BAILOUT_CHECK(isolate, 0);
     if (num->IsSmi()) {
       return i::Smi::cast(*num)->value();
     } else {
@@ -2380,7 +2381,7 @@
     return false;
   }
   LOG_API(isolate, "Equals");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> other = Utils::OpenHandle(*that);
   // If both obj and other are JSObjects, we'd better compare by identity
@@ -2390,10 +2391,10 @@
     return *obj == *other;
   }
   i::Object** args[1] = { other.location() };
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result =
       CallV8HeapFunction("EQUALS", obj, 1, args, &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
   return *result == i::Smi::FromInt(i::EQUAL);
 }
 
@@ -2431,18 +2432,18 @@
 
 
 uint32_t Value::Uint32Value() const {
-  i::Isolate* isolate = i::Isolate::Current();
-  if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
-  LOG_API(isolate, "Uint32Value");
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   if (obj->IsSmi()) {
     return i::Smi::cast(*obj)->value();
   } else {
-    ENTER_V8;
-    EXCEPTION_PREAMBLE();
+    i::Isolate* isolate = i::Isolate::Current();
+    if (IsDeadCheck(isolate, "v8::Value::Uint32Value()")) return 0;
+    LOG_API(isolate, "Uint32Value");
+    ENTER_V8(isolate);
+    EXCEPTION_PREAMBLE(isolate);
     i::Handle<i::Object> num =
         i::Execution::ToUint32(obj, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(0);
+    EXCEPTION_BAILOUT_CHECK(isolate, 0);
     if (num->IsSmi()) {
       return i::Smi::cast(*num)->value();
     } else {
@@ -2454,14 +2455,14 @@
 
 bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value,
                      v8::PropertyAttribute attribs) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::Set()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::Object> self = Utils::OpenHandle(this);
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj = i::SetProperty(
       self,
       key_obj,
@@ -2469,26 +2470,26 @@
       static_cast<PropertyAttributes>(attribs),
       i::kNonStrictMode);
   has_pending_exception = obj.is_null();
-  EXCEPTION_BAILOUT_CHECK(false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
   return true;
 }
 
 
 bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::Set()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj = i::SetElement(
       self,
       index,
       value_obj,
       i::kNonStrictMode);
   has_pending_exception = obj.is_null();
-  EXCEPTION_BAILOUT_CHECK(false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
   return true;
 }
 
@@ -2496,29 +2497,29 @@
 bool v8::Object::ForceSet(v8::Handle<Value> key,
                           v8::Handle<Value> value,
                           v8::PropertyAttribute attribs) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj = i::ForceSetProperty(
       self,
       key_obj,
       value_obj,
       static_cast<PropertyAttributes>(attribs));
   has_pending_exception = obj.is_null();
-  EXCEPTION_BAILOUT_CHECK(false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
   return true;
 }
 
 
 bool v8::Object::ForceDelete(v8::Handle<Value> key) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
@@ -2527,45 +2528,46 @@
   // as optimized code does not always handle access checks.
   i::Deoptimizer::DeoptimizeGlobalObject(*self);
 
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
   has_pending_exception = obj.is_null();
-  EXCEPTION_BAILOUT_CHECK(false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
   return obj->IsTrue();
 }
 
 
 Local<Value> v8::Object::Get(v8::Handle<Value> key) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> self = Utils::OpenHandle(this);
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result = i::GetProperty(self, key_obj);
   has_pending_exception = result.is_null();
-  EXCEPTION_BAILOUT_CHECK(Local<Value>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   return Utils::ToLocal(result);
 }
 
 
 Local<Value> v8::Object::Get(uint32_t index) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result = i::GetElement(self, index);
   has_pending_exception = result.is_null();
-  EXCEPTION_BAILOUT_CHECK(Local<Value>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   return Utils::ToLocal(result);
 }
 
 
 Local<Value> v8::Object::GetPrototype() {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::GetPrototype()",
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::GetPrototype()",
              return Local<v8::Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> self = Utils::OpenHandle(this);
   i::Handle<i::Object> result = i::GetPrototype(self);
   return Utils::ToLocal(result);
@@ -2573,25 +2575,26 @@
 
 
 bool v8::Object::SetPrototype(Handle<Value> value) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
   has_pending_exception = result.is_null();
-  EXCEPTION_BAILOUT_CHECK(false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
   return true;
 }
 
 
 Local<Object> v8::Object::FindInstanceInPrototypeChain(
     v8::Handle<FunctionTemplate> tmpl) {
-  ON_BAILOUT(i::Isolate::Current(),
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate,
              "v8::Object::FindInstanceInPrototypeChain()",
              return Local<v8::Object>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::JSObject* object = *Utils::OpenHandle(this);
   i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
   while (!object->IsInstanceOf(tmpl_info)) {
@@ -2604,11 +2607,11 @@
 
 
 Local<Array> v8::Object::GetPropertyNames() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
              return Local<v8::Array>());
-  ENTER_V8;
-  v8::HandleScope scope;
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::FixedArray> value =
       i::GetKeysInFixedArrayFor(self, i::INCLUDE_PROTOS);
@@ -2618,14 +2621,15 @@
   i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
   i::Handle<i::JSArray> result =
       isolate->factory()->NewJSArrayWithElements(elms);
-  return scope.Close(Utils::ToLocal(result));
+  return Utils::ToLocal(scope.CloseAndEscape(result));
 }
 
 
 Local<String> v8::Object::ObjectProtoToString() {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::ObjectProtoToString()",
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::ObjectProtoToString()",
              return Local<v8::String>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
 
   i::Handle<i::Object> name(self->class_name());
@@ -2676,10 +2680,10 @@
 
 
 Local<String> v8::Object::GetConstructorName() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
              return Local<v8::String>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::String> name(self->constructor_name());
   return Utils::ToLocal(name);
@@ -2687,9 +2691,9 @@
 
 
 bool v8::Object::Delete(v8::Handle<String> key) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
@@ -2698,8 +2702,9 @@
 
 
 bool v8::Object::Has(v8::Handle<String> key) {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::Has()", return false);
-  ENTER_V8;
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::Has()", return false);
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   return self->HasProperty(*key_obj);
@@ -2707,9 +2712,10 @@
 
 
 bool v8::Object::Delete(uint32_t index) {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::DeleteProperty()",
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
              return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   return i::DeleteElement(self, index)->IsTrue();
@@ -2717,7 +2723,8 @@
 
 
 bool v8::Object::Has(uint32_t index) {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasProperty()", return false);
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   return self->HasElement(index);
 }
@@ -2729,9 +2736,9 @@
                          v8::Handle<Value> data,
                          AccessControl settings,
                          PropertyAttribute attributes) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::AccessorInfo> info = MakeAccessorInfo(name,
                                                      getter, setter, data,
@@ -2742,7 +2749,8 @@
 
 
 bool v8::Object::HasRealNamedProperty(Handle<String> key) {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasRealNamedProperty()",
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
              return false);
   return Utils::OpenHandle(this)->HasRealNamedProperty(
       *Utils::OpenHandle(*key));
@@ -2750,31 +2758,35 @@
 
 
 bool v8::Object::HasRealIndexedProperty(uint32_t index) {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasRealIndexedProperty()",
+  ON_BAILOUT(Utils::OpenHandle(this)->GetIsolate(),
+             "v8::Object::HasRealIndexedProperty()",
              return false);
   return Utils::OpenHandle(this)->HasRealElementProperty(index);
 }
 
 
 bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
-  ON_BAILOUT(i::Isolate::Current(),
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate,
              "v8::Object::HasRealNamedCallbackProperty()",
              return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   return Utils::OpenHandle(this)->HasRealNamedCallbackProperty(
       *Utils::OpenHandle(*key));
 }
 
 
 bool v8::Object::HasNamedLookupInterceptor() {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasNamedLookupInterceptor()",
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
              return false);
   return Utils::OpenHandle(this)->HasNamedInterceptor();
 }
 
 
 bool v8::Object::HasIndexedLookupInterceptor() {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::HasIndexedLookupInterceptor()",
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
              return false);
   return Utils::OpenHandle(this)->HasIndexedInterceptor();
 }
@@ -2782,10 +2794,11 @@
 
 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
       Handle<String> key) {
-  ON_BAILOUT(i::Isolate::Current(),
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate,
              "v8::Object::GetRealNamedPropertyInPrototypeChain()",
              return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::LookupResult lookup;
@@ -2805,9 +2818,10 @@
 
 
 Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
-  ON_BAILOUT(i::Isolate::Current(), "v8::Object::GetRealNamedProperty()",
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
              return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
   i::LookupResult lookup;
@@ -2830,9 +2844,9 @@
 // Because the object gets a new map, existing inline cache caching
 // the old map of this object will fail.
 void v8::Object::TurnOnAccessCheck() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
 
@@ -2841,7 +2855,7 @@
   i::Deoptimizer::DeoptimizeGlobalObject(*obj);
 
   i::Handle<i::Map> new_map =
-    isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
+      isolate->factory()->CopyMapDropTransitions(i::Handle<i::Map>(obj->map()));
   new_map->set_is_access_check_needed(true);
   obj->set_map(*new_map);
 }
@@ -2853,22 +2867,22 @@
 
 
 Local<v8::Object> v8::Object::Clone() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::JSObject> result = i::Copy(self);
   has_pending_exception = result.is_null();
-  EXCEPTION_BAILOUT_CHECK(Local<Object>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
   return Utils::ToLocal(result);
 }
 
 
 int v8::Object::GetIdentityHash() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> hidden_props_obj(i::GetHiddenProperties(self, true));
@@ -2909,15 +2923,15 @@
 
 bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
                                 v8::Handle<v8::Value> value) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, true));
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj = i::SetProperty(
       hidden_props,
       key_obj,
@@ -2925,26 +2939,26 @@
       static_cast<PropertyAttributes>(None),
       i::kNonStrictMode);
   has_pending_exception = obj.is_null();
-  EXCEPTION_BAILOUT_CHECK(false);
+  EXCEPTION_BAILOUT_CHECK(isolate, false);
   return true;
 }
 
 
 v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
              return Local<v8::Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
   if (hidden_props->IsUndefined()) {
     return v8::Local<v8::Value>();
   }
   i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
   has_pending_exception = result.is_null();
-  EXCEPTION_BAILOUT_CHECK(v8::Local<v8::Value>());
+  EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
   if (result->IsUndefined()) {
     return v8::Local<v8::Value>();
   }
@@ -2953,9 +2967,9 @@
 
 
 bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> hidden_props(i::GetHiddenProperties(self, false));
@@ -2974,21 +2988,24 @@
                                   void* data,
                                   ExternalArrayType array_type,
                                   int length) {
+  i::Isolate* isolate = object->GetIsolate();
   i::Handle<i::ExternalArray> array =
-      FACTORY->NewExternalArray(length, array_type, data);
+      isolate->factory()->NewExternalArray(length, array_type, data);
 
   // If the object already has external elements, create a new, unique
   // map if the element type is now changing, because assumptions about
   // generated code based on the receiver's map will be invalid.
   i::Handle<i::HeapObject> elements(object->elements());
-  bool force_unique_map =
+  bool cant_reuse_map =
       elements->map()->IsUndefined() ||
       !elements->map()->has_external_array_elements() ||
-      elements->map() != HEAP->MapForExternalArrayType(array_type);
-  if (force_unique_map) {
+      elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
+  if (cant_reuse_map) {
     i::Handle<i::Map> external_array_map =
-        FACTORY->NewExternalArrayElementsMap(
-            i::Handle<i::Map>(object->map()));
+        isolate->factory()->GetExternalArrayElementsMap(
+            i::Handle<i::Map>(object->map()),
+            array_type,
+            object->HasFastProperties());
     object->set_map(*external_array_map);
   }
   object->set_elements(*array);
@@ -2998,9 +3015,9 @@
 
 
 void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
                 "v8::Object::SetIndexedPropertiesToPixelData()",
@@ -3018,17 +3035,17 @@
 
 
 bool v8::Object::HasIndexedPropertiesInPixelData() {
-  ON_BAILOUT(i::Isolate::Current(), "v8::HasIndexedPropertiesInPixelData()",
-             return false);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
+             return false);
   return self->HasExternalPixelElements();
 }
 
 
 uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
-  ON_BAILOUT(i::Isolate::Current(), "v8::GetIndexedPropertiesPixelData()",
-             return NULL);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
+             return NULL);
   if (self->HasExternalPixelElements()) {
     return i::ExternalPixelArray::cast(self->elements())->
         external_pixel_pointer();
@@ -3039,9 +3056,9 @@
 
 
 int v8::Object::GetIndexedPropertiesPixelDataLength() {
-  ON_BAILOUT(i::Isolate::Current(), "v8::GetIndexedPropertiesPixelDataLength()",
-             return -1);
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
+             return -1);
   if (self->HasExternalPixelElements()) {
     return i::ExternalPixelArray::cast(self->elements())->length();
   } else {
@@ -3053,9 +3070,9 @@
     void* data,
     ExternalArrayType array_type,
     int length) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
                 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
@@ -3073,19 +3090,19 @@
 
 
 bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
-  ON_BAILOUT(i::Isolate::Current(),
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  ON_BAILOUT(self->GetIsolate(),
              "v8::HasIndexedPropertiesInExternalArrayData()",
              return false);
-  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   return self->HasExternalArrayElements();
 }
 
 
 void* v8::Object::GetIndexedPropertiesExternalArrayData() {
-  ON_BAILOUT(i::Isolate::Current(),
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  ON_BAILOUT(self->GetIsolate(),
              "v8::GetIndexedPropertiesExternalArrayData()",
              return NULL);
-  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   if (self->HasExternalArrayElements()) {
     return i::ExternalArray::cast(self->elements())->external_pointer();
   } else {
@@ -3095,10 +3112,10 @@
 
 
 ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
-  ON_BAILOUT(i::Isolate::Current(),
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  ON_BAILOUT(self->GetIsolate(),
              "v8::GetIndexedPropertiesExternalArrayDataType()",
              return static_cast<ExternalArrayType>(-1));
-  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   switch (self->elements()->map()->instance_type()) {
     case i::EXTERNAL_BYTE_ARRAY_TYPE:
       return kExternalByteArray;
@@ -3123,10 +3140,10 @@
 
 
 int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
-  ON_BAILOUT(i::Isolate::Current(),
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  ON_BAILOUT(self->GetIsolate(),
              "v8::GetIndexedPropertiesExternalArrayDataLength()",
              return 0);
-  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   if (self->HasExternalArrayElements()) {
     return i::ExternalArray::cast(self->elements())->length();
   } else {
@@ -3142,29 +3159,29 @@
 
 Local<v8::Object> Function::NewInstance(int argc,
                                         v8::Handle<v8::Value> argv[]) const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Function::NewInstance()",
              return Local<v8::Object>());
   LOG_API(isolate, "Function::NewInstance");
-  ENTER_V8;
+  ENTER_V8(isolate);
   HandleScope scope;
   i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
   STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
   i::Object*** args = reinterpret_cast<i::Object***>(argv);
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> returned =
       i::Execution::New(function, argc, args, &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
   return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
 }
 
 
 Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
                                 v8::Handle<v8::Value> argv[]) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
   LOG_API(isolate, "Function::Call");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* raw_result = NULL;
   {
     i::HandleScope scope(isolate);
@@ -3172,10 +3189,10 @@
     i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
     STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
     i::Object*** args = reinterpret_cast<i::Object***>(argv);
-    EXCEPTION_PREAMBLE();
+    EXCEPTION_PREAMBLE(isolate);
     i::Handle<i::Object> returned =
         i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
-    EXCEPTION_BAILOUT_CHECK(Local<Object>());
+    EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
     raw_result = *returned;
   }
   i::Handle<i::Object> result(raw_result);
@@ -3184,7 +3201,8 @@
 
 
 void Function::SetName(v8::Handle<v8::String> name) {
-  ENTER_V8;
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ENTER_V8(isolate);
   i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
   func->shared()->set_name(*Utils::OpenHandle(*name));
 }
@@ -3224,14 +3242,16 @@
 
 
 int String::Length() const {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::String::Length()")) return 0;
-  return Utils::OpenHandle(this)->length();
+  i::Handle<i::String> str = Utils::OpenHandle(this);
+  if (IsDeadCheck(str->GetIsolate(), "v8::String::Length()")) return 0;
+  return str->length();
 }
 
 
 int String::Utf8Length() const {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::String::Utf8Length()")) return 0;
-  return Utils::OpenHandle(this)->Utf8Length();
+  i::Handle<i::String> str = Utils::OpenHandle(this);
+  if (IsDeadCheck(str->GetIsolate(), "v8::String::Utf8Length()")) return 0;
+  return str->Utf8Length();
 }
 
 
@@ -3239,10 +3259,10 @@
                       int capacity,
                       int* nchars_ref,
                       WriteHints hints) const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
   LOG_API(isolate, "String::WriteUtf8");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
   i::Handle<i::String> str = Utils::OpenHandle(this);
   isolate->string_tracker()->RecordWrite(str);
@@ -3296,10 +3316,10 @@
                        int start,
                        int length,
                        WriteHints hints) const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
   LOG_API(isolate, "String::WriteAscii");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
   ASSERT(start >= 0 && length >= -1);
   i::Handle<i::String> str = Utils::OpenHandle(this);
@@ -3330,10 +3350,10 @@
                   int start,
                   int length,
                   WriteHints hints) const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
   LOG_API(isolate, "String::Write");
-  ENTER_V8;
+  ENTER_V8(isolate);
   ASSERT(start >= 0 && length >= -1);
   i::Handle<i::String> str = Utils::OpenHandle(this);
   isolate->string_tracker()->RecordWrite(str);
@@ -3355,15 +3375,20 @@
 
 
 bool v8::String::IsExternal() const {
-  EnsureInitialized("v8::String::IsExternal()");
   i::Handle<i::String> str = Utils::OpenHandle(this);
+  if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternal()")) {
+    return false;
+  }
+  EnsureInitializedForIsolate(str->GetIsolate(), "v8::String::IsExternal()");
   return i::StringShape(*str).IsExternalTwoByte();
 }
 
 
 bool v8::String::IsExternalAscii() const {
-  EnsureInitialized("v8::String::IsExternalAscii()");
   i::Handle<i::String> str = Utils::OpenHandle(this);
+  if (IsDeadCheck(str->GetIsolate(), "v8::String::IsExternalAscii()")) {
+    return false;
+  }
   return i::StringShape(*str).IsExternalAscii();
 }
 
@@ -3384,8 +3409,11 @@
 
 v8::String::ExternalAsciiStringResource*
       v8::String::GetExternalAsciiStringResource() const {
-  EnsureInitialized("v8::String::GetExternalAsciiStringResource()");
   i::Handle<i::String> str = Utils::OpenHandle(this);
+  if (IsDeadCheck(str->GetIsolate(),
+                  "v8::String::GetExternalAsciiStringResource()")) {
+    return NULL;
+  }
   if (i::StringShape(*str).IsExternalAscii()) {
     void* resource = i::Handle<i::ExternalAsciiString>::cast(str)->resource();
     return reinterpret_cast<ExternalAsciiStringResource*>(resource);
@@ -3443,19 +3471,19 @@
 
 
 int v8::Object::InternalFieldCount() {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Object::InternalFieldCount()")) {
+  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+  if (IsDeadCheck(obj->GetIsolate(), "v8::Object::InternalFieldCount()")) {
     return 0;
   }
-  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   return obj->GetInternalFieldCount();
 }
 
 
 Local<Value> v8::Object::CheckedGetInternalField(int index) {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Object::GetInternalField()")) {
+  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+  if (IsDeadCheck(obj->GetIsolate(), "v8::Object::GetInternalField()")) {
     return Local<Value>();
   }
-  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   if (!ApiCheck(index < obj->GetInternalFieldCount(),
                 "v8::Object::GetInternalField()",
                 "Reading internal field out of bounds")) {
@@ -3472,16 +3500,17 @@
 
 
 void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Object::SetInternalField()")) {
+  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+  i::Isolate* isolate = obj->GetIsolate();
+  if (IsDeadCheck(isolate, "v8::Object::SetInternalField()")) {
     return;
   }
-  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
   if (!ApiCheck(index < obj->GetInternalFieldCount(),
                 "v8::Object::SetInternalField()",
                 "Writing internal field out of bounds")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> val = Utils::OpenHandle(*value);
   obj->SetInternalField(index, *val);
 }
@@ -3505,13 +3534,15 @@
 
 
 void v8::Object::SetPointerInInternalField(int index, void* value) {
-  ENTER_V8;
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ENTER_V8(isolate);
   if (CanBeEncodedAsSmi(value)) {
     Utils::OpenHandle(this)->SetInternalField(index, EncodeAsSmi(value));
   } else {
     HandleScope scope;
     i::Handle<i::Proxy> proxy =
-        FACTORY->NewProxy(reinterpret_cast<i::Address>(value), i::TENURED);
+        isolate->factory()->NewProxy(
+            reinterpret_cast<i::Address>(value), i::TENURED);
     if (!proxy.is_null())
         Utils::OpenHandle(this)->SetInternalField(index, *proxy);
   }
@@ -3550,11 +3581,12 @@
 
 
 void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
-  heap_statistics->set_total_heap_size(HEAP->CommittedMemory());
+  i::Heap* heap = i::Isolate::Current()->heap();
+  heap_statistics->set_total_heap_size(heap->CommittedMemory());
   heap_statistics->set_total_heap_size_executable(
-      HEAP->CommittedMemoryExecutable());
-  heap_statistics->set_used_heap_size(HEAP->SizeOfObjects());
-  heap_statistics->set_heap_size_limit(HEAP->MaxReserved());
+      heap->CommittedMemoryExecutable());
+  heap_statistics->set_used_heap_size(heap->SizeOfObjects());
+  heap_statistics->set_heap_size_limit(heap->MaxReserved());
 }
 
 
@@ -3567,14 +3599,16 @@
 
 
 void v8::V8::LowMemoryNotification() {
-  if (!i::Isolate::Current()->IsInitialized()) return;
-  HEAP->CollectAllGarbage(true);
+  i::Isolate* isolate = i::Isolate::Current();
+  if (!isolate->IsInitialized()) return;
+  isolate->heap()->CollectAllGarbage(true);
 }
 
 
 int v8::V8::ContextDisposedNotification() {
-  if (!i::Isolate::Current()->IsInitialized()) return 0;
-  return HEAP->NotifyContextDisposed();
+  i::Isolate* isolate = i::Isolate::Current();
+  if (!isolate->IsInitialized()) return 0;
+  return isolate->heap()->NotifyContextDisposed();
 }
 
 
@@ -3607,7 +3641,7 @@
   // Enter V8 via an ENTER_V8 scope.
   i::Handle<i::Context> env;
   {
-    ENTER_V8;
+    ENTER_V8(isolate);
     v8::Handle<ObjectTemplate> proxy_template = global_template;
     i::Handle<i::FunctionTemplateInfo> proxy_constructor;
     i::Handle<i::FunctionTemplateInfo> global_constructor;
@@ -3636,7 +3670,8 @@
         proxy_constructor->set_needs_access_check(
             global_constructor->needs_access_check());
         global_constructor->set_needs_access_check(false);
-        global_constructor->set_access_check_info(HEAP->undefined_value());
+        global_constructor->set_access_check_info(
+            isolate->heap()->undefined_value());
       }
     }
 
@@ -3655,7 +3690,7 @@
       global_constructor->set_needs_access_check(
           proxy_constructor->needs_access_check());
     }
-    i::Isolate::Current()->runtime_profiler()->Reset();
+    isolate->runtime_profiler()->Reset();
   }
   // Leave V8.
 
@@ -3666,10 +3701,11 @@
 
 
 void v8::Context::SetSecurityToken(Handle<Value> token) {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Context::SetSecurityToken()")) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Context::SetSecurityToken()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Context> env = Utils::OpenHandle(this);
   i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
   env->set_security_token(*token_handle);
@@ -3677,18 +3713,20 @@
 
 
 void v8::Context::UseDefaultSecurityToken() {
-  if (IsDeadCheck(i::Isolate::Current(),
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate,
                   "v8::Context::UseDefaultSecurityToken()")) {
     return;
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Context> env = Utils::OpenHandle(this);
   env->set_security_token(env->global());
 }
 
 
 Handle<Value> v8::Context::GetSecurityToken() {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetSecurityToken()")) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Context::GetSecurityToken()")) {
     return Handle<Value>();
   }
   i::Handle<i::Context> env = Utils::OpenHandle(this);
@@ -3710,11 +3748,12 @@
 
 
 v8::Local<v8::Context> Context::GetEntered() {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetEntered()")) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
     return Local<Context>();
   }
   i::Handle<i::Object> last =
-      i::Isolate::Current()->handle_scope_implementer()->LastEnteredContext();
+      isolate->handle_scope_implementer()->LastEnteredContext();
   if (last.is_null()) return Local<Context>();
   i::Handle<i::Context> context = i::Handle<i::Context>::cast(last);
   return Utils::ToLocal(context);
@@ -3722,10 +3761,11 @@
 
 
 v8::Local<v8::Context> Context::GetCurrent() {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetCurrent()")) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Context::GetCurrent()")) {
     return Local<Context>();
   }
-  i::Handle<i::Object> current = i::Isolate::Current()->global_context();
+  i::Handle<i::Object> current = isolate->global_context();
   if (current.is_null()) return Local<Context>();
   i::Handle<i::Context> context = i::Handle<i::Context>::cast(current);
   return Utils::ToLocal(context);
@@ -3733,11 +3773,12 @@
 
 
 v8::Local<v8::Context> Context::GetCalling() {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Context::GetCalling()")) {
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Context::GetCalling()")) {
     return Local<Context>();
   }
   i::Handle<i::Object> calling =
-      i::Isolate::Current()->GetCallingGlobalContext();
+      isolate->GetCallingGlobalContext();
   if (calling.is_null()) return Local<Context>();
   i::Handle<i::Context> context = i::Handle<i::Context>::cast(calling);
   return Utils::ToLocal(context);
@@ -3757,19 +3798,20 @@
 
 
 void Context::DetachGlobal() {
-  if (IsDeadCheck(i::Isolate::Current(), "v8::Context::DetachGlobal()")) return;
-  ENTER_V8;
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::Context::DetachGlobal()")) return;
+  ENTER_V8(isolate);
   i::Object** ctx = reinterpret_cast<i::Object**>(this);
   i::Handle<i::Context> context =
       i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
-  i::Isolate::Current()->bootstrapper()->DetachGlobal(context);
+  isolate->bootstrapper()->DetachGlobal(context);
 }
 
 
 void Context::ReattachGlobal(Handle<Object> global_object) {
   i::Isolate* isolate = i::Isolate::Current();
   if (IsDeadCheck(isolate, "v8::Context::ReattachGlobal()")) return;
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object** ctx = reinterpret_cast<i::Object**>(this);
   i::Handle<i::Context> context =
       i::Handle<i::Context>::cast(i::Handle<i::Object>(ctx));
@@ -3789,12 +3831,12 @@
   ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
              return Local<v8::Object>());
   LOG_API(isolate, "ObjectTemplate::NewInstance");
-  ENTER_V8;
-  EXCEPTION_PREAMBLE();
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj =
       i::Execution::InstantiateObject(Utils::OpenHandle(this),
                                       &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::Object>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
   return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
 }
 
@@ -3804,12 +3846,12 @@
   ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
              return Local<v8::Function>());
   LOG_API(isolate, "FunctionTemplate::GetFunction");
-  ENTER_V8;
-  EXCEPTION_PREAMBLE();
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj =
       i::Execution::InstantiateFunction(Utils::OpenHandle(this),
                                         &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::Function>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
   return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
 }
 
@@ -3836,7 +3878,7 @@
   STATIC_ASSERT(sizeof(data) == sizeof(i::Address));
   LOG_API(isolate, "External::Wrap");
   EnsureInitializedForIsolate(isolate, "v8::External::Wrap()");
-  ENTER_V8;
+  ENTER_V8(isolate);
 
   v8::Local<v8::Value> result = CanBeEncodedAsSmi(data)
       ? Utils::ToLocal(i::Handle<i::Object>(EncodeAsSmi(data)))
@@ -3881,7 +3923,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "External::New");
   EnsureInitializedForIsolate(isolate, "v8::External::New()");
-  ENTER_V8;
+  ENTER_V8(isolate);
   return ExternalNewImpl(data);
 }
 
@@ -3906,7 +3948,7 @@
   EnsureInitializedForIsolate(isolate, "v8::String::New()");
   LOG_API(isolate, "String::New(char)");
   if (length == 0) return Empty();
-  ENTER_V8;
+  ENTER_V8(isolate);
   if (length == -1) length = i::StrLength(data);
   i::Handle<i::String> result =
       isolate->factory()->NewStringFromUtf8(
@@ -3918,9 +3960,9 @@
 Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
   i::Handle<i::String> left_string = Utils::OpenHandle(*left);
   i::Isolate* isolate = left_string->GetIsolate();
-  EnsureInitializedForIsolate(isolate, "v8::String::Concat()");
-  LOG_API(isolate, "String::Concat()");
-  ENTER_V8;
+  EnsureInitializedForIsolate(isolate, "v8::String::New()");
+  LOG_API(isolate, "String::New(char)");
+  ENTER_V8(isolate);
   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
   i::Handle<i::String> result = isolate->factory()->NewConsString(left_string,
                                                                   right_string);
@@ -3932,7 +3974,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
   LOG_API(isolate, "String::NewUndetectable(char)");
-  ENTER_V8;
+  ENTER_V8(isolate);
   if (length == -1) length = i::StrLength(data);
   i::Handle<i::String> result =
       isolate->factory()->NewStringFromUtf8(
@@ -3954,7 +3996,7 @@
   EnsureInitializedForIsolate(isolate, "v8::String::New()");
   LOG_API(isolate, "String::New(uint16_)");
   if (length == 0) return Empty();
-  ENTER_V8;
+  ENTER_V8(isolate);
   if (length == -1) length = TwoByteStringLength(data);
   i::Handle<i::String> result =
       isolate->factory()->NewStringFromTwoByte(
@@ -3967,7 +4009,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::String::NewUndetectable()");
   LOG_API(isolate, "String::NewUndetectable(uint16_)");
-  ENTER_V8;
+  ENTER_V8(isolate);
   if (length == -1) length = TwoByteStringLength(data);
   i::Handle<i::String> result =
       isolate->factory()->NewStringFromTwoByte(
@@ -3998,7 +4040,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
   LOG_API(isolate, "String::NewExternal");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
   isolate->heap()->external_string_table()->AddString(*result);
   return Utils::ToLocal(result);
@@ -4009,8 +4051,10 @@
   i::Handle<i::String> obj = Utils::OpenHandle(this);
   i::Isolate* isolate = obj->GetIsolate();
   if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
-  if (this->IsExternal()) return false;  // Already an external string.
-  ENTER_V8;
+  if (i::StringShape(*obj).IsExternalTwoByte()) {
+    return false;  // Already an external string.
+  }
+  ENTER_V8(isolate);
   if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
     return false;
   }
@@ -4027,7 +4071,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::String::NewExternal()");
   LOG_API(isolate, "String::NewExternal");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
   isolate->heap()->external_string_table()->AddString(*result);
   return Utils::ToLocal(result);
@@ -4039,8 +4083,10 @@
   i::Handle<i::String> obj = Utils::OpenHandle(this);
   i::Isolate* isolate = obj->GetIsolate();
   if (IsDeadCheck(isolate, "v8::String::MakeExternal()")) return false;
-  if (this->IsExternal()) return false;  // Already an external string.
-  ENTER_V8;
+  if (i::StringShape(*obj).IsExternalTwoByte()) {
+    return false;  // Already an external string.
+  }
+  ENTER_V8(isolate);
   if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
     return false;
   }
@@ -4071,9 +4117,9 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Object::New()");
   LOG_API(isolate, "Object::New");
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> obj =
-      isolate->factory()->NewJSObject(i::Isolate::Current()->object_function());
+      isolate->factory()->NewJSObject(isolate->object_function());
   return Utils::ToLocal(obj);
 }
 
@@ -4086,11 +4132,11 @@
     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
     time = i::OS::nan_value();
   }
-  ENTER_V8;
-  EXCEPTION_PREAMBLE();
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj =
       i::Execution::NewDate(time, &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::Value>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Value>());
   return Utils::ToLocal(obj);
 }
 
@@ -4110,7 +4156,7 @@
   ON_BAILOUT(isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
              return);
   LOG_API(isolate, "Date::DateTimeConfigurationChangeNotification");
-  ENTER_V8;
+  ENTER_V8(isolate);
 
   i::HandleScope scope(isolate);
   // Get the function ResetDateCache (defined in date-delay.js).
@@ -4150,22 +4196,22 @@
 
 Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
                                   Flags flags) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
   EnsureInitializedForIsolate(isolate, "v8::RegExp::New()");
   LOG_API(isolate, "RegExp::New");
-  ENTER_V8;
-  EXCEPTION_PREAMBLE();
+  ENTER_V8(isolate);
+  EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
       Utils::OpenHandle(*pattern),
       RegExpFlagsToString(flags),
       &has_pending_exception);
-  EXCEPTION_BAILOUT_CHECK(Local<v8::RegExp>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
   return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
 }
 
 
 Local<v8::String> v8::RegExp::GetSource() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::RegExp::GetSource()")) {
     return Local<v8::String>();
   }
@@ -4197,7 +4243,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Array::New()");
   LOG_API(isolate, "Array::New");
-  ENTER_V8;
+  ENTER_V8(isolate);
   int real_length = length > 0 ? length : 0;
   i::Handle<i::JSArray> obj = isolate->factory()->NewJSArray(real_length);
   obj->set_length(*isolate->factory()->NewNumberFromInt(real_length));
@@ -4206,7 +4252,7 @@
 
 
 uint32_t v8::Array::Length() const {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   if (IsDeadCheck(isolate, "v8::Array::Length()")) return 0;
   i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
   i::Object* length = obj->length();
@@ -4219,7 +4265,7 @@
 
 
 Local<Object> Array::CloneElementAt(uint32_t index) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   if (!self->HasFastElements()) {
@@ -4231,11 +4277,11 @@
     return Local<Object>();
   }
   i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
-  EXCEPTION_PREAMBLE();
-  ENTER_V8;
+  EXCEPTION_PREAMBLE(isolate);
+  ENTER_V8(isolate);
   i::Handle<i::JSObject> result = i::Copy(paragon_handle);
   has_pending_exception = result.is_null();
-  EXCEPTION_BAILOUT_CHECK(Local<Object>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
   return Utils::ToLocal(result);
 }
 
@@ -4244,7 +4290,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::String::NewSymbol()");
   LOG_API(isolate, "String::NewSymbol(char)");
-  ENTER_V8;
+  ENTER_V8(isolate);
   if (length == -1) length = i::StrLength(data);
   i::Handle<i::String> result =
       isolate->factory()->LookupSymbol(i::Vector<const char>(data, length));
@@ -4259,7 +4305,7 @@
     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
     value = i::OS::nan_value();
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
   return Utils::NumberToLocal(result);
 }
@@ -4272,7 +4318,7 @@
     return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
                                                       isolate));
   }
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
   return Utils::IntegerToLocal(result);
 }
@@ -4283,8 +4329,9 @@
   if (fits_into_int32_t) {
     return Integer::New(static_cast<int32_t>(value));
   }
-  ENTER_V8;
-  i::Handle<i::Object> result = FACTORY->NewNumber(value);
+  i::Isolate* isolate = i::Isolate::Current();
+  ENTER_V8(isolate);
+  i::Handle<i::Object> result = isolate->factory()->NewNumber(value);
   return Utils::IntegerToLocal(result);
 }
 
@@ -4299,13 +4346,13 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::V8::AddMessageListener()");
   ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   NeanderArray listeners(isolate->factory()->message_listeners());
   NeanderObject obj(2);
   obj.set(0, *isolate->factory()->NewProxy(FUNCTION_ADDR(that)));
   obj.set(1, data.IsEmpty() ?
-             HEAP->undefined_value() :
+             isolate->heap()->undefined_value() :
              *Utils::OpenHandle(*data));
   listeners.add(obj.value());
   return true;
@@ -4316,7 +4363,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::V8::RemoveMessageListener()");
   ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   NeanderArray listeners(isolate->factory()->message_listeners());
   for (int i = 0; i < listeners.length(); i++) {
@@ -4325,7 +4372,7 @@
     NeanderObject listener(i::JSObject::cast(listeners.get(i)));
     i::Handle<i::Proxy> callback_obj(i::Proxy::cast(listener.get(0)));
     if (callback_obj->proxy() == FUNCTION_ADDR(that)) {
-      listeners.set(i, HEAP->undefined_value());
+      listeners.set(i, isolate->heap()->undefined_value());
     }
   }
 }
@@ -4495,21 +4542,22 @@
 
 void V8::ResumeProfilerEx(int flags, int tag) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
+  i::Isolate* isolate = i::Isolate::Current();
   if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
     // Snapshot mode: resume modules, perform GC, then pause only
     // those modules which haven't been started prior to making a
     // snapshot.
 
     // Make a GC prior to taking a snapshot.
-    HEAP->CollectAllGarbage(false);
+    isolate->heap()->CollectAllGarbage(false);
     // Reset snapshot flag and CPU module flags.
     flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
-    const int current_flags = LOGGER->GetActiveProfilerModules();
-    LOGGER->ResumeProfiler(flags, tag);
-    HEAP->CollectAllGarbage(false);
-    LOGGER->PauseProfiler(~current_flags & flags, tag);
+    const int current_flags = isolate->logger()->GetActiveProfilerModules();
+    isolate->logger()->ResumeProfiler(flags, tag);
+    isolate->heap()->CollectAllGarbage(false);
+    isolate->logger()->PauseProfiler(~current_flags & flags, tag);
   } else {
-    LOGGER->ResumeProfiler(flags, tag);
+    isolate->logger()->ResumeProfiler(flags, tag);
   }
 #endif
 }
@@ -4541,16 +4589,16 @@
 
 
 int V8::GetCurrentThreadId() {
-  API_ENTRY_CHECK("V8::GetCurrentThreadId()");
-  EnsureInitialized("V8::GetCurrentThreadId()");
-  return i::Isolate::Current()->thread_id();
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
+  return isolate->thread_id();
 }
 
 
 void V8::TerminateExecution(int thread_id) {
-  if (!i::Isolate::Current()->IsInitialized()) return;
-  API_ENTRY_CHECK("V8::GetCurrentThreadId()");
   i::Isolate* isolate = i::Isolate::Current();
+  if (!isolate->IsInitialized()) return;
+  API_ENTRY_CHECK("V8::TerminateExecution()");
   // If the thread_id identifies the current thread just terminate
   // execution right away.  Otherwise, ask the thread manager to
   // terminate the thread with the given id if any.
@@ -4573,12 +4621,8 @@
 
 
 bool V8::IsExecutionTerminating() {
-  if (!i::Isolate::Current()->IsInitialized()) return false;
-  if (i::Isolate::Current()->has_scheduled_exception()) {
-    return i::Isolate::Current()->scheduled_exception() ==
-        HEAP->termination_exception();
-  }
-  return false;
+  i::Isolate* isolate = i::Isolate::Current();
+  return IsExecutionTerminatingCheck(isolate);
 }
 
 
@@ -4618,14 +4662,15 @@
 
 
 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
-  EnsureInitialized("v8::String::Utf8Value::Utf8Value()");
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::String::Utf8Value::Utf8Value()")) return;
   if (obj.IsEmpty()) {
     str_ = NULL;
     length_ = 0;
     return;
   }
-  ENTER_V8;
-  HandleScope scope;
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
   TryCatch try_catch;
   Handle<String> str = obj->ToString();
   if (str.IsEmpty()) {
@@ -4645,14 +4690,15 @@
 
 
 String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
-  EnsureInitialized("v8::String::AsciiValue::AsciiValue()");
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::String::AsciiValue::AsciiValue()")) return;
   if (obj.IsEmpty()) {
     str_ = NULL;
     length_ = 0;
     return;
   }
-  ENTER_V8;
-  HandleScope scope;
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
   TryCatch try_catch;
   Handle<String> str = obj->ToString();
   if (str.IsEmpty()) {
@@ -4672,14 +4718,15 @@
 
 
 String::Value::Value(v8::Handle<v8::Value> obj) {
-  EnsureInitialized("v8::String::Value::Value()");
+  i::Isolate* isolate = i::Isolate::Current();
+  if (IsDeadCheck(isolate, "v8::String::Value::Value()")) return;
   if (obj.IsEmpty()) {
     str_ = NULL;
     length_ = 0;
     return;
   }
-  ENTER_V8;
-  HandleScope scope;
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
   TryCatch try_catch;
   Handle<String> str = obj->ToString();
   if (str.IsEmpty()) {
@@ -4701,7 +4748,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "RangeError");
   ON_BAILOUT(isolate, "v8::Exception::RangeError()", return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* error;
   {
     i::HandleScope scope(isolate);
@@ -4717,7 +4764,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "ReferenceError");
   ON_BAILOUT(isolate, "v8::Exception::ReferenceError()", return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* error;
   {
     i::HandleScope scope(isolate);
@@ -4734,7 +4781,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "SyntaxError");
   ON_BAILOUT(isolate, "v8::Exception::SyntaxError()", return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* error;
   {
     i::HandleScope scope(isolate);
@@ -4750,7 +4797,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "TypeError");
   ON_BAILOUT(isolate, "v8::Exception::TypeError()", return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* error;
   {
     i::HandleScope scope(isolate);
@@ -4766,7 +4813,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   LOG_API(isolate, "Error");
   ON_BAILOUT(isolate, "v8::Exception::Error()", return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Object* error;
   {
     i::HandleScope scope(isolate);
@@ -4798,7 +4845,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
   ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
 
   isolate->set_debug_event_callback(that);
 
@@ -4816,7 +4863,7 @@
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
   ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener2()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   i::Handle<i::Object> proxy = isolate->factory()->undefined_value();
   if (that != NULL) {
@@ -4832,7 +4879,7 @@
                                   Handle<Value> data) {
   i::Isolate* isolate = i::Isolate::Current();
   ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
-  ENTER_V8;
+  ENTER_V8(isolate);
   isolate->debugger()->SetEventListener(Utils::OpenHandle(*that),
                                                       Utils::OpenHandle(*data));
   return true;
@@ -4882,27 +4929,29 @@
 
 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
                               bool message_handler_thread) {
-  EnsureInitialized("v8::Debug::SetMessageHandler");
-  ENTER_V8;
   i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
+  ENTER_V8(isolate);
+
   // Message handler thread not supported any more. Parameter temporally left in
-  // the API for client compatability reasons.
+  // the API for client compatibility reasons.
   CHECK(!message_handler_thread);
 
   // TODO(sgjesse) support the old message handler API through a simple wrapper.
   isolate->set_message_handler(handler);
   if (handler != NULL) {
-    i::Isolate::Current()->debugger()->SetMessageHandler(MessageHandlerWrapper);
+    isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
   } else {
-    i::Isolate::Current()->debugger()->SetMessageHandler(NULL);
+    isolate->debugger()->SetMessageHandler(NULL);
   }
 }
 
 
 void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
-  EnsureInitialized("v8::Debug::SetMessageHandler");
-  ENTER_V8;
-  i::Isolate::Current()->debugger()->SetMessageHandler(handler);
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
+  ENTER_V8(isolate);
+  isolate->debugger()->SetMessageHandler(handler);
 }
 
 
@@ -4923,17 +4972,20 @@
 
 void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
                                    int period) {
-  EnsureInitialized("v8::Debug::SetHostDispatchHandler");
-  ENTER_V8;
-  i::Isolate::Current()->debugger()->SetHostDispatchHandler(handler, period);
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::Debug::SetHostDispatchHandler");
+  ENTER_V8(isolate);
+  isolate->debugger()->SetHostDispatchHandler(handler, period);
 }
 
 
 void Debug::SetDebugMessageDispatchHandler(
     DebugMessageDispatchHandler handler, bool provide_locker) {
-  EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler");
-  ENTER_V8;
-  i::Isolate::Current()->debugger()->SetDebugMessageDispatchHandler(
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate,
+                              "v8::Debug::SetDebugMessageDispatchHandler");
+  ENTER_V8(isolate);
+  isolate->debugger()->SetDebugMessageDispatchHandler(
       handler, provide_locker);
 }
 
@@ -4943,20 +4995,19 @@
   i::Isolate* isolate = i::Isolate::Current();
   if (!isolate->IsInitialized()) return Local<Value>();
   ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   i::Handle<i::Object> result;
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   if (data.IsEmpty()) {
-    result = i::Isolate::Current()->debugger()->Call(
-        Utils::OpenHandle(*fun),
-        isolate->factory()->undefined_value(),
-        &has_pending_exception);
+    result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
+                                       isolate->factory()->undefined_value(),
+                                       &has_pending_exception);
   } else {
-    result = i::Isolate::Current()->debugger()->Call(Utils::OpenHandle(*fun),
-                                                     Utils::OpenHandle(*data),
-                                                     &has_pending_exception);
+    result = isolate->debugger()->Call(Utils::OpenHandle(*fun),
+                                       Utils::OpenHandle(*data),
+                                       &has_pending_exception);
   }
-  EXCEPTION_BAILOUT_CHECK(Local<Value>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   return Utils::ToLocal(result);
 }
 
@@ -4965,9 +5016,9 @@
   i::Isolate* isolate = i::Isolate::Current();
   if (!isolate->IsInitialized()) return Local<Value>();
   ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
-  ENTER_V8;
+  ENTER_V8(isolate);
   v8::HandleScope scope;
-  i::Debug* isolate_debug = i::Isolate::Current()->debug();
+  i::Debug* isolate_debug = isolate->debug();
   isolate_debug->Load();
   i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global());
   i::Handle<i::String> name =
@@ -4977,11 +5028,11 @@
   v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
   const int kArgc = 1;
   v8::Handle<v8::Value> argv[kArgc] = { obj };
-  EXCEPTION_PREAMBLE();
+  EXCEPTION_PREAMBLE(isolate);
   v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
                                               kArgc,
                                               argv);
-  EXCEPTION_BAILOUT_CHECK(Local<Value>());
+  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   return scope.Close(result);
 }
 
@@ -4996,8 +5047,9 @@
 }
 
 Local<Context> Debug::GetDebugContext() {
-  EnsureInitialized("v8::Debug::GetDebugContext()");
-  ENTER_V8;
+  i::Isolate* isolate = i::Isolate::Current();
+  EnsureInitializedForIsolate(isolate, "v8::Debug::GetDebugContext()");
+  ENTER_V8(isolate);
   return Utils::ToLocal(i::Isolate::Current()->debugger()->GetDebugContext());
 }
 
@@ -5216,7 +5268,7 @@
           edge->index())));
     default: UNREACHABLE();
   }
-  return ImplementationUtilities::Undefined();
+  return v8::Undefined();
 }
 
 
diff --git a/src/apiutils.h b/src/apiutils.h
index 149ede5..68579af 100644
--- a/src/apiutils.h
+++ b/src/apiutils.h
@@ -31,11 +31,6 @@
 namespace v8 {
 class ImplementationUtilities {
  public:
-  static v8::Handle<v8::Primitive> Undefined();
-  static v8::Handle<v8::Primitive> Null();
-  static v8::Handle<v8::Boolean> True();
-  static v8::Handle<v8::Boolean> False();
-
   static int GetNameCount(ExtensionConfiguration* that) {
     return that->name_count_;
   }
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index e6d6525..f401cfd 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -310,6 +310,7 @@
 // construct call and normal call.
 static void ArrayNativeCode(MacroAssembler* masm,
                             Label* call_generic_code) {
+  Counters* counters = masm->isolate()->counters();
   Label argc_one_or_more, argc_two_or_more;
 
   // Check for array construction with zero arguments or one.
@@ -325,7 +326,7 @@
                        r5,
                        JSArray::kPreallocatedArrayElements,
                        call_generic_code);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1, r3, r4);
+  __ IncrementCounter(counters->array_function_native(), 1, r3, r4);
   // Setup return value, remove receiver from stack and return.
   __ mov(r0, r2);
   __ add(sp, sp, Operand(kPointerSize));
@@ -361,7 +362,7 @@
                   r7,
                   true,
                   call_generic_code);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1, r2, r4);
+  __ IncrementCounter(counters->array_function_native(), 1, r2, r4);
   // Setup return value, remove receiver and argument from stack and return.
   __ mov(r0, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
@@ -385,7 +386,7 @@
                   r7,
                   false,
                   call_generic_code);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1, r2, r6);
+  __ IncrementCounter(counters->array_function_native(), 1, r2, r6);
 
   // Fill arguments as array elements. Copy from the top of the stack (last
   // element) to the array backing store filling it backwards. Note:
@@ -442,9 +443,9 @@
   // Jump to the generic array code if the specialized code cannot handle
   // the construction.
   __ bind(&generic_array_code);
-  Code* code = masm->isolate()->builtins()->builtin(
-      Builtins::ArrayCodeGeneric);
-  Handle<Code> array_code(code);
+
+  Handle<Code> array_code =
+      masm->isolate()->builtins()->ArrayCodeGeneric();
   __ Jump(array_code, RelocInfo::CODE_TARGET);
 }
 
@@ -475,9 +476,8 @@
   // Jump to the generic construct code in case the specialized code cannot
   // handle the construction.
   __ bind(&generic_constructor);
-  Code* code = masm->isolate()->builtins()->builtin(
-      Builtins::JSConstructStubGeneric);
-  Handle<Code> generic_construct_stub(code);
+  Handle<Code> generic_construct_stub =
+      masm->isolate()->builtins()->JSConstructStubGeneric();
   __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
 }
 
@@ -490,7 +490,8 @@
   //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
   //  -- sp[argc * 4]           : receiver
   // -----------------------------------
-  __ IncrementCounter(COUNTERS->string_ctor_calls(), 1, r2, r3);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->string_ctor_calls(), 1, r2, r3);
 
   Register function = r1;
   if (FLAG_debug_code) {
@@ -520,7 +521,7 @@
       r5,        // Scratch.
       false,     // Is it a Smi?
       &not_cached);
-  __ IncrementCounter(COUNTERS->string_ctor_cached_number(), 1, r3, r4);
+  __ IncrementCounter(counters->string_ctor_cached_number(), 1, r3, r4);
   __ bind(&argument_is_string);
 
   // ----------- S t a t e -------------
@@ -574,13 +575,13 @@
   __ tst(r3, Operand(kIsNotStringMask));
   __ b(ne, &convert_argument);
   __ mov(argument, r0);
-  __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1, r3, r4);
+  __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
   __ b(&argument_is_string);
 
   // Invoke the conversion builtin and put the result into r2.
   __ bind(&convert_argument);
   __ push(function);  // Preserve the function.
-  __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1, r3, r4);
+  __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
   __ EnterInternalFrame();
   __ push(r0);
   __ InvokeBuiltin(Builtins::TO_STRING, CALL_JS);
@@ -599,7 +600,7 @@
   // At this point the argument is already a string. Call runtime to
   // create a string wrapper.
   __ bind(&gc_required);
-  __ IncrementCounter(COUNTERS->string_ctor_gc_required(), 1, r3, r4);
+  __ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4);
   __ EnterInternalFrame();
   __ push(argument);
   __ CallRuntime(Runtime::kNewStringWrapper, 1);
@@ -635,8 +636,8 @@
   // Set expected number of arguments to zero (not changing r0).
   __ mov(r2, Operand(0, RelocInfo::NONE));
   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
-  __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
-      ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+          RelocInfo::CODE_TARGET);
 }
 
 
@@ -646,6 +647,8 @@
   // Should never count constructions for api objects.
   ASSERT(!is_api_function || !count_constructions);
 
+  Isolate* isolate = masm->isolate();
+
   // Enter a construct frame.
   __ EnterConstructFrame();
 
@@ -661,7 +664,7 @@
     Label undo_allocation;
 #ifdef ENABLE_DEBUGGER_SUPPORT
     ExternalReference debug_step_in_fp =
-        ExternalReference::debug_step_in_fp_address(masm->isolate());
+        ExternalReference::debug_step_in_fp_address(isolate);
     __ mov(r2, Operand(debug_step_in_fp));
     __ ldr(r2, MemOperand(r2));
     __ tst(r2, r2);
@@ -907,9 +910,8 @@
   // r1: constructor function
   if (is_api_function) {
     __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
-    Handle<Code> code = Handle<Code>(
-        masm->isolate()->builtins()->builtin(
-            Builtins::HandleApiCallConstruct));
+    Handle<Code> code =
+        masm->isolate()->builtins()->HandleApiCallConstruct();
     ParameterCount expected(0);
     __ InvokeCode(code, expected, expected,
                   RelocInfo::CODE_TARGET, CALL_FUNCTION);
@@ -966,7 +968,7 @@
   __ LeaveConstructFrame();
   __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
   __ add(sp, sp, Operand(kPointerSize));
-  __ IncrementCounter(COUNTERS->constructed_objects(), 1, r1, r2);
+  __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2);
   __ Jump(lr);
 }
 
@@ -1043,8 +1045,8 @@
   // Invoke the code and pass argc as r0.
   __ mov(r0, Operand(r3));
   if (is_construct) {
-    __ Call(Handle<Code>(masm->isolate()->builtins()->builtin(
-        Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
+    __ Call(masm->isolate()->builtins()->JSConstructCall(),
+            RelocInfo::CODE_TARGET);
   } else {
     ParameterCount actual(r0);
     __ InvokeFunction(r1, actual, CALL_FUNCTION);
@@ -1336,8 +1338,8 @@
     // Expected number of arguments is 0 for CALL_NON_FUNCTION.
     __ mov(r2, Operand(0, RelocInfo::NONE));
     __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
-    __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
-        ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+            RelocInfo::CODE_TARGET);
     __ bind(&function);
   }
 
@@ -1352,8 +1354,9 @@
   __ mov(r2, Operand(r2, ASR, kSmiTagSize));
   __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
   __ cmp(r2, r0);  // Check formal and actual parameter counts.
-  __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
-      ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET, ne);
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+          RelocInfo::CODE_TARGET,
+          ne);
 
   ParameterCount expected(0);
   __ InvokeCode(r3, expected, expected, JUMP_FUNCTION);
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index e7b563c..c25d445 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -1458,11 +1458,12 @@
   // number string cache for smis is just the smi value, and the hash for
   // doubles is the xor of the upper and lower words. See
   // Heap::GetNumberStringCache.
+  Isolate* isolate = masm->isolate();
   Label is_smi;
   Label load_result_from_cache;
   if (!object_is_smi) {
     __ JumpIfSmi(object, &is_smi);
-    if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+    if (isolate->cpu_features()->IsSupported(VFP3)) {
       CpuFeatures::Scope scope(VFP3);
       __ CheckMap(object,
                   scratch1,
@@ -1519,7 +1520,7 @@
   __ bind(&load_result_from_cache);
   __ ldr(result,
          FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize));
-  __ IncrementCounter(COUNTERS->number_to_string_native(),
+  __ IncrementCounter(isolate->counters()->number_to_string_native(),
                       1,
                       scratch1,
                       scratch2);
@@ -1595,7 +1596,8 @@
   __ bind(&both_loaded_as_doubles);
   // The arguments have been converted to doubles and stored in d6 and d7, if
   // VFP3 is supported, or in r0, r1, r2, and r3.
-  if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+  Isolate* isolate = masm->isolate();
+  if (isolate->cpu_features()->IsSupported(VFP3)) {
     __ bind(&lhs_not_nan);
     CpuFeatures::Scope scope(VFP3);
     Label no_nan;
@@ -1665,7 +1667,7 @@
 
   __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow);
 
-  __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3);
+  __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3);
   StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
                                                      lhs_,
                                                      rhs_,
@@ -4494,11 +4496,11 @@
   // r3: argc
   // r4: argv
   if (is_construct) {
-    ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline,
+    ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
                                       isolate);
     __ mov(ip, Operand(construct_entry));
   } else {
-    ExternalReference entry(Builtins::JSEntryTrampoline, isolate);
+    ExternalReference entry(Builtins::kJSEntryTrampoline, isolate);
     __ mov(ip, Operand(entry));
   }
   __ ldr(ip, MemOperand(ip));  // deref address
@@ -5089,7 +5091,7 @@
   // subject: Subject string
   // regexp_data: RegExp data (FixedArray)
   // All checks done. Now push arguments for native regexp code.
-  __ IncrementCounter(COUNTERS->regexp_entry_native(), 1, r0, r2);
+  __ IncrementCounter(isolate->counters()->regexp_entry_native(), 1, r0, r2);
 
   // Isolates: note we add an additional parameter here (isolate pointer).
   static const int kRegExpExecuteArguments = 8;
@@ -5397,8 +5399,7 @@
   __ mov(r0, Operand(argc_));  // Setup the number of arguments.
   __ mov(r2, Operand(0, RelocInfo::NONE));
   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
-  __ Jump(Handle<Code>(Isolate::Current()->builtins()->builtin(
-              Builtins::ArgumentsAdaptorTrampoline)),
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
 }
 
@@ -6105,7 +6106,6 @@
   static const int kFromOffset = 1 * kPointerSize;
   static const int kStringOffset = 2 * kPointerSize;
 
-
   // Check bounds and smi-ness.
   Register to = r6;
   Register from = r7;
@@ -6206,7 +6206,8 @@
   Label make_two_character_string;
   StringHelper::GenerateTwoCharacterSymbolTableProbe(
       masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string);
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
   __ add(sp, sp, Operand(3 * kPointerSize));
   __ Ret();
 
@@ -6215,7 +6216,7 @@
   __ bind(&make_two_character_string);
   __ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime);
   __ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+  __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
   __ add(sp, sp, Operand(3 * kPointerSize));
   __ Ret();
 
@@ -6241,7 +6242,7 @@
   STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
   StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
                                            COPY_ASCII | DEST_ALWAYS_ALIGNED);
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+  __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
   __ add(sp, sp, Operand(3 * kPointerSize));
   __ Ret();
 
@@ -6273,7 +6274,7 @@
   STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
   StringHelper::GenerateCopyCharactersLong(
       masm, r1, r5, r2, r3, r4, r6, r7, r9, DEST_ALWAYS_ALIGNED);
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1, r3, r4);
+  __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
   __ add(sp, sp, Operand(3 * kPointerSize));
   __ Ret();
 
@@ -6345,6 +6346,8 @@
 void StringCompareStub::Generate(MacroAssembler* masm) {
   Label runtime;
 
+  Counters* counters = masm->isolate()->counters();
+
   // Stack frame on entry.
   //  sp[0]: right string
   //  sp[4]: left string
@@ -6356,7 +6359,7 @@
   STATIC_ASSERT(EQUAL == 0);
   STATIC_ASSERT(kSmiTag == 0);
   __ mov(r0, Operand(Smi::FromInt(EQUAL)));
-  __ IncrementCounter(COUNTERS->string_compare_native(), 1, r1, r2);
+  __ IncrementCounter(counters->string_compare_native(), 1, r1, r2);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
 
@@ -6366,7 +6369,7 @@
   __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime);
 
   // Compare flat ASCII strings natively. Remove arguments from stack first.
-  __ IncrementCounter(COUNTERS->string_compare_native(), 1, r2, r3);
+  __ IncrementCounter(counters->string_compare_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
 
@@ -6381,6 +6384,8 @@
   Label string_add_runtime, call_builtin;
   Builtins::JavaScript builtin_id = Builtins::ADD;
 
+  Counters* counters = masm->isolate()->counters();
+
   // Stack on entry:
   // sp[0]: second argument (right).
   // sp[4]: first argument (left).
@@ -6436,7 +6441,7 @@
     __ cmp(r3, Operand(Smi::FromInt(0)), ne);
     __ b(ne, &strings_not_empty);  // If either string was empty, return r0.
 
-    __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+    __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
     __ add(sp, sp, Operand(2 * kPointerSize));
     __ Ret();
 
@@ -6481,7 +6486,7 @@
   Label make_two_character_string;
   StringHelper::GenerateTwoCharacterSymbolTableProbe(
       masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+  __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
 
@@ -6494,7 +6499,7 @@
   __ mov(r6, Operand(2));
   __ AllocateAsciiString(r0, r6, r4, r5, r9, &string_add_runtime);
   __ strh(r2, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
-  __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+  __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
 
@@ -6531,7 +6536,7 @@
   __ str(r0, FieldMemOperand(r7, ConsString::kFirstOffset));
   __ str(r1, FieldMemOperand(r7, ConsString::kSecondOffset));
   __ mov(r0, Operand(r7));
-  __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+  __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
 
@@ -6613,7 +6618,7 @@
   // r7: result string.
   StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, true);
   __ mov(r0, Operand(r7));
-  __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+  __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
 
@@ -6654,7 +6659,7 @@
   StringHelper::GenerateCopyCharacters(masm, r6, r1, r3, r4, false);
 
   __ mov(r0, Operand(r7));
-  __ IncrementCounter(COUNTERS->string_add_native(), 1, r2, r3);
+  __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
   __ add(sp, sp, Operand(2 * kPointerSize));
   __ Ret();
 
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 5e3b7d0..91c4747 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -1787,7 +1787,7 @@
   __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE);
   __ b(ne, &build_args);
   Handle<Code> apply_code(
-      Isolate::Current()->builtins()->builtin(Builtins::FunctionApply));
+      Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply));
   __ ldr(r1, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
   __ sub(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
   __ cmp(r1, Operand(apply_code));
@@ -3632,7 +3632,7 @@
       case ObjectLiteral::Property::COMPUTED:
         if (key->handle()->IsSymbol()) {
           Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-              Builtins::StoreIC_Initialize));
+              Builtins::kStoreIC_Initialize));
           Load(value);
           if (property->emit_store()) {
             frame_->PopToR0();
@@ -3699,7 +3699,8 @@
     FastCloneShallowArrayStub stub(
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
     frame_->CallStub(&stub, 3);
-    __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1, r1, r2);
+    __ IncrementCounter(masm_->isolate()->counters()->cow_arrays_created_stub(),
+                        1, r1, r2);
   } else if (node->depth() > 1) {
     frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
@@ -4460,7 +4461,7 @@
   // constructor invocation.
   CodeForSourcePosition(node->position());
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::JSConstructCall));
+      Builtins::kJSConstructCall));
   frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1);
   frame_->EmitPush(r0);
 
@@ -6588,9 +6589,10 @@
   Register scratch1 = VirtualFrame::scratch0();
   Register scratch2 = VirtualFrame::scratch1();
   ASSERT(!receiver_.is(scratch1) && !receiver_.is(scratch2));
-  __ DecrementCounter(COUNTERS->named_load_inline(), 1, scratch1, scratch2);
-  __ IncrementCounter(COUNTERS->named_load_inline_miss(), 1,
-      scratch1, scratch2);
+  __ DecrementCounter(masm_->isolate()->counters()->named_load_inline(),
+                      1, scratch1, scratch2);
+  __ IncrementCounter(masm_->isolate()->counters()->named_load_inline_miss(),
+                      1, scratch1, scratch2);
 
   // Ensure receiver in r0 and name in r2 to match load ic calling convention.
   __ Move(r0, receiver_);
@@ -6599,7 +6601,7 @@
   // The rest of the instructions in the deferred code must be together.
   { Assembler::BlockConstPoolScope block_const_pool(masm_);
     Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-        Builtins::LoadIC_Initialize));
+        Builtins::kLoadIC_Initialize));
     RelocInfo::Mode mode = is_contextual_
         ? RelocInfo::CODE_TARGET_CONTEXT
         : RelocInfo::CODE_TARGET;
@@ -6661,9 +6663,10 @@
 
   Register scratch1 = VirtualFrame::scratch0();
   Register scratch2 = VirtualFrame::scratch1();
-  __ DecrementCounter(COUNTERS->keyed_load_inline(), 1, scratch1, scratch2);
-  __ IncrementCounter(COUNTERS->keyed_load_inline_miss(),
-      1, scratch1, scratch2);
+  __ DecrementCounter(masm_->isolate()->counters()->keyed_load_inline(),
+                      1, scratch1, scratch2);
+  __ IncrementCounter(masm_->isolate()->counters()->keyed_load_inline_miss(),
+                      1, scratch1, scratch2);
 
   // Ensure key in r0 and receiver in r1 to match keyed load ic calling
   // convention.
@@ -6675,7 +6678,7 @@
   { Assembler::BlockConstPoolScope block_const_pool(masm_);
     // Call keyed load IC. It has the arguments key and receiver in r0 and r1.
     Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-        Builtins::KeyedLoadIC_Initialize));
+        Builtins::kKeyedLoadIC_Initialize));
     __ Call(ic, RelocInfo::CODE_TARGET);
     // The call must be followed by a nop instruction to indicate that the
     // keyed load has been inlined.
@@ -6722,8 +6725,9 @@
 void DeferredReferenceSetKeyedValue::Generate() {
   Register scratch1 = VirtualFrame::scratch0();
   Register scratch2 = VirtualFrame::scratch1();
-  __ DecrementCounter(COUNTERS->keyed_store_inline(), 1, scratch1, scratch2);
-  __ IncrementCounter(COUNTERS->keyed_store_inline_miss(),
+  __ DecrementCounter(masm_->isolate()->counters()->keyed_store_inline(),
+                      1, scratch1, scratch2);
+  __ IncrementCounter(masm_->isolate()->counters()->keyed_store_inline_miss(),
                       1, scratch1, scratch2);
 
   // Ensure value in r0, key in r1 and receiver in r2 to match keyed store ic
@@ -6738,8 +6742,9 @@
     // Call keyed store IC. It has the arguments value, key and receiver in r0,
     // r1 and r2.
     Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-        (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
-                                      : Builtins::KeyedStoreIC_Initialize));
+        (strict_mode_ == kStrictMode)
+        ? Builtins::kKeyedStoreIC_Initialize_Strict
+        : Builtins::kKeyedStoreIC_Initialize));
     __ Call(ic, RelocInfo::CODE_TARGET);
     // The call must be followed by a nop instruction to indicate that the
     // keyed store has been inlined.
@@ -6793,8 +6798,8 @@
     // Call keyed store IC. It has the arguments value, key and receiver in r0,
     // r1 and r2.
     Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-        (strict_mode_ == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
-                                      : Builtins::StoreIC_Initialize));
+        (strict_mode_ == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+                                      : Builtins::kStoreIC_Initialize));
     __ Call(ic, RelocInfo::CODE_TARGET);
     // The call must be followed by a nop instruction to indicate that the
     // named store has been inlined.
@@ -6840,11 +6845,12 @@
     // Counter will be decremented in the deferred code. Placed here to avoid
     // having it in the instruction stream below where patching will occur.
     if (is_contextual) {
-      __ IncrementCounter(COUNTERS->named_load_global_inline(), 1,
-                          frame_->scratch0(), frame_->scratch1());
+      __ IncrementCounter(
+          masm_->isolate()->counters()->named_load_global_inline(),
+          1, frame_->scratch0(), frame_->scratch1());
     } else {
-      __ IncrementCounter(COUNTERS->named_load_inline(), 1,
-                          frame_->scratch0(), frame_->scratch1());
+      __ IncrementCounter(masm_->isolate()->counters()->named_load_inline(),
+                          1, frame_->scratch0(), frame_->scratch1());
     }
 
     // The following instructions are the inlined load of an in-object property.
@@ -6876,8 +6882,9 @@
         }
       }
       if (is_dont_delete) {
-        __ IncrementCounter(COUNTERS->dont_delete_hint_hit(), 1,
-                            frame_->scratch0(), frame_->scratch1());
+        __ IncrementCounter(
+            masm_->isolate()->counters()->dont_delete_hint_hit(),
+            1, frame_->scratch0(), frame_->scratch1());
       }
     }
 
@@ -7062,8 +7069,8 @@
 
     // Counter will be decremented in the deferred code. Placed here to avoid
     // having it in the instruction stream below where patching will occur.
-    __ IncrementCounter(COUNTERS->keyed_load_inline(), 1,
-                        frame_->scratch0(), frame_->scratch1());
+    __ IncrementCounter(masm_->isolate()->counters()->keyed_load_inline(),
+                        1, frame_->scratch0(), frame_->scratch1());
 
     // Load the key and receiver from the stack.
     bool key_is_known_smi = frame_->KnownSmiAt(0);
@@ -7149,8 +7156,8 @@
 
     // Counter will be decremented in the deferred code. Placed here to avoid
     // having it in the instruction stream below where patching will occur.
-    __ IncrementCounter(COUNTERS->keyed_store_inline(), 1,
-                        scratch1, scratch2);
+    __ IncrementCounter(masm_->isolate()->counters()->keyed_store_inline(),
+                        1, scratch1, scratch2);
 
 
     // Load the value, key and receiver from the stack.
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index f1fde92..33ca3b0 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -44,6 +44,11 @@
 }
 
 
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  // Nothing to do. No new relocation information is written for lazy
+  // deoptimization on ARM.
+}
+
 
 void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
   HandleScope scope;
@@ -106,7 +111,7 @@
 
   // Add the deoptimizing code to the list.
   DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
-  DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
+  DeoptimizerData* data = code->GetIsolate()->deoptimizer_data();
   node->set_next(data->deoptimizing_code_list_);
   data->deoptimizing_code_list_ = node;
 
@@ -316,8 +321,7 @@
         optimized_code_->entry() + pc_offset);
     output_[0]->SetPc(pc);
   }
-  Code* continuation = Isolate::Current()->builtins()->builtin(
-    Builtins::NotifyOSR);
+  Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
   output_[0]->SetContinuation(
       reinterpret_cast<uint32_t>(continuation->entry()));
 
@@ -496,8 +500,8 @@
   if (is_topmost) {
     Builtins* builtins = isolate_->builtins();
     Code* continuation = (bailout_type_ == EAGER)
-        ? builtins->builtin(Builtins::NotifyDeoptimized)
-        : builtins->builtin(Builtins::NotifyLazyDeoptimized);
+        ? builtins->builtin(Builtins::kNotifyDeoptimized)
+        : builtins->builtin(Builtins::kNotifyLazyDeoptimized);
     output_frame->SetContinuation(
         reinterpret_cast<uint32_t>(continuation->entry()));
   }
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 2edfd0a..088ba58 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -781,9 +781,9 @@
              prop->key()->AsLiteral()->handle()->IsSmi());
       __ mov(r1, Operand(prop->key()->AsLiteral()->handle()));
 
-      Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
-          ? Builtins::KeyedStoreIC_Initialize_Strict
-          : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       // Value in r0 is ignored (declarations are statements).
     }
@@ -1186,8 +1186,8 @@
                  ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
                                                    slow));
           __ mov(r0, Operand(key_literal->handle()));
-          Handle<Code> ic(isolate()->builtins()->builtin(
-              Builtins::KeyedLoadIC_Initialize));
+          Handle<Code> ic =
+              isolate()->builtins()->KeyedLoadIC_Initialize();
           EmitCallIC(ic, RelocInfo::CODE_TARGET);
           __ jmp(done);
         }
@@ -1253,8 +1253,7 @@
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   EmitCallIC(ic, mode);
 }
 
@@ -1272,8 +1271,7 @@
     // object (receiver) in r0.
     __ ldr(r0, GlobalObjectOperand());
     __ mov(r2, Operand(var->name()));
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::LoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
     context()->Plug(r0);
 
@@ -1332,8 +1330,7 @@
     __ mov(r0, Operand(key_literal->handle()));
 
     // Call keyed load IC. It has arguments key and receiver in r0 and r1.
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET);
     context()->Plug(r0);
   }
@@ -1442,8 +1439,7 @@
             VisitForAccumulatorValue(value);
             __ mov(r2, Operand(key->handle()));
             __ ldr(r1, MemOperand(sp));
-            Handle<Code> ic(isolate()->builtins()->builtin(
-                Builtins::StoreIC_Initialize));
+            Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
             EmitCallIC(ic, RelocInfo::CODE_TARGET);
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           } else {
@@ -1698,8 +1694,7 @@
   Literal* key = prop->key()->AsLiteral();
   __ mov(r2, Operand(key->handle()));
   // Call load IC. It has arguments receiver and property name r0 and r2.
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 }
 
@@ -1707,8 +1702,7 @@
 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   // Call keyed load IC. It has arguments key and receiver in r0 and r1.
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 }
 
@@ -1853,9 +1847,9 @@
       __ mov(r1, r0);
       __ pop(r0);  // Restore value.
       __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                           : Builtins::StoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->StoreIC_Initialize_Strict()
+          : isolate()->builtins()->StoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       break;
     }
@@ -1876,9 +1870,9 @@
         __ pop(r2);
       }
       __ pop(r0);  // Restore value.
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                           : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       break;
     }
@@ -1902,9 +1896,9 @@
     // r2, and the global object in r1.
     __ mov(r2, Operand(var->name()));
     __ ldr(r1, GlobalObjectOperand());
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                         : Builtins::StoreIC_Initialize));
+    Handle<Code> ic = is_strict_mode()
+        ? isolate()->builtins()->StoreIC_Initialize_Strict()
+        : isolate()->builtins()->StoreIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
 
   } else if (op == Token::INIT_CONST) {
@@ -2011,9 +2005,9 @@
     __ pop(r1);
   }
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                       : Builtins::StoreIC_Initialize));
+  Handle<Code> ic = is_strict_mode()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 
   // If the assignment ends an initialization block, revert to fast case.
@@ -2057,9 +2051,9 @@
     __ pop(r2);
   }
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                       : Builtins::KeyedStoreIC_Initialize));
+  Handle<Code> ic = is_strict_mode()
+      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+      : isolate()->builtins()->KeyedStoreIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 
   // If the assignment ends an initialization block, revert to fast case.
@@ -2344,8 +2338,7 @@
         // Record source code position for IC call.
         SetSourcePosition(prop->position());
 
-        Handle<Code> ic(isolate()->builtins()->builtin(
-            Builtins::KeyedLoadIC_Initialize));
+        Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
         EmitCallIC(ic, RelocInfo::CODE_TARGET);
         __ ldr(r1, GlobalObjectOperand());
         __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
@@ -2413,8 +2406,8 @@
   __ mov(r0, Operand(arg_count));
   __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
 
-  Handle<Code> construct_builtin(isolate()->builtins()->builtin(
-      Builtins::JSConstructCall));
+  Handle<Code> construct_builtin =
+      isolate()->builtins()->JSConstructCall();
   __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
   context()->Plug(r0);
 }
@@ -3914,9 +3907,9 @@
     case NAMED_PROPERTY: {
       __ mov(r2, Operand(prop->key()->AsLiteral()->handle()));
       __ pop(r1);
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                           : Builtins::StoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->StoreIC_Initialize_Strict()
+          : isolate()->builtins()->StoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
@@ -3931,9 +3924,9 @@
     case KEYED_PROPERTY: {
       __ pop(r1);  // Key.
       __ pop(r2);  // Receiver.
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                           : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
@@ -3957,8 +3950,7 @@
     Comment cmnt(masm_, "Global variable");
     __ ldr(r0, GlobalObjectOperand());
     __ mov(r2, Operand(proxy->name()));
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::LoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
     EmitCallIC(ic, RelocInfo::CODE_TARGET);
@@ -4229,18 +4221,19 @@
 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
   ASSERT(mode == RelocInfo::CODE_TARGET ||
          mode == RelocInfo::CODE_TARGET_CONTEXT);
+  Counters* counters = isolate()->counters();
   switch (ic->kind()) {
     case Code::LOAD_IC:
-      __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2);
+      __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
       break;
     case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2);
+      __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
       break;
     case Code::STORE_IC:
-      __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2);
+      __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
       break;
     case Code::KEYED_STORE_IC:
-      __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2);
+      __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
     default:
       break;
   }
@@ -4250,18 +4243,19 @@
 
 
 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
+  Counters* counters = isolate()->counters();
   switch (ic->kind()) {
     case Code::LOAD_IC:
-      __ IncrementCounter(COUNTERS->named_load_full(), 1, r1, r2);
+      __ IncrementCounter(counters->named_load_full(), 1, r1, r2);
       break;
     case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(COUNTERS->keyed_load_full(), 1, r1, r2);
+      __ IncrementCounter(counters->keyed_load_full(), 1, r1, r2);
       break;
     case Code::STORE_IC:
-      __ IncrementCounter(COUNTERS->named_store_full(), 1, r1, r2);
+      __ IncrementCounter(counters->named_store_full(), 1, r1, r2);
       break;
     case Code::KEYED_STORE_IC:
-      __ IncrementCounter(COUNTERS->keyed_store_full(), 1, r1, r2);
+      __ IncrementCounter(counters->keyed_store_full(), 1, r1, r2);
     default:
       break;
   }
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 9f9b63c..dc4f761 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -646,11 +646,12 @@
   //  -- r2    : name
   //  -- lr    : return address
   // -----------------------------------
+  Isolate* isolate = masm->isolate();
 
   if (id == IC::kCallIC_Miss) {
-    __ IncrementCounter(COUNTERS->call_miss(), 1, r3, r4);
+    __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4);
   } else {
-    __ IncrementCounter(COUNTERS->keyed_call_miss(), 1, r3, r4);
+    __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4);
   }
 
   // Get the receiver of the function from the stack.
@@ -663,7 +664,7 @@
 
   // Call the entry.
   __ mov(r0, Operand(2));
-  __ mov(r1, Operand(ExternalReference(IC_Utility(id), masm->isolate())));
+  __ mov(r1, Operand(ExternalReference(IC_Utility(id), isolate)));
 
   CEntryStub stub(1);
   __ CallStub(&stub);
@@ -765,7 +766,8 @@
 
   GenerateFastArrayLoad(
       masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1, r0, r3);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1, r0, r3);
 
   __ bind(&do_call);
   // receiver in r1 is not used after this point.
@@ -784,13 +786,13 @@
   __ mov(r0, Operand(r2, ASR, kSmiTagSize));
   // r0: untagged index
   GenerateNumberDictionaryLoad(masm, &slow_load, r4, r2, r1, r0, r3, r5);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1, r0, r3);
+  __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3);
   __ jmp(&do_call);
 
   __ bind(&slow_load);
   // This branch is taken when calling KeyedCallIC_Miss is neither required
   // nor beneficial.
-  __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1, r0, r3);
+  __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, r0, r3);
   __ EnterInternalFrame();
   __ push(r2);  // save the key
   __ Push(r1, r2);  // pass the receiver and the key
@@ -817,11 +819,11 @@
   __ b(ne, &lookup_monomorphic_cache);
 
   GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1, r0, r3);
+  __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3);
   __ jmp(&do_call);
 
   __ bind(&lookup_monomorphic_cache);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1, r0, r3);
+  __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3);
   GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
   // Fall through on miss.
 
@@ -832,7 +834,7 @@
   // - the value loaded is not a function,
   // - there is hope that the runtime will create a monomorphic call stub
   //   that will get fetched next time.
-  __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1, r0, r3);
+  __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3);
   GenerateMiss(masm, argc);
 
   __ bind(&index_string);
@@ -911,15 +913,16 @@
   //  -- r0    : receiver
   //  -- sp[0] : receiver
   // -----------------------------------
+  Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(COUNTERS->load_miss(), 1, r3, r4);
+  __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4);
 
   __ mov(r3, r0);
   __ Push(r3, r2);
 
   // Perform tail call to the entry.
   ExternalReference ref =
-      ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
+      ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
   __ TailCallExternalReference(ref, 2, 1);
 }
 
@@ -965,7 +968,7 @@
 
   // Find the end of the inlined code for handling the load if this is an
   // inlined IC call site.
-  Address inline_end_address;
+  Address inline_end_address = 0;
   if (InlinedICSiteMarker(address, &inline_end_address)
       != Assembler::PROPERTY_ACCESS_INLINED) {
     return false;
@@ -1005,7 +1008,7 @@
                                         bool is_dont_delete) {
   // Find the end of the inlined code for handling the contextual load if
   // this is inlined IC call site.
-  Address inline_end_address;
+  Address inline_end_address = 0;
   int marker = InlinedICSiteMarker(address, &inline_end_address);
   if (!((marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT) ||
         (marker == Assembler::PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE))) {
@@ -1046,7 +1049,7 @@
 
   // Find the end of the inlined code for the store if there is an
   // inlined version of the store.
-  Address inline_end_address;
+  Address inline_end_address = 0;
   if (InlinedICSiteMarker(address, &inline_end_address)
       != Assembler::PROPERTY_ACCESS_INLINED) {
     return false;
@@ -1096,7 +1099,7 @@
 bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
   if (V8::UseCrankshaft()) return false;
 
-  Address inline_end_address;
+  Address inline_end_address = 0;
   if (InlinedICSiteMarker(address, &inline_end_address)
       != Assembler::PROPERTY_ACCESS_INLINED) {
     return false;
@@ -1118,7 +1121,7 @@
 
   // Find the end of the inlined code for handling the store if this is an
   // inlined IC call site.
-  Address inline_end_address;
+  Address inline_end_address = 0;
   if (InlinedICSiteMarker(address, &inline_end_address)
       != Assembler::PROPERTY_ACCESS_INLINED) {
     return false;
@@ -1144,13 +1147,14 @@
   //  -- r0     : key
   //  -- r1     : receiver
   // -----------------------------------
+  Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(COUNTERS->keyed_load_miss(), 1, r3, r4);
+  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4);
 
   __ Push(r1, r0);
 
   ExternalReference ref =
-      ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
+      ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
   __ TailCallExternalReference(ref, 2, 1);
 }
 
@@ -1180,6 +1184,8 @@
   Register key = r0;
   Register receiver = r1;
 
+  Isolate* isolate = masm->isolate();
+
   // Check that the key is a smi.
   __ JumpIfNotSmi(key, &check_string);
   __ bind(&index_smi);
@@ -1197,7 +1203,7 @@
 
   GenerateFastArrayLoad(
       masm, receiver, key, r4, r3, r2, r0, NULL, &slow);
-  __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1, r2, r3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r2, r3);
   __ Ret();
 
   __ bind(&check_number_dictionary);
@@ -1217,7 +1223,8 @@
 
   // Slow case, key and receiver still in r0 and r1.
   __ bind(&slow);
-  __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1, r2, r3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
+                      1, r2, r3);
   GenerateRuntimeGetProperty(masm);
 
   __ bind(&check_string);
@@ -1245,7 +1252,7 @@
   // Load the key (consisting of map and symbol) from the cache and
   // check for match.
   ExternalReference cache_keys =
-      ExternalReference::keyed_lookup_cache_keys(masm->isolate());
+      ExternalReference::keyed_lookup_cache_keys(isolate);
   __ mov(r4, Operand(cache_keys));
   __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1));
   __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex));  // Move r4 to symbol.
@@ -1261,7 +1268,7 @@
   // r2     : receiver's map
   // r3     : lookup cache index
   ExternalReference cache_field_offsets =
-      ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
+      ExternalReference::keyed_lookup_cache_field_offsets(isolate);
   __ mov(r4, Operand(cache_field_offsets));
   __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2));
   __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset));
@@ -1273,7 +1280,8 @@
   __ add(r6, r6, r5);  // Index from start of object.
   __ sub(r1, r1, Operand(kHeapObjectTag));  // Remove the heap tag.
   __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2));
-  __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
+                      1, r2, r3);
   __ Ret();
 
   // Load property array property.
@@ -1281,7 +1289,8 @@
   __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset));
   __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2));
-  __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(),
+                      1, r2, r3);
   __ Ret();
 
   // Do a quick inline probe of the receiver's dictionary, if it
@@ -1295,7 +1304,8 @@
   GenerateGlobalInstanceTypeCheck(masm, r2, &slow);
   // Load the property to r0.
   GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4);
-  __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1, r2, r3);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(),
+                      1, r2, r3);
   __ Ret();
 
   __ bind(&index_string);
@@ -1625,11 +1635,13 @@
   GenerateStringDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss);
 
   GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5);
-  __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->store_normal_hit(),
+                      1, r4, r5);
   __ Ret();
 
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5);
+  __ IncrementCounter(counters->store_normal_miss(), 1, r4, r5);
   GenerateMiss(masm);
 }
 
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 3446995..5d31473 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1769,6 +1769,21 @@
 }
 
 
+LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
+    HLoadNamedFieldPolymorphic* instr) {
+  ASSERT(instr->representation().IsTagged());
+  if (instr->need_generic()) {
+    LOperand* obj = UseFixed(instr->object(), r0);
+    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    return MarkAsCall(DefineFixed(result, r0), instr);
+  } else {
+    LOperand* obj = UseRegisterAtStart(instr->object());
+    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    return AssignEnvironment(DefineAsRegister(result));
+  }
+}
+
+
 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
   LOperand* object = UseFixed(instr->object(), r0);
   LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), r0);
@@ -1807,15 +1822,22 @@
 }
 
 
-LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
-    HLoadPixelArrayElement* instr) {
+LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
+    HLoadKeyedSpecializedArrayElement* instr) {
+  // TODO(danno): Add support for other external array types.
+  if (instr->array_type() != kExternalPixelArray) {
+    Abort("unsupported load for external array type.");
+    return NULL;
+  }
+
   ASSERT(instr->representation().IsInteger32());
   ASSERT(instr->key()->representation().IsInteger32());
   LOperand* external_pointer =
       UseRegisterAtStart(instr->external_pointer());
   LOperand* key = UseRegisterAtStart(instr->key());
-  LLoadPixelArrayElement* result =
-      new LLoadPixelArrayElement(external_pointer, key);
+  LLoadKeyedSpecializedArrayElement* result =
+      new LLoadKeyedSpecializedArrayElement(external_pointer,
+                                            key);
   return DefineAsRegister(result);
 }
 
@@ -1849,8 +1871,14 @@
 }
 
 
-LInstruction* LChunkBuilder::DoStorePixelArrayElement(
-    HStorePixelArrayElement* instr) {
+LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
+    HStoreKeyedSpecializedArrayElement* instr) {
+  // TODO(danno): Add support for other external array types.
+  if (instr->array_type() != kExternalPixelArray) {
+    Abort("unsupported store for external array type.");
+    return NULL;
+  }
+
   ASSERT(instr->value()->representation().IsInteger32());
   ASSERT(instr->external_pointer()->representation().IsExternal());
   ASSERT(instr->key()->representation().IsInteger32());
@@ -1859,7 +1887,9 @@
   LOperand* value = UseTempRegister(instr->value());  // changed by clamp.
   LOperand* key = UseRegister(instr->key());
 
-  return new LStorePixelArrayElement(external_pointer, key, value);
+  return new LStoreKeyedSpecializedArrayElement(external_pointer,
+                                                key,
+                                                value);
 }
 
 
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 50650c1..77aabaf 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -122,9 +122,10 @@
   V(LoadGlobal)                                 \
   V(LoadKeyedFastElement)                       \
   V(LoadKeyedGeneric)                           \
+  V(LoadKeyedSpecializedArrayElement)           \
   V(LoadNamedField)                             \
+  V(LoadNamedFieldPolymorphic)                  \
   V(LoadNamedGeneric)                           \
-  V(LoadPixelArrayElement)                      \
   V(ModI)                                       \
   V(MulI)                                       \
   V(NumberTagD)                                 \
@@ -146,9 +147,9 @@
   V(StoreGlobal)                                \
   V(StoreKeyedFastElement)                      \
   V(StoreKeyedGeneric)                          \
+  V(StoreKeyedSpecializedArrayElement)          \
   V(StoreNamedField)                            \
   V(StoreNamedGeneric)                          \
-  V(StorePixelArrayElement)                     \
   V(StringCharCodeAt)                           \
   V(StringCharFromCode)                         \
   V(StringLength)                               \
@@ -1148,6 +1149,19 @@
 };
 
 
+class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LLoadNamedFieldPolymorphic(LOperand* object) {
+    inputs_[0] = object;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
+  DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
+
+  LOperand* object() { return inputs_[0]; }
+};
+
+
 class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LLoadNamedGeneric(LOperand* object) {
@@ -1211,19 +1225,23 @@
 };
 
 
-class LLoadPixelArrayElement: public LTemplateInstruction<1, 2, 0> {
+class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
  public:
-  LLoadPixelArrayElement(LOperand* external_pointer, LOperand* key) {
+  LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
+                                    LOperand* key) {
     inputs_[0] = external_pointer;
     inputs_[1] = key;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
-                               "load-pixel-array-element")
-  DECLARE_HYDROGEN_ACCESSOR(LoadPixelArrayElement)
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+                               "load-keyed-specialized-array-element")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
+  ExternalArrayType array_type() const {
+    return hydrogen()->array_type();
+  }
 };
 
 
@@ -1628,25 +1646,29 @@
   LOperand* value() { return inputs_[2]; }
 };
 
-class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
  public:
-  LStorePixelArrayElement(LOperand* external_pointer,
-                          LOperand* key,
-                          LOperand* val) {
+  LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
+                                     LOperand* key,
+                                     LOperand* val) {
     inputs_[0] = external_pointer;
     inputs_[1] = key;
     inputs_[2] = val;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
-                               "store-pixel-array-element")
-  DECLARE_HYDROGEN_ACCESSOR(StorePixelArrayElement)
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+                               "store-keyed-specialized-array-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
+  ExternalArrayType array_type() const {
+    return hydrogen()->array_type();
+  }
 };
 
+
 class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> {
  public:
   LStringCharCodeAt(LOperand* string, LOperand* index) {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 48a9f7f..75406cf 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -94,6 +94,7 @@
   code->set_stack_slots(StackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
   PopulateDeoptimizationData(code);
+  Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
 }
 
 
@@ -1085,16 +1086,25 @@
   ASSERT(left->Equals(instr->result()));
   ASSERT(left->IsRegister());
   Register result = ToRegister(left);
-  Register right_reg = EmitLoadRegister(right, ip);
+  Operand right_operand(no_reg);
+
+  if (right->IsStackSlot() || right->IsArgument()) {
+    Register right_reg = EmitLoadRegister(right, ip);
+    right_operand = Operand(right_reg);
+  } else {
+    ASSERT(right->IsRegister() || right->IsConstantOperand());
+    right_operand = ToOperand(right);
+  }
+
   switch (instr->op()) {
     case Token::BIT_AND:
-      __ and_(result, ToRegister(left), Operand(right_reg));
+      __ and_(result, ToRegister(left), right_operand);
       break;
     case Token::BIT_OR:
-      __ orr(result, ToRegister(left), Operand(right_reg));
+      __ orr(result, ToRegister(left), right_operand);
       break;
     case Token::BIT_XOR:
-      __ eor(result, ToRegister(left), Operand(right_reg));
+      __ eor(result, ToRegister(left), right_operand);
       break;
     default:
       UNREACHABLE();
@@ -1163,11 +1173,21 @@
 
 
 void LCodeGen::DoSubI(LSubI* instr) {
-  Register left = ToRegister(instr->InputAt(0));
-  Register right = EmitLoadRegister(instr->InputAt(1), ip);
-  ASSERT(instr->InputAt(0)->Equals(instr->result()));
-  __ sub(left, left, right, SetCC);
-  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+  LOperand* left = instr->InputAt(0);
+  LOperand* right = instr->InputAt(1);
+  ASSERT(left->Equals(instr->result()));
+  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+  SBit set_cond = can_overflow ? SetCC : LeaveCC;
+
+  if (right->IsStackSlot() || right->IsArgument()) {
+    Register right_reg = EmitLoadRegister(right, ip);
+    __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
+  } else {
+    ASSERT(right->IsRegister() || right->IsConstantOperand());
+    __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
+  }
+
+  if (can_overflow) {
     DeoptimizeIf(vs, instr->environment());
   }
 }
@@ -1256,11 +1276,18 @@
   LOperand* left = instr->InputAt(0);
   LOperand* right = instr->InputAt(1);
   ASSERT(left->Equals(instr->result()));
+  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+  SBit set_cond = can_overflow ? SetCC : LeaveCC;
 
-  Register right_reg = EmitLoadRegister(right, ip);
-  __ add(ToRegister(left), ToRegister(left), Operand(right_reg), SetCC);
+  if (right->IsStackSlot() || right->IsArgument()) {
+    Register right_reg = EmitLoadRegister(right, ip);
+    __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond);
+  } else {
+    ASSERT(right->IsRegister() || right->IsConstantOperand());
+    __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond);
+  }
 
-  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+  if (can_overflow) {
     DeoptimizeIf(vs, instr->environment());
   }
 }
@@ -2203,14 +2230,77 @@
 }
 
 
+void LCodeGen::EmitLoadField(Register result,
+                             Register object,
+                             Handle<Map> type,
+                             Handle<String> name) {
+  LookupResult lookup;
+  type->LookupInDescriptors(NULL, *name, &lookup);
+  ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
+  int index = lookup.GetLocalFieldIndexFromMap(*type);
+  int offset = index * kPointerSize;
+  if (index < 0) {
+    // Negative property indices are in-object properties, indexed
+    // from the end of the fixed part of the object.
+    __ ldr(result, FieldMemOperand(object, offset + type->instance_size()));
+  } else {
+    // Non-negative property indices are in the properties array.
+    __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
+    __ ldr(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
+  }
+}
+
+
+void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
+  Register object = ToRegister(instr->object());
+  Register result = ToRegister(instr->result());
+  Register scratch = scratch0();
+  int map_count = instr->hydrogen()->types()->length();
+  Handle<String> name = instr->hydrogen()->name();
+  if (map_count == 0) {
+    ASSERT(instr->hydrogen()->need_generic());
+    __ mov(r2, Operand(name));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+    CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  } else {
+    Label done;
+    __ ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+    for (int i = 0; i < map_count - 1; ++i) {
+      Handle<Map> map = instr->hydrogen()->types()->at(i);
+      Label next;
+      __ cmp(scratch, Operand(map));
+      __ b(ne, &next);
+      EmitLoadField(result, object, map, name);
+      __ b(&done);
+      __ bind(&next);
+    }
+    Handle<Map> map = instr->hydrogen()->types()->last();
+    __ cmp(scratch, Operand(map));
+    if (instr->hydrogen()->need_generic()) {
+      Label generic;
+      __ b(ne, &generic);
+      EmitLoadField(result, object, map, name);
+      __ b(&done);
+      __ bind(&generic);
+      __ mov(r2, Operand(name));
+      Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+      CallCode(ic, RelocInfo::CODE_TARGET, instr);
+    } else {
+      DeoptimizeIf(ne, instr->environment());
+      EmitLoadField(result, object, map, name);
+    }
+    __ bind(&done);
+  }
+}
+
+
 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
   ASSERT(ToRegister(instr->object()).is(r0));
   ASSERT(ToRegister(instr->result()).is(r0));
 
   // Name is always in r2.
   __ mov(r2, Operand(instr->name()));
-  Handle<Code> ic(
-      isolate()->builtins()->builtin(Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2327,7 +2417,10 @@
 }
 
 
-void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
+void LCodeGen::DoLoadKeyedSpecializedArrayElement(
+    LLoadKeyedSpecializedArrayElement* instr) {
+  ASSERT(instr->array_type() == kExternalPixelArray);
+
   Register external_pointer = ToRegister(instr->external_pointer());
   Register key = ToRegister(instr->key());
   Register result = ToRegister(instr->result());
@@ -2341,8 +2434,7 @@
   ASSERT(ToRegister(instr->object()).is(r1));
   ASSERT(ToRegister(instr->key()).is(r0));
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2908,8 +3000,7 @@
   ASSERT(ToRegister(instr->InputAt(0)).is(r1));
   ASSERT(ToRegister(instr->result()).is(r0));
 
-  Handle<Code> builtin(isolate()->builtins()->builtin(
-      Builtins::JSConstructCall));
+  Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
   __ mov(r0, Operand(instr->arity()));
   CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
 }
@@ -2958,9 +3049,9 @@
 
   // Name is always in r2.
   __ mov(r2, Operand(instr->name()));
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      info_->is_strict() ? Builtins::StoreIC_Initialize_Strict
-                         : Builtins::StoreIC_Initialize));
+  Handle<Code> ic = info_->is_strict()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2997,7 +3088,10 @@
 }
 
 
-void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) {
+void LCodeGen::DoStoreKeyedSpecializedArrayElement(
+    LStoreKeyedSpecializedArrayElement* instr) {
+  ASSERT(instr->array_type() == kExternalPixelArray);
+
   Register external_pointer = ToRegister(instr->external_pointer());
   Register key = ToRegister(instr->key());
   Register value = ToRegister(instr->value());
@@ -3013,9 +3107,9 @@
   ASSERT(ToRegister(instr->key()).is(r1));
   ASSERT(ToRegister(instr->value()).is(r0));
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
-                         : Builtins::KeyedStoreIC_Initialize));
+  Handle<Code> ic = info_->is_strict()
+      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+      : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index da34176..caa85d2 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -264,6 +264,11 @@
   // Caller should branch on equal condition.
   void EmitIsConstructCall(Register temp1, Register temp2);
 
+  void EmitLoadField(Register result,
+                     Register object,
+                     Handle<Map> type,
+                     Handle<String> name);
+
   LChunk* const chunk_;
   MacroAssembler* const masm_;
   CompilationInfo* const info_;
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 626c46f..3a1a8b6 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -903,8 +903,7 @@
     }
 
     Handle<Code> adaptor =
-        Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::ArgumentsAdaptorTrampoline));
+        isolate()->builtins()->ArgumentsAdaptorTrampoline();
     if (flag == CALL_FUNCTION) {
       if (call_wrapper != NULL) {
         call_wrapper->BeforeCall(CallSize(adaptor, RelocInfo::CODE_TARGET));
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index c548aab..30f1b38 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -102,8 +102,9 @@
                                              Register scratch0,
                                              Register scratch1) {
   ASSERT(name->IsSymbol());
-  __ IncrementCounter(COUNTERS->negative_lookups(), 1, scratch0, scratch1);
-  __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1, scratch0, scratch1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
+  __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
 
   Label done;
 
@@ -199,7 +200,7 @@
     }
   }
   __ bind(&done);
-  __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1, scratch0, scratch1);
+  __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
 }
 
 
@@ -210,7 +211,7 @@
                               Register scratch,
                               Register extra,
                               Register extra2) {
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = masm->isolate();
   Label miss;
 
   // Make sure that code is valid. The shifting code relies on the
@@ -288,14 +289,15 @@
 
 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
     MacroAssembler* masm, int index, Register prototype, Label* miss) {
+  Isolate* isolate = masm->isolate();
   // Check we're still in the same context.
   __ ldr(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  __ Move(ip, Isolate::Current()->global());
+  __ Move(ip, isolate->global());
   __ cmp(prototype, ip);
   __ b(ne, miss);
   // Get the global function with the given index.
-  JSFunction* function = JSFunction::cast(
-      Isolate::Current()->global_context()->get(index));
+  JSFunction* function =
+      JSFunction::cast(isolate->global_context()->get(index));
   // Load its initial map. The global functions all have initial maps.
   __ Move(prototype, Handle<Map>(function->initial_map()));
   // Load the prototype from the initial map.
@@ -510,9 +512,9 @@
   ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
   Code* code = NULL;
   if (kind == Code::LOAD_IC) {
-    code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss);
+    code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
   } else {
-    code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
+    code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
   }
 
   Handle<Code> ic(code);
@@ -736,6 +738,8 @@
     ASSERT(optimization.is_constant_call());
     ASSERT(!lookup->holder()->IsGlobalObject());
 
+    Counters* counters = masm->isolate()->counters();
+
     int depth1 = kInvalidProtoDepth;
     int depth2 = kInvalidProtoDepth;
     bool can_do_fast_api_call = false;
@@ -753,11 +757,11 @@
                             (depth2 != kInvalidProtoDepth);
     }
 
-    __ IncrementCounter(COUNTERS->call_const_interceptor(), 1,
+    __ IncrementCounter(counters->call_const_interceptor(), 1,
                       scratch1, scratch2);
 
     if (can_do_fast_api_call) {
-      __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1,
+      __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1,
                           scratch1, scratch2);
       ReserveSpaceForFastApiCall(masm, scratch1);
     }
@@ -949,7 +953,7 @@
                             Register fval,
                             Register scratch1,
                             Register scratch2) {
-  if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+  if (masm->isolate()->cpu_features()->IsSupported(VFP3)) {
     CpuFeatures::Scope scope(VFP3);
     __ vmov(s0, ival);
     __ add(scratch1, dst, Operand(wordoffset, LSL, 2));
@@ -1161,7 +1165,7 @@
   __ b(ne, miss);
 
   // Log the check depth.
-  LOG(Isolate::Current(), IntEvent("check-maps-depth", depth + 1));
+  LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
 
   // Perform security check for access to the global object.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
@@ -1497,7 +1501,7 @@
 
 
 MaybeObject* CallStubCompiler::GenerateMissBranch() {
-  MaybeObject* maybe_obj = Isolate::Current()->stub_cache()->ComputeCallMiss(
+  MaybeObject* maybe_obj = masm()->isolate()->stub_cache()->ComputeCallMiss(
       arguments().immediate(), kind_);
   Object* obj;
   if (!maybe_obj->ToObject(&obj)) return maybe_obj;
@@ -2044,7 +2048,7 @@
   //  -- sp[argc * 4]           : receiver
   // -----------------------------------
 
-  if (!Isolate::Current()->cpu_features()->IsSupported(VFP3))
+  if (!masm()->isolate()->cpu_features()->IsSupported(VFP3))
       return HEAP->undefined_value();
 
   CpuFeatures::Scope scope_vfp3(VFP3);
@@ -2287,14 +2291,18 @@
     JSGlobalPropertyCell* cell,
     JSFunction* function,
     String* name) {
+  Isolate* isolate = masm()->isolate();
+  Heap* heap = isolate->heap();
+  Counters* counters = isolate->counters();
+
   ASSERT(optimization.is_simple_api_call());
   // Bail out if object is a global object as we don't want to
   // repatch it to global receiver.
-  if (object->IsGlobalObject()) return HEAP->undefined_value();
-  if (cell != NULL) return HEAP->undefined_value();
+  if (object->IsGlobalObject()) return heap->undefined_value();
+  if (cell != NULL) return heap->undefined_value();
   int depth = optimization.GetPrototypeDepthOfExpectedType(
             JSObject::cast(object), holder);
-  if (depth == kInvalidProtoDepth) return HEAP->undefined_value();
+  if (depth == kInvalidProtoDepth) return heap->undefined_value();
 
   Label miss, miss_before_stack_reserved;
 
@@ -2308,8 +2316,8 @@
   __ tst(r1, Operand(kSmiTagMask));
   __ b(eq, &miss_before_stack_reserved);
 
-  __ IncrementCounter(COUNTERS->call_const(), 1, r0, r3);
-  __ IncrementCounter(COUNTERS->call_const_fast_api(), 1, r0, r3);
+  __ IncrementCounter(counters->call_const(), 1, r0, r3);
+  __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3);
 
   ReserveSpaceForFastApiCall(masm(), r0);
 
@@ -2371,7 +2379,8 @@
   SharedFunctionInfo* function_info = function->shared();
   switch (check) {
     case RECEIVER_MAP_CHECK:
-      __ IncrementCounter(COUNTERS->call_const(), 1, r0, r3);
+      __ IncrementCounter(masm()->isolate()->counters()->call_const(),
+                          1, r0, r3);
 
       // Check that the maps haven't changed.
       CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
@@ -2558,7 +2567,8 @@
   __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
 
   // Jump to the cached code (tail call).
-  __ IncrementCounter(COUNTERS->call_global_inline(), 1, r3, r4);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->call_global_inline(), 1, r3, r4);
   ASSERT(function->is_compiled());
   Handle<Code> code(function->code());
   ParameterCount expected(function->shared()->formal_parameter_count());
@@ -2575,7 +2585,7 @@
 
   // Handle call cache miss.
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1, r1, r3);
+  __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3);
   MaybeObject* maybe_result = GenerateMissBranch();
   if (maybe_result->IsFailure()) return maybe_result;
 
@@ -2603,8 +2613,7 @@
                      r1, r2, r3,
                      &miss);
   __ bind(&miss);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2653,8 +2662,7 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2703,8 +2711,7 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2741,14 +2748,14 @@
   // Store the value in the cell.
   __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset));
 
-  __ IncrementCounter(COUNTERS->named_store_global_inline(), 1, r4, r3);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3);
   __ Ret();
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1, r4, r3);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3);
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2930,11 +2937,12 @@
   }
 
   __ mov(r0, r4);
-  __ IncrementCounter(COUNTERS->named_load_global_stub(), 1, r1, r3);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
   __ Ret();
 
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1, r1, r3);
+  __ IncrementCounter(counters->named_load_global_stub_miss(), 1, r1, r3);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
 
   // Return the generated code.
@@ -3079,7 +3087,9 @@
   //  -- r1    : receiver
   // -----------------------------------
   Label miss;
-  __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1, r2, r3);
+
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_string_length(), 1, r2, r3);
 
   // Check the key is the cached one.
   __ cmp(r0, Operand(Handle<String>(name)));
@@ -3087,7 +3097,7 @@
 
   GenerateLoadStringLength(masm(), r1, r2, r3, &miss, true);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1, r2, r3);
+  __ DecrementCounter(counters->keyed_load_string_length(), 1, r2, r3);
 
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
@@ -3103,7 +3113,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1, r2, r3);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
 
   // Check the name hasn't changed.
   __ cmp(r0, Operand(Handle<String>(name)));
@@ -3111,7 +3122,7 @@
 
   GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1, r2, r3);
+  __ DecrementCounter(counters->keyed_load_function_prototype(), 1, r2, r3);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   return GetCode(CALLBACKS, name);
@@ -3179,7 +3190,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_store_field(), 1, r3, r4);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4);
 
   // Check that the name has not changed.
   __ cmp(r1, Operand(Handle<String>(name)));
@@ -3195,10 +3207,8 @@
                      &miss);
   __ bind(&miss);
 
-  __ DecrementCounter(COUNTERS->keyed_store_field(), 1, r3, r4);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedStoreIC_Miss));
-
+  __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4);
+  Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -3268,8 +3278,7 @@
   __ Ret();
 
   __ bind(&miss);
-  Handle<Code> ic(
-      Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -3405,17 +3414,16 @@
   // Remove caller arguments and receiver from the stack and return.
   __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2));
   __ add(sp, sp, Operand(kPointerSize));
-  __ IncrementCounter(COUNTERS->constructed_objects(), 1, r1, r2);
-  __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1, r1, r2);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->constructed_objects(), 1, r1, r2);
+  __ IncrementCounter(counters->constructed_objects_stub(), 1, r1, r2);
   __ Jump(lr);
 
   // Jump to the generic stub in case the specialized code cannot handle the
   // construction.
   __ bind(&generic_stub_call);
-  Code* code = Isolate::Current()->builtins()->builtin(
-      Builtins::JSConstructStubGeneric);
-  Handle<Code> generic_construct_stub(code);
-  __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
+  Handle<Code> code = masm()->isolate()->builtins()->JSConstructStubGeneric();
+  __ Jump(code, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
   return GetCode();
@@ -3502,7 +3510,7 @@
       __ ldr(value, MemOperand(r3, key, LSL, 1));
       break;
     case kExternalFloatArray:
-      if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+      if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
         CpuFeatures::Scope scope(VFP3);
         __ add(r2, r3, Operand(key, LSL, 1));
         __ vldr(s0, r2, 0);
@@ -3541,7 +3549,7 @@
     // Now we can use r0 for the result as key is not needed any more.
     __ mov(r0, r5);
 
-    if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+    if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
       CpuFeatures::Scope scope(VFP3);
       __ vmov(s0, value);
       __ vcvt_f64_s32(d0, s0);
@@ -3556,7 +3564,7 @@
     // The test is different for unsigned int values. Since we need
     // the value to be in the range of a positive smi, we can't
     // handle either of the top two bits being set in the value.
-    if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+    if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
       CpuFeatures::Scope scope(VFP3);
       Label box_int, done;
       __ tst(value, Operand(0xC0000000));
@@ -3620,7 +3628,7 @@
   } else if (array_type == kExternalFloatArray) {
     // For the floating-point array type, we need to always allocate a
     // HeapNumber.
-    if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+    if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
       CpuFeatures::Scope scope(VFP3);
       // Allocate a HeapNumber for the result. Don't use r0 and r1 as
       // AllocateHeapNumber clobbers all registers - also when jumping due to
@@ -3696,7 +3704,9 @@
 
   // Slow case, key and receiver still in r0 and r1.
   __ bind(&slow);
-  __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1, r2, r3);
+  __ IncrementCounter(
+      masm()->isolate()->counters()->keyed_load_external_array_slow(),
+      1, r2, r3);
 
   // ---------- S t a t e --------------
   //  -- lr     : return address
@@ -3811,10 +3821,9 @@
     // The WebGL specification leaves the behavior of storing NaN and
     // +/-Infinity into integer arrays basically undefined. For more
     // reproducible behavior, convert these to zero.
-    if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
+    if (masm()->isolate()->cpu_features()->IsSupported(VFP3)) {
       CpuFeatures::Scope scope(VFP3);
 
-
       if (array_type == kExternalFloatArray) {
         // vldr requires offset to be a multiple of 4 so we can not
         // include -kHeapObjectTag into it.
diff --git a/src/arm/virtual-frame-arm.cc b/src/arm/virtual-frame-arm.cc
index c4919b8..a852d6e 100644
--- a/src/arm/virtual-frame-arm.cc
+++ b/src/arm/virtual-frame-arm.cc
@@ -322,7 +322,7 @@
 
 void VirtualFrame::CallLoadIC(Handle<String> name, RelocInfo::Mode mode) {
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+      Builtins::kLoadIC_Initialize));
   PopToR0();
   SpillAll();
   __ mov(r2, Operand(name));
@@ -334,8 +334,8 @@
                                bool is_contextual,
                                StrictModeFlag strict_mode) {
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      (strict_mode == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
-                                   : Builtins::StoreIC_Initialize));
+      (strict_mode == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+                                   : Builtins::kStoreIC_Initialize));
   PopToR0();
   RelocInfo::Mode mode;
   if (is_contextual) {
@@ -354,7 +354,7 @@
 
 void VirtualFrame::CallKeyedLoadIC() {
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+      Builtins::kKeyedLoadIC_Initialize));
   PopToR1R0();
   SpillAll();
   CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
@@ -363,8 +363,8 @@
 
 void VirtualFrame::CallKeyedStoreIC(StrictModeFlag strict_mode) {
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      (strict_mode == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
-                                   : Builtins::KeyedStoreIC_Initialize));
+      (strict_mode == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+                                   : Builtins::kKeyedStoreIC_Initialize));
   PopToR1R0();
   SpillAll();
   EmitPop(r2);
@@ -388,7 +388,7 @@
       break;
     case Code::BUILTIN:
       ASSERT(*code == Isolate::Current()->builtins()->builtin(
-          Builtins::JSConstructCall));
+          Builtins::kJSConstructCall));
       break;
     default:
       UNREACHABLE();
diff --git a/src/assembler.cc b/src/assembler.cc
index c6d1cfa..58ec8ca 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -140,6 +140,7 @@
 
 const int kSmallPCDeltaBits = kBitsPerByte - kTagBits;
 const int kSmallPCDeltaMask = (1 << kSmallPCDeltaBits) - 1;
+const int RelocInfo::kMaxSmallPCDelta = kSmallPCDeltaMask;
 
 const int kVariableLengthPCJumpTopTag = 1;
 const int kChunkBits = 7;
@@ -217,7 +218,6 @@
 #ifdef DEBUG
   byte* begin_pos = pos_;
 #endif
-  COUNTERS->reloc_info_count()->Increment();
   ASSERT(rinfo->pc() - last_pc_ >= 0);
   ASSERT(RelocInfo::NUMBER_OF_MODES <= kMaxRelocModes);
   // Use unsigned delta-encoding for pc.
diff --git a/src/assembler.h b/src/assembler.h
index 8147227..62fe04d 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -205,6 +205,9 @@
   // The maximum size for a call instruction including pc-jump.
   static const int kMaxCallSize = 6;
 
+  // The maximum pc delta that will use the short encoding.
+  static const int kMaxSmallPCDelta;
+
   enum Mode {
     // Please note the order is important (see IsCodeTarget, IsGCRelocMode).
     CONSTRUCT_CALL,  // code target that is a call to a JavaScript constructor.
diff --git a/src/ast.cc b/src/ast.cc
index 3912773..8434357 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -527,12 +527,12 @@
   // Record type feedback from the oracle in the AST.
   is_monomorphic_ = oracle->LoadIsMonomorphic(this);
   if (key()->IsPropertyName()) {
-    if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_ArrayLength)) {
+    if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
       is_array_length_ = true;
-    } else if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_StringLength)) {
+    } else if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_StringLength)) {
       is_string_length_ = true;
     } else if (oracle->LoadIsBuiltin(this,
-                                     Builtins::LoadIC_FunctionPrototype)) {
+                                     Builtins::kLoadIC_FunctionPrototype)) {
       is_function_prototype_ = true;
     } else {
       Literal* lit_key = key()->AsLiteral();
@@ -541,7 +541,7 @@
       ZoneMapList* types = oracle->LoadReceiverTypes(this, name);
       receiver_types_ = types;
     }
-  } else if (oracle->LoadIsBuiltin(this, Builtins::KeyedLoadIC_String)) {
+  } else if (oracle->LoadIsBuiltin(this, Builtins::kKeyedLoadIC_String)) {
     is_string_access_ = true;
   } else if (is_monomorphic_) {
     monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this);
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 015e702..e7c0554 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -445,7 +445,7 @@
   // --- E m p t y ---
   Handle<Code> code =
       Handle<Code>(Isolate::Current()->builtins()->builtin(
-          Builtins::EmptyFunction));
+          Builtins::kEmptyFunction));
   empty_function->set_code(*code);
   empty_function->shared()->set_code(*code);
   Handle<String> source = FACTORY->NewStringFromAscii(CStrVector("() {}"));
@@ -587,9 +587,9 @@
 
   // Create the ThrowTypeError function instances.
   Handle<JSFunction> arguments_throw =
-      CreateThrowTypeErrorFunction(Builtins::StrictFunctionArguments);
+      CreateThrowTypeErrorFunction(Builtins::kStrictFunctionArguments);
   Handle<JSFunction> caller_throw =
-      CreateThrowTypeErrorFunction(Builtins::StrictFunctionCaller);
+      CreateThrowTypeErrorFunction(Builtins::kStrictFunctionCaller);
 
   // Complete the callback fixed arrays.
   arguments->set(0, *arguments_throw);
@@ -673,7 +673,7 @@
   if (js_global_template.is_null()) {
     Handle<String> name = Handle<String>(HEAP->empty_symbol());
     Handle<Code> code = Handle<Code>(Isolate::Current()->builtins()->builtin(
-        Builtins::Illegal));
+        Builtins::kIllegal));
     js_global_function =
         FACTORY->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
                              JSGlobalObject::kSize, code, true);
@@ -707,7 +707,7 @@
   if (global_template.IsEmpty()) {
     Handle<String> name = Handle<String>(HEAP->empty_symbol());
     Handle<Code> code = Handle<Code>(Isolate::Current()->builtins()->builtin(
-        Builtins::Illegal));
+        Builtins::kIllegal));
     global_proxy_function =
         FACTORY->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
                              JSGlobalProxy::kSize, code, true);
@@ -796,15 +796,15 @@
 
   // Install global Function object
   InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
-                  empty_function, Builtins::Illegal, true);  // ECMA native.
+                  empty_function, Builtins::kIllegal, true);  // ECMA native.
 
   {  // --- A r r a y ---
     Handle<JSFunction> array_function =
         InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
                         Isolate::Current()->initial_object_prototype(),
-                        Builtins::ArrayCode, true);
+                        Builtins::kArrayCode, true);
     array_function->shared()->set_construct_stub(
-        Isolate::Current()->builtins()->builtin(Builtins::ArrayConstructCode));
+        Isolate::Current()->builtins()->builtin(Builtins::kArrayConstructCode));
     array_function->shared()->DontAdaptArguments();
 
     // This seems a bit hackish, but we need to make sure Array.length
@@ -832,7 +832,7 @@
     Handle<JSFunction> number_fun =
         InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
                         Isolate::Current()->initial_object_prototype(),
-                        Builtins::Illegal, true);
+                        Builtins::kIllegal, true);
     global_context()->set_number_function(*number_fun);
   }
 
@@ -840,7 +840,7 @@
     Handle<JSFunction> boolean_fun =
         InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
                         Isolate::Current()->initial_object_prototype(),
-                        Builtins::Illegal, true);
+                        Builtins::kIllegal, true);
     global_context()->set_boolean_function(*boolean_fun);
   }
 
@@ -848,9 +848,10 @@
     Handle<JSFunction> string_fun =
         InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
                         Isolate::Current()->initial_object_prototype(),
-                        Builtins::Illegal, true);
+                        Builtins::kIllegal, true);
     string_fun->shared()->set_construct_stub(
-        Isolate::Current()->builtins()->builtin(Builtins::StringConstructCode));
+        Isolate::Current()->builtins()->builtin(
+            Builtins::kStringConstructCode));
     global_context()->set_string_function(*string_fun);
     // Add 'length' property to strings.
     Handle<DescriptorArray> string_descriptors =
@@ -872,7 +873,7 @@
     Handle<JSFunction> date_fun =
         InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
                         Isolate::Current()->initial_object_prototype(),
-                        Builtins::Illegal, true);
+                        Builtins::kIllegal, true);
 
     global_context()->set_date_function(*date_fun);
   }
@@ -883,7 +884,7 @@
     Handle<JSFunction> regexp_fun =
         InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
                         Isolate::Current()->initial_object_prototype(),
-                        Builtins::Illegal, true);
+                        Builtins::kIllegal, true);
     global_context()->set_regexp_function(*regexp_fun);
 
     ASSERT(regexp_fun->has_initial_map());
@@ -968,7 +969,7 @@
     // class_name equals 'Arguments'.
     Handle<String> symbol = FACTORY->LookupAsciiSymbol("Arguments");
     Handle<Code> code = Handle<Code>(
-        Isolate::Current()->builtins()->builtin(Builtins::Illegal));
+        Isolate::Current()->builtins()->builtin(Builtins::kIllegal));
     Handle<JSObject> prototype =
         Handle<JSObject>(
             JSObject::cast(global_context()->object_function()->prototype()));
@@ -1023,9 +1024,9 @@
     Handle<FixedArray> caller = FACTORY->NewFixedArray(2, TENURED);
 
     Handle<JSFunction> callee_throw =
-        CreateThrowTypeErrorFunction(Builtins::StrictArgumentsCallee);
+        CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCallee);
     Handle<JSFunction> caller_throw =
-        CreateThrowTypeErrorFunction(Builtins::StrictArgumentsCaller);
+        CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCaller);
 
     // Install the ThrowTypeError functions.
     callee->set(0, *callee_throw);
@@ -1088,7 +1089,7 @@
   {  // --- context extension
     // Create a function for the context extension objects.
     Handle<Code> code = Handle<Code>(
-        Isolate::Current()->builtins()->builtin(Builtins::Illegal));
+        Isolate::Current()->builtins()->builtin(Builtins::kIllegal));
     Handle<JSFunction> context_extension_fun =
         FACTORY->NewFunction(FACTORY->empty_symbol(),
                              JS_CONTEXT_EXTENSION_OBJECT_TYPE,
@@ -1106,7 +1107,7 @@
     // Setup the call-as-function delegate.
     Handle<Code> code =
         Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::HandleApiCallAsFunction));
+            Builtins::kHandleApiCallAsFunction));
     Handle<JSFunction> delegate =
         FACTORY->NewFunction(FACTORY->empty_symbol(), JS_OBJECT_TYPE,
                              JSObject::kHeaderSize, code, true);
@@ -1118,7 +1119,7 @@
     // Setup the call-as-constructor delegate.
     Handle<Code> code =
         Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::HandleApiCallAsConstructor));
+            Builtins::kHandleApiCallAsConstructor));
     Handle<JSFunction> delegate =
         FACTORY->NewFunction(FACTORY->empty_symbol(), JS_OBJECT_TYPE,
                              JSObject::kHeaderSize, code, true);
@@ -1251,7 +1252,7 @@
   // JavaScript builtins, a reference to the builtins object
   // (itself) and a reference to the global_context directly in the object.
   Handle<Code> code = Handle<Code>(
-      isolate->builtins()->builtin(Builtins::Illegal));
+      isolate->builtins()->builtin(Builtins::kIllegal));
   Handle<JSFunction> builtins_fun =
       factory->NewFunction(factory->empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
                            JSBuiltinsObject::kSize, code, true);
@@ -1296,7 +1297,7 @@
     Handle<JSFunction> script_fun =
         InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
                         isolate->initial_object_prototype(),
-                        Builtins::Illegal, false);
+                        Builtins::kIllegal, false);
     Handle<JSObject> prototype =
         factory->NewJSObject(isolate->object_function(), TENURED);
     SetPrototype(script_fun, prototype);
@@ -1421,7 +1422,7 @@
         InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
                         JSValue::kSize,
                         isolate->initial_object_prototype(),
-                        Builtins::Illegal, false);
+                        Builtins::kIllegal, false);
     Handle<JSObject> prototype =
         factory->NewJSObject(isolate->object_function(), TENURED);
     SetPrototype(opaque_reference_fun, prototype);
@@ -1443,14 +1444,14 @@
                         JS_ARRAY_TYPE,
                         JSArray::kSize,
                         isolate->initial_object_prototype(),
-                        Builtins::ArrayCode,
+                        Builtins::kArrayCode,
                         true);
     Handle<JSObject> prototype =
         factory->NewJSObject(isolate->object_function(), TENURED);
     SetPrototype(array_function, prototype);
 
     array_function->shared()->set_construct_stub(
-        isolate->builtins()->builtin(Builtins::ArrayConstructCode));
+        isolate->builtins()->builtin(Builtins::kArrayConstructCode));
     array_function->shared()->DontAdaptArguments();
 
     // Make "length" magic on instances.
@@ -1505,12 +1506,12 @@
     Handle<JSFunction> call =
         InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
                         Handle<JSObject>::null(),
-                        Builtins::FunctionCall,
+                        Builtins::kFunctionCall,
                         false);
     Handle<JSFunction> apply =
         InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
                         Handle<JSObject>::null(),
-                        Builtins::FunctionApply,
+                        Builtins::kFunctionApply,
                         false);
 
     // Make sure that Function.prototype.call appears to be compiled.
@@ -1936,6 +1937,7 @@
           break;
         }
         case MAP_TRANSITION:
+        case EXTERNAL_ARRAY_TRANSITION:
         case CONSTANT_TRANSITION:
         case NULL_DESCRIPTOR:
           // Ignore non-properties.
diff --git a/src/builtins.cc b/src/builtins.cc
index 4604872..72f9d57 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1576,7 +1576,7 @@
     functions->generator = FUNCTION_ADDR(Generate_##aname);                 \
     functions->c_code = NULL;                                               \
     functions->s_name = #aname;                                             \
-    functions->name = aname;                                                \
+    functions->name = k##aname;                                             \
     functions->flags = Code::ComputeFlags(Code::kind,                       \
                                           NOT_IN_LOOP,                      \
                                           state,                            \
@@ -1685,4 +1685,23 @@
 }
 
 
+#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore)               \
+Handle<Code> Builtins::name() {                               \
+  Code** code_address =                                       \
+      reinterpret_cast<Code**>(builtin_address(k##name));     \
+  return Handle<Code>(code_address);                          \
+}
+#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
+Handle<Code> Builtins::name() {                             \
+  Code** code_address =                                     \
+      reinterpret_cast<Code**>(builtin_address(k##name));   \
+  return Handle<Code>(code_address);                        \
+}
+BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
+BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
+BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
+#undef DEFINE_BUILTIN_ACCESSOR_C
+#undef DEFINE_BUILTIN_ACCESSOR_A
+
+
 } }  // namespace v8::internal
diff --git a/src/builtins.h b/src/builtins.h
index 4dd6111..bc0facb 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -260,8 +260,8 @@
   const char* Lookup(byte* pc);
 
   enum Name {
-#define DEF_ENUM_C(name, ignore) name,
-#define DEF_ENUM_A(name, kind, state, extra) name,
+#define DEF_ENUM_C(name, ignore) k##name,
+#define DEF_ENUM_A(name, kind, state, extra) k##name,
     BUILTIN_LIST_C(DEF_ENUM_C)
     BUILTIN_LIST_A(DEF_ENUM_A)
     BUILTIN_LIST_DEBUG_A(DEF_ENUM_A)
@@ -284,6 +284,15 @@
     id_count
   };
 
+#define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name();
+#define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
+  Handle<Code> name();
+  BUILTIN_LIST_C(DECLARE_BUILTIN_ACCESSOR_C)
+  BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A)
+  BUILTIN_LIST_DEBUG_A(DECLARE_BUILTIN_ACCESSOR_A)
+#undef DECLARE_BUILTIN_ACCESSOR_C
+#undef DECLARE_BUILTIN_ACCESSOR_A
+
   Code* builtin(Name name) {
     // Code::cast cannot be used here since we access builtins
     // during the marking phase of mark sweep. See IC::Clear.
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index cfe9309..b370c65 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -48,7 +48,7 @@
 
 void CodeStub::GenerateCode(MacroAssembler* masm) {
   // Update the static counter each time a new code stub is generated.
-  COUNTERS->code_stubs()->Increment();
+  masm->isolate()->counters()->code_stubs()->Increment();
 
   // Nested stubs are not allowed for leafs.
   AllowStubCallsScope allow_scope(masm, AllowsStubCalls());
@@ -62,9 +62,11 @@
 void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
   code->set_major_key(MajorKey());
 
-  PROFILE(ISOLATE, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
+  Isolate* isolate = masm->isolate();
+  PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
   GDBJIT(AddCode(GDBJITInterface::STUB, GetName(), code));
-  COUNTERS->total_stubs_code_size()->Increment(code->instruction_size());
+  Counters* counters = isolate->counters();
+  counters->total_stubs_code_size()->Increment(code->instruction_size());
 
 #ifdef ENABLE_DISASSEMBLER
   if (FLAG_print_code_stubs) {
diff --git a/src/codegen.cc b/src/codegen.cc
index 5a99272..03f64a1 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -175,13 +175,17 @@
 Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
                                              Code::Flags flags,
                                              CompilationInfo* info) {
+  Isolate* isolate = info->isolate();
+
   // Allocate and install the code.
   CodeDesc desc;
   masm->GetCode(&desc);
-  Handle<Code> code = FACTORY->NewCode(desc, flags, masm->CodeObject());
+  Handle<Code> code =
+      isolate->factory()->NewCode(desc, flags, masm->CodeObject());
 
   if (!code.is_null()) {
-    COUNTERS->total_compiled_code_size()->Increment(code->instruction_size());
+    isolate->counters()->total_compiled_code_size()->Increment(
+        code->instruction_size());
   }
   return code;
 }
@@ -235,7 +239,8 @@
   Handle<Script> script = info->script();
   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
     int len = String::cast(script->source())->length();
-    COUNTERS->total_old_codegen_source_size()->Increment(len);
+    Counters* counters = info->isolate()->counters();
+    counters->total_old_codegen_source_size()->Increment(len);
   }
   if (FLAG_trace_codegen) {
     PrintF("Classic Compiler - ");
diff --git a/src/compiler.cc b/src/compiler.cc
index 85448dd..1ec4414 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -203,6 +203,10 @@
   Handle<Code> code(info->shared_info()->code());
   ASSERT(code->kind() == Code::FUNCTION);
 
+  // We should never arrive here if optimization has been disabled on the
+  // shared function info.
+  ASSERT(!info->shared_info()->optimization_disabled());
+
   // Fall back to using the full code generator if it's not possible
   // to use the Hydrogen-based optimizing compiler. We already have
   // generated code for this from the shared function object.
@@ -409,8 +413,8 @@
   // rest of the function into account to avoid overlap with the
   // parsing statistics.
   HistogramTimer* rate = info->is_eval()
-      ? COUNTERS->compile_eval()
-      : COUNTERS->compile();
+      ? info->isolate()->counters()->compile_eval()
+      : info->isolate()->counters()->compile();
   HistogramTimerScope timer(rate);
 
   // Compile the code.
@@ -480,10 +484,10 @@
                                              ScriptDataImpl* input_pre_data,
                                              Handle<Object> script_data,
                                              NativesFlag natives) {
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = source->GetIsolate();
   int source_length = source->length();
-  COUNTERS->total_load_size()->Increment(source_length);
-  COUNTERS->total_compile_size()->Increment(source_length);
+  isolate->counters()->total_load_size()->Increment(source_length);
+  isolate->counters()->total_compile_size()->Increment(source_length);
 
   // The VM is in the COMPILER state until exiting this function.
   VMState state(isolate, COMPILER);
@@ -629,6 +633,11 @@
     } else {
       ASSERT(!info->code().is_null());
       Handle<Code> code = info->code();
+      // Set optimizable to false if this is disallowed by the shared
+      // function info, e.g., we might have flushed the code and must
+      // reset this bit when lazy compiling the code again.
+      if (shared->optimization_disabled()) code->set_optimizable(false);
+
       Handle<JSFunction> function = info->closure();
       RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
 
@@ -665,7 +674,7 @@
         ASSERT(shared->is_compiled());
         shared->set_code_age(0);
 
-        if (V8::UseCrankshaft() && info->AllowOptimize()) {
+        if (info->AllowOptimize() && !shared->optimization_disabled()) {
           // If we're asked to always optimize, we compile the optimized
           // version of the function right away - unless the debugger is
           // active as it makes no sense to compile optimized code then.
@@ -710,8 +719,7 @@
 
   // Generate code
   if (FLAG_lazy && allow_lazy) {
-    Handle<Code> code(
-        info.isolate()->builtins()->builtin(Builtins::LazyCompile));
+    Handle<Code> code = info.isolate()->builtins()->LazyCompile();
     info.SetCode(code);
   } else {
     if (V8::UseCrankshaft()) {
@@ -801,7 +809,7 @@
   if (info->isolate()->logger()->is_logging() || CpuProfiler::is_profiling()) {
     Handle<Script> script = info->script();
     Handle<Code> code = info->code();
-    if (*code == info->isolate()->builtins()->builtin(Builtins::LazyCompile))
+    if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile))
       return;
     if (script->name()->IsString()) {
       int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
diff --git a/src/debug.cc b/src/debug.cc
index 10b8b4a..87afe34 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -717,11 +717,11 @@
   if (create_heap_objects) {
     // Get code to handle debug break on return.
     debug_break_return_ =
-        Isolate::Current()->builtins()->builtin(Builtins::Return_DebugBreak);
+        Isolate::Current()->builtins()->builtin(Builtins::kReturn_DebugBreak);
     ASSERT(debug_break_return_->IsCode());
     // Get code to handle debug break in debug break slots.
     debug_break_slot_ =
-        Isolate::Current()->builtins()->builtin(Builtins::Slot_DebugBreak);
+        Isolate::Current()->builtins()->builtin(Builtins::kSlot_DebugBreak);
     ASSERT(debug_break_slot_->IsCode());
   }
 }
@@ -1007,14 +1007,15 @@
       FRAME_DROPPED_IN_IC_CALL) {
     // We must have been calling IC stub. Do not go there anymore.
     Code* plain_return =
-        Isolate::Current()->builtins()->builtin(Builtins::PlainReturn_LiveEdit);
+        Isolate::Current()->builtins()->builtin(
+            Builtins::kPlainReturn_LiveEdit);
     debug->thread_local_.after_break_target_ = plain_return->entry();
   } else if (debug->thread_local_.frame_drop_mode_ ==
       FRAME_DROPPED_IN_DEBUG_SLOT_CALL) {
     // Debug break slot stub does not return normally, instead it manually
     // cleans the stack and jumps. We should patch the jump address.
     Code* plain_return = Isolate::Current()->builtins()->builtin(
-        Builtins::FrameDropper_LiveEdit);
+        Builtins::kFrameDropper_LiveEdit);
     debug->thread_local_.after_break_target_ = plain_return->entry();
   } else if (debug->thread_local_.frame_drop_mode_ ==
       FRAME_DROPPED_IN_DIRECT_CALL) {
@@ -1517,22 +1518,16 @@
         return ComputeCallDebugBreak(code->arguments_count(), code->kind());
 
       case Code::LOAD_IC:
-        return Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::LoadIC_DebugBreak));
+        return Isolate::Current()->builtins()->LoadIC_DebugBreak();
 
       case Code::STORE_IC:
-        return Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::StoreIC_DebugBreak));
+        return Isolate::Current()->builtins()->StoreIC_DebugBreak();
 
       case Code::KEYED_LOAD_IC:
-        return Handle<Code>(
-            Isolate::Current()->builtins()->builtin(
-                Builtins::KeyedLoadIC_DebugBreak));
+        return Isolate::Current()->builtins()->KeyedLoadIC_DebugBreak();
 
       case Code::KEYED_STORE_IC:
-        return Handle<Code>(
-            Isolate::Current()->builtins()->builtin(
-                Builtins::KeyedStoreIC_DebugBreak));
+        return Isolate::Current()->builtins()->KeyedStoreIC_DebugBreak();
 
       default:
         UNREACHABLE();
@@ -1540,15 +1535,13 @@
   }
   if (RelocInfo::IsConstructCall(mode)) {
     Handle<Code> result =
-        Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::ConstructCall_DebugBreak));
+        Isolate::Current()->builtins()->ConstructCall_DebugBreak();
     return result;
   }
   if (code->kind() == Code::STUB) {
     ASSERT(code->major_key() == CodeStub::CallFunction);
     Handle<Code> result =
-        Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::StubNoRegisters_DebugBreak));
+        Isolate::Current()->builtins()->StubNoRegisters_DebugBreak();
     return result;
   }
 
@@ -1616,9 +1609,9 @@
     // Don't allow step into functions in the native context.
     if (!function->IsBuiltin()) {
       if (function->shared()->code() ==
-          Isolate::Current()->builtins()->builtin(Builtins::FunctionApply) ||
+          Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply) ||
           function->shared()->code() ==
-          Isolate::Current()->builtins()->builtin(Builtins::FunctionCall)) {
+          Isolate::Current()->builtins()->builtin(Builtins::kFunctionCall)) {
         // Handle function.apply and function.call separately to flood the
         // function to be called and not the code for Builtins::FunctionApply or
         // Builtins::FunctionCall. The receiver of call/apply is the target
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index ef27646..a53de3d 100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -136,6 +136,13 @@
                           Isolate* isolate);
   static Deoptimizer* Grab(Isolate* isolate);
 
+  // Makes sure that there is enough room in the relocation
+  // information of a code object to perform lazy deoptimization
+  // patching. If there is not enough room a new relocation
+  // information object is allocated and comments are added until it
+  // is big enough.
+  static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code);
+
   // Deoptimize the function now. Its current optimized code will never be run
   // again and any activations of the optimized code will get deoptimized when
   // execution returns.
@@ -319,7 +326,9 @@
                    JSFunction* function);
 
   void* operator new(size_t size, uint32_t frame_size) {
-    return malloc(size + frame_size);
+    // Subtracts kPointerSize, as the member frame_content_ already supplies
+    // the first element of the area to store the frame.
+    return malloc(size + frame_size - kPointerSize);
   }
 
   void operator delete(void* description) {
@@ -403,7 +412,7 @@
   }
 
   static int frame_content_offset() {
-    return sizeof(FrameDescription);
+    return OFFSET_OF(FrameDescription, frame_content_);
   }
 
  private:
@@ -422,6 +431,10 @@
   // deoptimizing.
   intptr_t continuation_;
 
+  // This must be at the end of the object as the object is allocated larger
+  // than it's definition indicate to extend this array.
+  intptr_t frame_content_[1];
+
   intptr_t* GetFrameSlotPointer(unsigned offset) {
     ASSERT(offset < frame_size_);
     return reinterpret_cast<intptr_t*>(
diff --git a/src/factory.cc b/src/factory.cc
index d798c3e..7dee66f 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -392,8 +392,14 @@
 }
 
 
-Handle<Map> Factory::NewExternalArrayElementsMap(Handle<Map> src) {
-  CALL_HEAP_FUNCTION(isolate(), src->NewExternalArrayElementsMap(), Map);
+Handle<Map> Factory::GetExternalArrayElementsMap(
+    Handle<Map> src,
+    ExternalArrayType array_type,
+    bool safe_to_add_transition) {
+  CALL_HEAP_FUNCTION(isolate(),
+                     src->GetExternalArrayElementsMap(array_type,
+                                                      safe_to_add_transition),
+                     Map);
 }
 
 
@@ -987,11 +993,8 @@
 
 Handle<JSFunction> Factory::CreateApiFunction(
     Handle<FunctionTemplateInfo> obj, ApiInstanceType instance_type) {
-  Handle<Code> code = Handle<Code>(isolate()->builtins()->builtin(
-      Builtins::HandleApiCall));
-  Handle<Code> construct_stub =
-      Handle<Code>(isolate()->builtins()->builtin(
-          Builtins::JSConstructStubApi));
+  Handle<Code> code = isolate()->builtins()->HandleApiCall();
+  Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();
 
   int internal_field_count = 0;
   if (!obj->instance_template()->IsUndefined()) {
diff --git a/src/factory.h b/src/factory.h
index d9d5ec4..71bfdc4 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -192,7 +192,9 @@
 
   Handle<Map> GetSlowElementsMap(Handle<Map> map);
 
-  Handle<Map> NewExternalArrayElementsMap(Handle<Map> map);
+  Handle<Map> GetExternalArrayElementsMap(Handle<Map> map,
+                                          ExternalArrayType array_type,
+                                          bool safe_to_add_transition);
 
   Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
 
diff --git a/src/frames.cc b/src/frames.cc
index 30d0456..79aa250 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -851,7 +851,7 @@
 
 Code* ArgumentsAdaptorFrame::unchecked_code() const {
   return Isolate::Current()->builtins()->builtin(
-      Builtins::ArgumentsAdaptorTrampoline);
+      Builtins::kArgumentsAdaptorTrampoline);
 }
 
 
@@ -1147,14 +1147,14 @@
 
 
 PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) {
-  COUNTERS->pc_to_code()->Increment();
+  isolate_->counters()->pc_to_code()->Increment();
   ASSERT(IsPowerOf2(kPcToCodeCacheSize));
   uint32_t hash = ComputeIntegerHash(
       static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pc)));
   uint32_t index = hash & (kPcToCodeCacheSize - 1);
   PcToCodeCacheEntry* entry = cache(index);
   if (entry->pc == pc) {
-    COUNTERS->pc_to_code_cached()->Increment();
+    isolate_->counters()->pc_to_code_cached()->Increment();
     ASSERT(entry->code == GcSafeFindCodeForPc(pc));
   } else {
     // Because this code may be interrupted by a profiling signal that
diff --git a/src/heap.cc b/src/heap.cc
index 9a5a2b0..1c1e084 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2271,11 +2271,11 @@
 
   SharedFunctionInfo* share = SharedFunctionInfo::cast(result);
   share->set_name(name);
-  Code* illegal = isolate_->builtins()->builtin(Builtins::Illegal);
+  Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
   share->set_code(illegal);
   share->set_scope_info(SerializedScopeInfo::Empty());
   Code* construct_stub = isolate_->builtins()->builtin(
-      Builtins::JSConstructStubGeneric);
+      Builtins::kJSConstructStubGeneric);
   share->set_construct_stub(construct_stub);
   share->set_expected_nof_properties(0);
   share->set_length(0);
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index e253795..c73ce4c 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1156,6 +1156,60 @@
 }
 
 
+HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* object,
+                                                       ZoneMapList* types,
+                                                       Handle<String> name)
+    : HUnaryOperation(object),
+      types_(Min(types->length(), kMaxLoadPolymorphism)),
+      name_(name),
+      need_generic_(false) {
+  set_representation(Representation::Tagged());
+  SetFlag(kDependsOnMaps);
+  for (int i = 0;
+       i < types->length() && types_.length() < kMaxLoadPolymorphism;
+       ++i) {
+    Handle<Map> map = types->at(i);
+    LookupResult lookup;
+    map->LookupInDescriptors(NULL, *name, &lookup);
+    if (lookup.IsProperty() && lookup.type() == FIELD) {
+      types_.Add(types->at(i));
+      int index = lookup.GetLocalFieldIndexFromMap(*map);
+      if (index < 0) {
+        SetFlag(kDependsOnInobjectFields);
+      } else {
+        SetFlag(kDependsOnBackingStoreFields);
+      }
+    }
+  }
+
+  if (types_.length() == types->length() && FLAG_deoptimize_uncommon_cases) {
+    SetFlag(kUseGVN);
+  } else {
+    SetAllSideEffects();
+    need_generic_ = true;
+  }
+}
+
+
+bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) {
+  HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value);
+  if (types_.length() != other->types()->length()) return false;
+  if (!name_.is_identical_to(other->name())) return false;
+  if (need_generic_ != other->need_generic_) return false;
+  for (int i = 0; i < types_.length(); i++) {
+    bool found = false;
+    for (int j = 0; j < types_.length(); j++) {
+      if (types_.at(j).is_identical_to(other->types()->at(i))) {
+        found = true;
+        break;
+      }
+    }
+    if (!found) return false;
+  }
+  return true;
+}
+
+
 void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   stream->Add("[");
@@ -1172,8 +1226,36 @@
 }
 
 
-void HLoadPixelArrayElement::PrintDataTo(StringStream* stream) {
+void HLoadKeyedSpecializedArrayElement::PrintDataTo(
+    StringStream* stream) {
   external_pointer()->PrintNameTo(stream);
+  stream->Add(".");
+  switch (array_type()) {
+    case kExternalByteArray:
+      stream->Add("byte");
+      break;
+    case kExternalUnsignedByteArray:
+      stream->Add("u_byte");
+      break;
+    case kExternalShortArray:
+      stream->Add("short");
+      break;
+    case kExternalUnsignedShortArray:
+      stream->Add("u_short");
+      break;
+    case kExternalIntArray:
+      stream->Add("int");
+      break;
+    case kExternalUnsignedIntArray:
+      stream->Add("u_int");
+      break;
+    case kExternalFloatArray:
+      stream->Add("float");
+      break;
+    case kExternalPixelArray:
+      stream->Add("pixel");
+      break;
+  }
   stream->Add("[");
   key()->PrintNameTo(stream);
   stream->Add("]");
@@ -1221,8 +1303,36 @@
 }
 
 
-void HStorePixelArrayElement::PrintDataTo(StringStream* stream) {
+void HStoreKeyedSpecializedArrayElement::PrintDataTo(
+    StringStream* stream) {
   external_pointer()->PrintNameTo(stream);
+  stream->Add(".");
+  switch (array_type()) {
+    case kExternalByteArray:
+      stream->Add("byte");
+      break;
+    case kExternalUnsignedByteArray:
+      stream->Add("u_byte");
+      break;
+    case kExternalShortArray:
+      stream->Add("short");
+      break;
+    case kExternalUnsignedShortArray:
+      stream->Add("u_short");
+      break;
+    case kExternalIntArray:
+      stream->Add("int");
+      break;
+    case kExternalUnsignedIntArray:
+      stream->Add("u_int");
+      break;
+    case kExternalFloatArray:
+      stream->Add("float");
+      break;
+    case kExternalPixelArray:
+      stream->Add("pixel");
+      break;
+  }
   stream->Add("[");
   key()->PrintNameTo(stream);
   stream->Add("] = ");
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 3ca76f7..fed4b8b 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -29,7 +29,9 @@
 #define V8_HYDROGEN_INSTRUCTIONS_H_
 
 #include "v8.h"
+
 #include "code-stubs.h"
+#include "small-pointer-list.h"
 #include "string-stream.h"
 #include "zone.h"
 
@@ -125,9 +127,10 @@
   V(LoadGlobal)                                \
   V(LoadKeyedFastElement)                      \
   V(LoadKeyedGeneric)                          \
+  V(LoadKeyedSpecializedArrayElement)          \
   V(LoadNamedField)                            \
+  V(LoadNamedFieldPolymorphic)                 \
   V(LoadNamedGeneric)                          \
-  V(LoadPixelArrayElement)                     \
   V(Mod)                                       \
   V(Mul)                                       \
   V(ObjectLiteral)                             \
@@ -146,7 +149,7 @@
   V(StoreContextSlot)                          \
   V(StoreGlobal)                               \
   V(StoreKeyedFastElement)                     \
-  V(StorePixelArrayElement)                    \
+  V(StoreKeyedSpecializedArrayElement)         \
   V(StoreKeyedGeneric)                         \
   V(StoreNamedField)                           \
   V(StoreNamedGeneric)                         \
@@ -168,7 +171,7 @@
   V(InobjectFields)                            \
   V(BackingStoreFields)                        \
   V(ArrayElements)                             \
-  V(PixelArrayElements)                        \
+  V(SpecializedArrayElements)                  \
   V(GlobalVars)                                \
   V(Maps)                                      \
   V(ArrayLengths)                              \
@@ -451,7 +454,6 @@
 
   HValue() : block_(NULL),
              id_(kNoNumber),
-             uses_(2),
              type_(HType::Tagged()),
              range_(NULL),
              flags_(0) {}
@@ -463,7 +465,7 @@
   int id() const { return id_; }
   void set_id(int id) { id_ = id; }
 
-  ZoneList<HValue*>* uses() { return &uses_; }
+  SmallPointerList<HValue>* uses() { return &uses_; }
 
   virtual bool EmitAtUses() { return false; }
   Representation representation() const { return representation_; }
@@ -607,7 +609,7 @@
   int id_;
 
   Representation representation_;
-  ZoneList<HValue*> uses_;
+  SmallPointerList<HValue> uses_;
   HType type_;
   Range* range_;
   int flags_;
@@ -1246,7 +1248,7 @@
 
   bool IsApplyFunction() const {
     return function_->code() ==
-        Isolate::Current()->builtins()->builtin(Builtins::FunctionApply);
+        Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
   }
 
   virtual void PrintDataTo(StringStream* stream);
@@ -1406,8 +1408,9 @@
     // object. It is guaranteed to be 32 bit integer, but it can be
     // represented as either a smi or heap number.
     set_representation(Representation::Tagged());
-    SetFlag(kDependsOnArrayLengths);
     SetFlag(kUseGVN);
+    SetFlag(kDependsOnArrayLengths);
+    SetFlag(kDependsOnMaps);
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
@@ -1425,8 +1428,8 @@
  public:
   explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
     set_representation(Representation::Tagged());
-    SetFlag(kDependsOnArrayLengths);
     SetFlag(kUseGVN);
+    SetFlag(kDependsOnArrayLengths);
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
@@ -1584,7 +1587,7 @@
       : HUnaryOperation(value) {
     set_representation(Representation::External());
     // The result of this instruction is idempotent as long as its inputs don't
-    // change.  The external array of a pixel array elements object cannot
+    // change.  The external array of a specialized array elements object cannot
     // change once set, so it's no necessary to introduce any additional
     // dependencies on top of the inputs.
     SetFlag(kUseGVN);
@@ -2256,6 +2259,7 @@
       : HBinaryOperation(left, right) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
+    SetFlag(kDependsOnMaps);
   }
 
   virtual bool EmitAtUses() {
@@ -2941,6 +2945,7 @@
         offset_(offset) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
+    SetFlag(kDependsOnMaps);
     if (is_in_object) {
       SetFlag(kDependsOnInobjectFields);
     } else {
@@ -2971,6 +2976,37 @@
 };
 
 
+class HLoadNamedFieldPolymorphic: public HUnaryOperation {
+ public:
+  HLoadNamedFieldPolymorphic(HValue* object,
+                             ZoneMapList* types,
+                             Handle<String> name);
+
+  HValue* object() { return OperandAt(0); }
+  ZoneMapList* types() { return &types_; }
+  Handle<String> name() { return name_; }
+  bool need_generic() { return need_generic_; }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic,
+                               "load_named_field_polymorphic")
+
+  static const int kMaxLoadPolymorphism = 4;
+
+ protected:
+  virtual bool DataEquals(HValue* value);
+
+ private:
+  ZoneMapList types_;
+  Handle<String> name_;
+  bool need_generic_;
+};
+
+
+
 class HLoadNamedGeneric: public HBinaryOperation {
  public:
   HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
@@ -3043,13 +3079,20 @@
 };
 
 
-class HLoadPixelArrayElement: public HBinaryOperation {
+class HLoadKeyedSpecializedArrayElement: public HBinaryOperation {
  public:
-  HLoadPixelArrayElement(HValue* external_elements, HValue* key)
-      : HBinaryOperation(external_elements, key) {
-    set_representation(Representation::Integer32());
-    SetFlag(kDependsOnPixelArrayElements);
-    // Native code could change the pixel array.
+  HLoadKeyedSpecializedArrayElement(HValue* external_elements,
+                                    HValue* key,
+                                    ExternalArrayType array_type)
+      : HBinaryOperation(external_elements, key),
+        array_type_(array_type) {
+    if (array_type == kExternalFloatArray) {
+      set_representation(Representation::Double());
+    } else {
+      set_representation(Representation::Integer32());
+    }
+    SetFlag(kDependsOnSpecializedArrayElements);
+    // Native code could change the specialized array.
     SetFlag(kDependsOnCalls);
     SetFlag(kUseGVN);
   }
@@ -3065,12 +3108,21 @@
 
   HValue* external_pointer() { return OperandAt(0); }
   HValue* key() { return OperandAt(1); }
+  ExternalArrayType array_type() const { return array_type_; }
 
-  DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
-                               "load_pixel_array_element")
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+                               "load_keyed_specialized_array_element")
 
  protected:
-  virtual bool DataEquals(HValue* other) { return true; }
+  virtual bool DataEquals(HValue* other) {
+    if (!other->IsLoadKeyedSpecializedArrayElement()) return false;
+    HLoadKeyedSpecializedArrayElement* cast_other =
+        HLoadKeyedSpecializedArrayElement::cast(other);
+    return array_type_ == cast_other->array_type();
+  }
+
+ private:
+  ExternalArrayType array_type_;
 };
 
 
@@ -3205,10 +3257,14 @@
 };
 
 
-class HStorePixelArrayElement: public HTemplateInstruction<3> {
+class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
  public:
-  HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
-    SetFlag(kChangesPixelArrayElements);
+  HStoreKeyedSpecializedArrayElement(HValue* external_elements,
+                                     HValue* key,
+                                     HValue* val,
+                                     ExternalArrayType array_type)
+      : array_type_(array_type) {
+    SetFlag(kChangesSpecializedArrayElements);
     SetOperandAt(0, external_elements);
     SetOperandAt(1, key);
     SetOperandAt(2, val);
@@ -3220,16 +3276,23 @@
     if (index == 0) {
       return Representation::External();
     } else {
-      return Representation::Integer32();
+      if (index == 2 && array_type() == kExternalFloatArray) {
+        return Representation::Double();
+      } else {
+        return Representation::Integer32();
+      }
     }
   }
 
   HValue* external_pointer() { return OperandAt(0); }
   HValue* key() { return OperandAt(1); }
   HValue* value() { return OperandAt(2); }
+  ExternalArrayType array_type() const { return array_type_; }
 
-  DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
-                               "store_pixel_array_element")
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+                               "store_keyed_specialized_array_element")
+ private:
+  ExternalArrayType array_type_;
 };
 
 
@@ -3267,6 +3330,7 @@
       : HBinaryOperation(string, index) {
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
+    SetFlag(kDependsOnMaps);
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
@@ -3311,6 +3375,7 @@
   explicit HStringLength(HValue* string) : HUnaryOperation(string) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
+    SetFlag(kDependsOnMaps);
   }
 
   virtual Representation RequiredInputRepresentation(int index) const {
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index e9bfafd..7d9c814 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -745,7 +745,7 @@
     if (value != NULL) {
       // Iterate through uses finding the ones that should be
       // replaced.
-      ZoneList<HValue*>* uses = phi->uses();
+      SmallPointerList<HValue>* uses = phi->uses();
       while (!uses->is_empty()) {
         HValue* use = uses->RemoveLast();
         if (use != NULL) {
@@ -3219,9 +3219,10 @@
       // never both. Pixel array maps that are assigned to pixel array elements
       // are always created with the fast elements flag cleared.
       if (receiver_type->has_external_array_elements()) {
-        if (expr->GetExternalArrayType() == kExternalPixelArray) {
-          instr = BuildStoreKeyedPixelArrayElement(object, key, value, expr);
-        }
+        instr = BuildStoreKeyedSpecializedArrayElement(object,
+                                                       key,
+                                                       value,
+                                                       expr);
       } else if (receiver_type->has_fast_elements()) {
         instr = BuildStoreKeyedFastElement(object, key, value, expr);
       }
@@ -3445,69 +3446,6 @@
 }
 
 
-void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
-                                                    HValue* object,
-                                                    ZoneMapList* types,
-                                                    Handle<String> name) {
-  // TODO(ager): We should recognize when the prototype chains for different
-  // maps are identical. In that case we can avoid repeatedly generating the
-  // same prototype map checks.
-  int count = 0;
-  HBasicBlock* join = NULL;
-  for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
-    Handle<Map> map = types->at(i);
-    LookupResult lookup;
-    map->LookupInDescriptors(NULL, *name, &lookup);
-    if (lookup.IsProperty() && lookup.type() == FIELD) {
-      if (count == 0) {
-        AddInstruction(new HCheckNonSmi(object));  // Only needed once.
-        join = graph()->CreateBasicBlock();
-      }
-      ++count;
-      HBasicBlock* if_true = graph()->CreateBasicBlock();
-      HBasicBlock* if_false = graph()->CreateBasicBlock();
-      HCompareMap* compare = new HCompareMap(object, map, if_true, if_false);
-      current_block()->Finish(compare);
-
-      set_current_block(if_true);
-      HLoadNamedField* instr =
-          BuildLoadNamedField(object, expr, map, &lookup, false);
-      instr->set_position(expr->position());
-      instr->ClearFlag(HValue::kUseGVN);
-      AddInstruction(instr);
-      if (!ast_context()->IsEffect()) Push(instr);
-      current_block()->Goto(join);
-
-      set_current_block(if_false);
-    }
-  }
-
-  // Finish up.  Unconditionally deoptimize if we've handled all the maps we
-  // know about and do not want to handle ones we've never seen.  Otherwise
-  // use a generic IC.
-  if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
-    current_block()->FinishExitWithDeoptimization();
-  } else {
-    HInstruction* instr = BuildLoadNamedGeneric(object, expr);
-    instr->set_position(expr->position());
-
-    if (join != NULL) {
-      AddInstruction(instr);
-      if (!ast_context()->IsEffect()) Push(instr);
-      current_block()->Goto(join);
-    } else {
-      ast_context()->ReturnInstruction(instr, expr->id());
-      return;
-    }
-  }
-
-  ASSERT(join != NULL);
-  join->SetJoinId(expr->id());
-  set_current_block(join);
-  if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
-}
-
-
 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
                                                     Property* expr,
                                                     Handle<Map> type,
@@ -3597,9 +3535,10 @@
 }
 
 
-HInstruction* HGraphBuilder::BuildLoadKeyedPixelArrayElement(HValue* object,
-                                                             HValue* key,
-                                                             Property* expr) {
+HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement(
+    HValue* object,
+    HValue* key,
+    Property* expr) {
   ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
   AddInstruction(new HCheckNonSmi(object));
   Handle<Map> map = expr->GetMonomorphicReceiverType();
@@ -3614,8 +3553,10 @@
   HLoadExternalArrayPointer* external_elements =
       new HLoadExternalArrayPointer(elements);
   AddInstruction(external_elements);
-  HLoadPixelArrayElement* pixel_array_value =
-      new HLoadPixelArrayElement(external_elements, key);
+  HLoadKeyedSpecializedArrayElement* pixel_array_value =
+      new HLoadKeyedSpecializedArrayElement(external_elements,
+                                            key,
+                                            expr->GetExternalArrayType());
   return pixel_array_value;
 }
 
@@ -3653,11 +3594,11 @@
 }
 
 
-HInstruction* HGraphBuilder::BuildStoreKeyedPixelArrayElement(
+HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement(
     HValue* object,
     HValue* key,
     HValue* val,
-    Expression* expr) {
+    Assignment* expr) {
   ASSERT(expr->IsMonomorphic());
   AddInstruction(new HCheckNonSmi(object));
   Handle<Map> map = expr->GetMonomorphicReceiverType();
@@ -3671,7 +3612,11 @@
   HLoadExternalArrayPointer* external_elements =
       new HLoadExternalArrayPointer(elements);
   AddInstruction(external_elements);
-  return new HStorePixelArrayElement(external_elements, key, val);
+  return new HStoreKeyedSpecializedArrayElement(
+      external_elements,
+      key,
+      val,
+      expr->GetExternalArrayType());
 }
 
 
@@ -3748,9 +3693,8 @@
     if (expr->IsMonomorphic()) {
       instr = BuildLoadNamed(obj, expr, types->first(), name);
     } else if (types != NULL && types->length() > 1) {
-      HandlePolymorphicLoadNamedField(expr, obj, types, name);
-      return;
-
+      AddInstruction(new HCheckNonSmi(obj));
+      instr = new HLoadNamedFieldPolymorphic(obj, types, name);
     } else {
       instr = BuildLoadNamedGeneric(obj, expr);
     }
@@ -3767,9 +3711,7 @@
       // both. Pixel array maps that are assigned to pixel array elements are
       // always created with the fast elements flag cleared.
       if (receiver_type->has_external_array_elements()) {
-        if (expr->GetExternalArrayType() == kExternalPixelArray) {
-          instr = BuildLoadKeyedPixelArrayElement(obj, key, expr);
-        }
+        instr = BuildLoadKeyedSpecializedArrayElement(obj, key, expr);
       } else if (receiver_type->has_fast_elements()) {
         instr = BuildLoadKeyedFastElement(obj, key, expr);
       }
@@ -5875,9 +5817,14 @@
     PrintF(" %8u bytes / %4.1f %%\n", size, size_percent);
   }
   double source_size_in_kb = static_cast<double>(source_size_) / 1024;
+  double normalized_time =  source_size_in_kb > 0
+      ? (static_cast<double>(sum) / 1000) / source_size_in_kb
+      : 0;
+  double normalized_bytes = source_size_in_kb > 0
+      ? total_size_ / source_size_in_kb
+      : 0;
   PrintF("%30s - %7.3f ms           %7.3f bytes\n", "Sum",
-         (static_cast<double>(sum) / 1000) / source_size_in_kb,
-         total_size_ / source_size_in_kb);
+         normalized_time, normalized_bytes);
   PrintF("---------------------------------------------------------------\n");
   PrintF("%30s - %7.3f ms (%.1f times slower than full code gen)\n",
          "Total",
diff --git a/src/hydrogen.h b/src/hydrogen.h
index dee7866..e14799a 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -794,10 +794,6 @@
 
   void HandlePropertyAssignment(Assignment* expr);
   void HandleCompoundAssignment(Assignment* expr);
-  void HandlePolymorphicLoadNamedField(Property* expr,
-                                       HValue* object,
-                                       ZoneMapList* types,
-                                       Handle<String> name);
   void HandlePolymorphicStoreNamedField(Assignment* expr,
                                         HValue* object,
                                         HValue* value,
@@ -823,9 +819,9 @@
   HInstruction* BuildLoadKeyedFastElement(HValue* object,
                                           HValue* key,
                                           Property* expr);
-  HInstruction* BuildLoadKeyedPixelArrayElement(HValue* object,
-                                                HValue* key,
-                                                Property* expr);
+  HInstruction* BuildLoadKeyedSpecializedArrayElement(HValue* object,
+                                                      HValue* key,
+                                                      Property* expr);
   HInstruction* BuildLoadKeyedGeneric(HValue* object,
                                       HValue* key);
 
@@ -854,10 +850,11 @@
                                            HValue* val,
                                            Expression* expr);
 
-  HInstruction* BuildStoreKeyedPixelArrayElement(HValue* object,
-                                                 HValue* key,
-                                                 HValue* val,
-                                                 Expression* expr);
+  HInstruction* BuildStoreKeyedSpecializedArrayElement(
+      HValue* object,
+      HValue* key,
+      HValue* val,
+      Assignment* expr);
 
   HValue* BuildContextChainWalk(Variable* var);
 
diff --git a/src/ia32/assembler-ia32-inl.h b/src/ia32/assembler-ia32-inl.h
index f7be363..1da3f81 100644
--- a/src/ia32/assembler-ia32-inl.h
+++ b/src/ia32/assembler-ia32-inl.h
@@ -300,7 +300,7 @@
 void Assembler::emit(Handle<Object> handle) {
   // Verify all Objects referred by code are NOT in new space.
   Object* obj = *handle;
-  ASSERT(!HEAP->InNewSpace(obj));
+  ASSERT(!isolate()->heap()->InNewSpace(obj));
   if (obj->IsHeapObject()) {
     emit(reinterpret_cast<intptr_t>(handle.location()),
          RelocInfo::EMBEDDED_OBJECT);
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index 311ac39..e6d245e 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -122,9 +122,10 @@
   CodeDesc desc;
   assm.GetCode(&desc);
   Object* code;
-  { MaybeObject* maybe_code = HEAP->CreateCode(desc,
-                                               Code::ComputeFlags(Code::STUB),
-                                               Handle<Code>::null());
+  { MaybeObject* maybe_code =
+        assm.isolate()->heap()->CreateCode(desc,
+                                           Code::ComputeFlags(Code::STUB),
+                                           Handle<Code>::null());
     if (!maybe_code->ToObject(&code)) return;
   }
   if (!code->IsCode()) return;
@@ -368,8 +369,6 @@
   desc->instr_size = pc_offset();
   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
   desc->origin = this;
-
-  COUNTERS->reloc_info_size()->Increment(desc->reloc_size);
 }
 
 
@@ -2178,6 +2177,17 @@
 }
 
 
+void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
+  ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xF2);
+  EMIT(0x0F);
+  EMIT(0x5A);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
   ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
   EnsureSpace ensure_space(this);
@@ -2422,6 +2432,39 @@
 }
 
 
+void Assembler::movss(const Operand& dst, XMMRegister src ) {
+  ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xF3);  // float
+  EMIT(0x0F);
+  EMIT(0x11);  // store
+  emit_sse_operand(src, dst);
+}
+
+
+void Assembler::movss(XMMRegister dst, const Operand& src) {
+  ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xF3);  // float
+  EMIT(0x0F);
+  EMIT(0x10);  // load
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::movss(XMMRegister dst, XMMRegister src) {
+  ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xF3);
+  EMIT(0x0F);
+  EMIT(0x10);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::movd(XMMRegister dst, const Operand& src) {
   ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
   EnsureSpace ensure_space(this);
@@ -2630,7 +2673,7 @@
   // Some internal data structures overflow for very large buffers,
   // they must ensure that kMaximalBufferSize is not too large.
   if ((desc.buffer_size > kMaximalBufferSize) ||
-      (desc.buffer_size > HEAP->MaxOldGenerationSize())) {
+      (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
   }
 
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 19d879b..8e0c762 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -904,6 +904,7 @@
 
   void cvtsi2sd(XMMRegister dst, const Operand& src);
   void cvtss2sd(XMMRegister dst, XMMRegister src);
+  void cvtsd2ss(XMMRegister dst, XMMRegister src);
 
   void addsd(XMMRegister dst, XMMRegister src);
   void subsd(XMMRegister dst, XMMRegister src);
@@ -934,6 +935,10 @@
   void movd(const Operand& src, XMMRegister dst);
   void movsd(XMMRegister dst, XMMRegister src);
 
+  void movss(XMMRegister dst, const Operand& src);
+  void movss(const Operand& src, XMMRegister dst);
+  void movss(XMMRegister dst, XMMRegister src);
+
   void pand(XMMRegister dst, XMMRegister src);
   void pxor(XMMRegister dst, XMMRegister src);
   void por(XMMRegister dst, XMMRegister src);
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index cb41646..2970a0e 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -100,8 +100,9 @@
   // Set expected number of arguments to zero (not changing eax).
   __ Set(ebx, Immediate(0));
   __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
-  __ jmp(Handle<Code>(masm->isolate()->builtins()->builtin(
-      ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+  Handle<Code> arguments_adaptor =
+      masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+  __ jmp(arguments_adaptor, RelocInfo::CODE_TARGET);
 }
 
 
@@ -184,7 +185,8 @@
     // ebx: JSObject
     // edi: start of next object
     __ mov(Operand(ebx, JSObject::kMapOffset), eax);
-    __ mov(ecx, FACTORY->empty_fixed_array());
+    Factory* factory = masm->isolate()->factory();
+    __ mov(ecx, factory->empty_fixed_array());
     __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);
     __ mov(Operand(ebx, JSObject::kElementsOffset), ecx);
     // Set extra fields in the newly allocated object.
@@ -194,9 +196,9 @@
     { Label loop, entry;
       // To allow for truncation.
       if (count_constructions) {
-        __ mov(edx, FACTORY->one_pointer_filler_map());
+        __ mov(edx, factory->one_pointer_filler_map());
       } else {
-        __ mov(edx, FACTORY->undefined_value());
+        __ mov(edx, factory->undefined_value());
       }
       __ lea(ecx, Operand(ebx, JSObject::kHeaderSize));
       __ jmp(&entry);
@@ -252,7 +254,7 @@
     // edi: FixedArray
     // edx: number of elements
     // ecx: start of next object
-    __ mov(eax, FACTORY->fixed_array_map());
+    __ mov(eax, factory->fixed_array_map());
     __ mov(Operand(edi, FixedArray::kMapOffset), eax);  // setup the map
     __ SmiTag(edx);
     __ mov(Operand(edi, FixedArray::kLengthOffset), edx);  // and length
@@ -262,7 +264,7 @@
     // edi: FixedArray
     // ecx: start of next object
     { Label loop, entry;
-      __ mov(edx, FACTORY->undefined_value());
+      __ mov(edx, factory->undefined_value());
       __ lea(eax, Operand(edi, FixedArray::kHeaderSize));
       __ jmp(&entry);
       __ bind(&loop);
@@ -334,8 +336,8 @@
   // Call the function.
   if (is_api_function) {
     __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
-    Handle<Code> code = Handle<Code>(
-        masm->isolate()->builtins()->builtin(Builtins::HandleApiCallConstruct));
+    Handle<Code> code =
+        masm->isolate()->builtins()->HandleApiCallConstruct();
     ParameterCount expected(0);
     __ InvokeCode(code, expected, expected,
                   RelocInfo::CODE_TARGET, CALL_FUNCTION);
@@ -376,7 +378,7 @@
   __ pop(ecx);
   __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  // 1 ~ receiver
   __ push(ecx);
-  __ IncrementCounter(COUNTERS->constructed_objects(), 1);
+  __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
   __ ret(0);
 }
 
@@ -436,8 +438,8 @@
 
   // Invoke the code.
   if (is_construct) {
-    __ call(Handle<Code>(masm->isolate()->builtins()->builtin(
-        Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
+    __ call(masm->isolate()->builtins()->JSConstructCall(),
+            RelocInfo::CODE_TARGET);
   } else {
     ParameterCount actual(eax);
     __ InvokeFunction(edi, actual, CALL_FUNCTION);
@@ -561,12 +563,14 @@
 
 
 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
+  Factory* factory = masm->isolate()->factory();
+
   // 1. Make sure we have at least one argument.
   { Label done;
     __ test(eax, Operand(eax));
     __ j(not_zero, &done, taken);
     __ pop(ebx);
-    __ push(Immediate(FACTORY->undefined_value()));
+    __ push(Immediate(factory->undefined_value()));
     __ push(ebx);
     __ inc(eax);
     __ bind(&done);
@@ -600,9 +604,9 @@
     __ test(ebx, Immediate(kSmiTagMask));
     __ j(zero, &convert_to_object);
 
-    __ cmp(ebx, FACTORY->null_value());
+    __ cmp(ebx, factory->null_value());
     __ j(equal, &use_global_receiver);
-    __ cmp(ebx, FACTORY->undefined_value());
+    __ cmp(ebx, factory->undefined_value());
     __ j(equal, &use_global_receiver);
 
     // We don't use IsObjectJSObjectType here because we jump on success.
@@ -674,8 +678,8 @@
     __ j(not_zero, &function, taken);
     __ Set(ebx, Immediate(0));
     __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
-    __ jmp(Handle<Code>(masm->isolate()->builtins()->builtin(
-        ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+    __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+           RelocInfo::CODE_TARGET);
     __ bind(&function);
   }
 
@@ -688,8 +692,8 @@
   __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset));
   __ SmiUntag(ebx);
   __ cmp(eax, Operand(ebx));
-  __ j(not_equal, Handle<Code>(masm->isolate()->builtins()->builtin(
-      ArgumentsAdaptorTrampoline)));
+  __ j(not_equal,
+       masm->isolate()->builtins()->ArgumentsAdaptorTrampoline());
 
   ParameterCount expected(0);
   __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
@@ -754,9 +758,10 @@
   // Compute the receiver in non-strict mode.
   __ test(ebx, Immediate(kSmiTagMask));
   __ j(zero, &call_to_object);
-  __ cmp(ebx, FACTORY->null_value());
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(ebx, factory->null_value());
   __ j(equal, &use_global_receiver);
-  __ cmp(ebx, FACTORY->undefined_value());
+  __ cmp(ebx, factory->undefined_value());
   __ j(equal, &use_global_receiver);
 
   // If given receiver is already a JavaScript object then there's no
@@ -796,8 +801,7 @@
   __ mov(edx, Operand(ebp, 2 * kPointerSize));  // load arguments
 
   // Use inline caching to speed up access to arguments.
-  Handle<Code> ic(masm->isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize();
   __ call(ic, RelocInfo::CODE_TARGET);
   // It is important that we do not have a test instruction after the
   // call.  A test instruction after the call is used to indicate that
@@ -868,8 +872,9 @@
   // scratch1: initial map
   // scratch2: start of next object
   __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1);
+  Factory* factory = masm->isolate()->factory();
   __ mov(FieldOperand(result, JSArray::kPropertiesOffset),
-         FACTORY->empty_fixed_array());
+         factory->empty_fixed_array());
   // Field JSArray::kElementsOffset is initialized later.
   __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0));
 
@@ -877,7 +882,7 @@
   // fixed array.
   if (initial_capacity == 0) {
     __ mov(FieldOperand(result, JSArray::kElementsOffset),
-           FACTORY->empty_fixed_array());
+           factory->empty_fixed_array());
     return;
   }
 
@@ -894,7 +899,7 @@
   // scratch1: elements array
   // scratch2: start of next object
   __ mov(FieldOperand(scratch1, FixedArray::kMapOffset),
-         FACTORY->fixed_array_map());
+         factory->fixed_array_map());
   __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset),
          Immediate(Smi::FromInt(initial_capacity)));
 
@@ -905,7 +910,7 @@
   if (initial_capacity <= kLoopUnfoldLimit) {
     // Use a scratch register here to have only one reloc info when unfolding
     // the loop.
-    __ mov(scratch3, FACTORY->the_hole_value());
+    __ mov(scratch3, factory->the_hole_value());
     for (int i = 0; i < initial_capacity; i++) {
       __ mov(FieldOperand(scratch1,
                           FixedArray::kHeaderSize + i * kPointerSize),
@@ -915,7 +920,7 @@
     Label loop, entry;
     __ jmp(&entry);
     __ bind(&loop);
-    __ mov(Operand(scratch1, 0), FACTORY->the_hole_value());
+    __ mov(Operand(scratch1, 0), factory->the_hole_value());
     __ add(Operand(scratch1), Immediate(kPointerSize));
     __ bind(&entry);
     __ cmp(scratch1, Operand(scratch2));
@@ -970,7 +975,8 @@
   // elements_array_end: start of next object
   // array_size: size of array (smi)
   __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array);
-  __ mov(elements_array, FACTORY->empty_fixed_array());
+  Factory* factory = masm->isolate()->factory();
+  __ mov(elements_array, factory->empty_fixed_array());
   __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array);
   // Field JSArray::kElementsOffset is initialized later.
   __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size);
@@ -989,7 +995,7 @@
   // elements_array_end: start of next object
   // array_size: size of array (smi)
   __ mov(FieldOperand(elements_array, FixedArray::kMapOffset),
-         FACTORY->fixed_array_map());
+         factory->fixed_array_map());
   // For non-empty JSArrays the length of the FixedArray and the JSArray is the
   // same.
   __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size);
@@ -1001,7 +1007,7 @@
     __ SmiUntag(array_size);
     __ lea(edi, Operand(elements_array,
                         FixedArray::kHeaderSize - kHeapObjectTag));
-    __ mov(eax, FACTORY->the_hole_value());
+    __ mov(eax, factory->the_hole_value());
     __ cld();
     // Do not use rep stos when filling less than kRepStosThreshold
     // words.
@@ -1065,7 +1071,7 @@
                        edi,
                        kPreallocatedArrayElements,
                        &prepare_generic_code_call);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1);
+  __ IncrementCounter(masm->isolate()->counters()->array_function_native(), 1);
   __ pop(ebx);
   if (construct_call) {
     __ pop(edi);
@@ -1121,7 +1127,8 @@
                   edi,
                   true,
                   &prepare_generic_code_call);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->array_function_native(), 1);
   __ mov(eax, ebx);
   __ pop(ebx);
   if (construct_call) {
@@ -1148,7 +1155,7 @@
                   edi,
                   false,
                   &prepare_generic_code_call);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1);
+  __ IncrementCounter(counters->array_function_native(), 1);
   __ mov(eax, ebx);
   __ pop(ebx);
   if (construct_call) {
@@ -1234,8 +1241,8 @@
   // Jump to the generic array code in case the specialized code cannot handle
   // the construction.
   __ bind(&generic_array_code);
-  Code* code = masm->isolate()->builtins()->builtin(Builtins::ArrayCodeGeneric);
-  Handle<Code> array_code(code);
+  Handle<Code> array_code =
+      masm->isolate()->builtins()->ArrayCodeGeneric();
   __ jmp(array_code, RelocInfo::CODE_TARGET);
 }
 
@@ -1268,9 +1275,8 @@
   // Jump to the generic construct code in case the specialized code cannot
   // handle the construction.
   __ bind(&generic_constructor);
-  Code* code = masm->isolate()->builtins()->builtin(
-      Builtins::JSConstructStubGeneric);
-  Handle<Code> generic_construct_stub(code);
+  Handle<Code> generic_construct_stub =
+      masm->isolate()->builtins()->JSConstructStubGeneric();
   __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
 }
 
@@ -1283,7 +1289,8 @@
   //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
   //  -- esp[(argc + 1) * 4] : receiver
   // -----------------------------------
-  __ IncrementCounter(COUNTERS->string_ctor_calls(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->string_ctor_calls(), 1);
 
   if (FLAG_debug_code) {
     __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, ecx);
@@ -1312,7 +1319,7 @@
       edx,  // Scratch 2.
       false,  // Input is known to be smi?
       &not_cached);
-  __ IncrementCounter(COUNTERS->string_ctor_cached_number(), 1);
+  __ IncrementCounter(counters->string_ctor_cached_number(), 1);
   __ bind(&argument_is_string);
   // ----------- S t a t e -------------
   //  -- ebx    : argument converted to string
@@ -1341,7 +1348,8 @@
   __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx);
 
   // Set properties and elements.
-  __ Set(ecx, Immediate(FACTORY->empty_fixed_array()));
+  Factory* factory = masm->isolate()->factory();
+  __ Set(ecx, Immediate(factory->empty_fixed_array()));
   __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx);
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx);
 
@@ -1364,12 +1372,12 @@
   Condition is_string = masm->IsObjectStringType(eax, ebx, ecx);
   __ j(NegateCondition(is_string), &convert_argument);
   __ mov(ebx, eax);
-  __ IncrementCounter(COUNTERS->string_ctor_string_value(), 1);
+  __ IncrementCounter(counters->string_ctor_string_value(), 1);
   __ jmp(&argument_is_string);
 
   // Invoke the conversion builtin and put the result into ebx.
   __ bind(&convert_argument);
-  __ IncrementCounter(COUNTERS->string_ctor_conversions(), 1);
+  __ IncrementCounter(counters->string_ctor_conversions(), 1);
   __ EnterInternalFrame();
   __ push(edi);  // Preserve the function.
   __ push(eax);
@@ -1382,7 +1390,7 @@
   // Load the empty string into ebx, remove the receiver from the
   // stack, and jump back to the case where the argument is a string.
   __ bind(&no_arguments);
-  __ Set(ebx, Immediate(FACTORY->empty_string()));
+  __ Set(ebx, Immediate(factory->empty_string()));
   __ pop(ecx);
   __ lea(esp, Operand(esp, kPointerSize));
   __ push(ecx);
@@ -1391,7 +1399,7 @@
   // At this point the argument is already a string. Call runtime to
   // create a string wrapper.
   __ bind(&gc_required);
-  __ IncrementCounter(COUNTERS->string_ctor_gc_required(), 1);
+  __ IncrementCounter(counters->string_ctor_gc_required(), 1);
   __ EnterInternalFrame();
   __ push(ebx);
   __ CallRuntime(Runtime::kNewStringWrapper, 1);
@@ -1442,7 +1450,7 @@
   // -----------------------------------
 
   Label invoke, dont_adapt_arguments;
-  __ IncrementCounter(COUNTERS->arguments_adaptors(), 1);
+  __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1);
 
   Label enough, too_few;
   __ cmp(eax, Operand(ebx));
@@ -1490,7 +1498,7 @@
     Label fill;
     __ bind(&fill);
     __ inc(ecx);
-    __ push(Immediate(FACTORY->undefined_value()));
+    __ push(Immediate(masm->isolate()->factory()->undefined_value()));
     __ cmp(ecx, Operand(ebx));
     __ j(less, &fill);
 
@@ -1586,7 +1594,7 @@
 
 
 #undef __
-
-} }  // namespace v8::internal
+}
+}  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_IA32
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index eaff1b8..711616f 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -49,7 +49,8 @@
 
   __ bind(&check_heap_number);
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
-  __ cmp(Operand(ebx), Immediate(FACTORY->heap_number_map()));
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(Operand(ebx), Immediate(factory->heap_number_map()));
   __ j(not_equal, &call_builtin);
   __ ret(0);
 
@@ -83,16 +84,17 @@
 
   // Initialize the rest of the function. We don't have to update the
   // write barrier because the allocated object is in new space.
-  __ mov(ebx, Immediate(FACTORY->empty_fixed_array()));
+  Factory* factory = masm->isolate()->factory();
+  __ mov(ebx, Immediate(factory->empty_fixed_array()));
   __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ebx);
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
   __ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset),
-         Immediate(FACTORY->the_hole_value()));
+         Immediate(factory->the_hole_value()));
   __ mov(FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset), edx);
   __ mov(FieldOperand(eax, JSFunction::kContextOffset), esi);
   __ mov(FieldOperand(eax, JSFunction::kLiteralsOffset), ebx);
   __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset),
-         Immediate(FACTORY->undefined_value()));
+         Immediate(factory->undefined_value()));
 
   // Initialize the code pointer in the function to be the one
   // found in the shared function info object.
@@ -109,7 +111,7 @@
   __ pop(edx);
   __ push(esi);
   __ push(edx);
-  __ push(Immediate(FACTORY->false_value()));
+  __ push(Immediate(factory->false_value()));
   __ push(ecx);  // Restore return address.
   __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
 }
@@ -126,7 +128,8 @@
   __ mov(ecx, Operand(esp, 1 * kPointerSize));
 
   // Setup the object header.
-  __ mov(FieldOperand(eax, HeapObject::kMapOffset), FACTORY->context_map());
+  Factory* factory = masm->isolate()->factory();
+  __ mov(FieldOperand(eax, HeapObject::kMapOffset), factory->context_map());
   __ mov(FieldOperand(eax, Context::kLengthOffset),
          Immediate(Smi::FromInt(length)));
 
@@ -145,7 +148,7 @@
   __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
 
   // Initialize the rest of the slots to undefined.
-  __ mov(ebx, FACTORY->undefined_value());
+  __ mov(ebx, factory->undefined_value());
   for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
     __ mov(Operand(eax, Context::SlotOffset(i)), ebx);
   }
@@ -181,7 +184,8 @@
   STATIC_ASSERT(kSmiTag == 0);
   __ mov(ecx, FieldOperand(ecx, eax, times_half_pointer_size,
                            FixedArray::kHeaderSize));
-  __ cmp(ecx, FACTORY->undefined_value());
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(ecx, factory->undefined_value());
   __ j(equal, &slow_case);
 
   if (FLAG_debug_code) {
@@ -189,11 +193,11 @@
     Handle<Map> expected_map;
     if (mode_ == CLONE_ELEMENTS) {
       message = "Expected (writable) fixed array";
-      expected_map = FACTORY->fixed_array_map();
+      expected_map = factory->fixed_array_map();
     } else {
       ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS);
       message = "Expected copy-on-write fixed array";
-      expected_map = FACTORY->fixed_cow_array_map();
+      expected_map = factory->fixed_cow_array_map();
     }
     __ push(ecx);
     __ mov(ecx, FieldOperand(ecx, JSArray::kElementsOffset));
@@ -242,7 +246,8 @@
   __ mov(eax, Operand(esp, 1 * kPointerSize));
 
   // 'null' => false.
-  __ cmp(eax, FACTORY->null_value());
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(eax, factory->null_value());
   __ j(equal, &false_result);
 
   // Get the map and type of the heap object.
@@ -268,7 +273,7 @@
 
   __ bind(&not_string);
   // HeapNumber => false iff +0, -0, or NaN.
-  __ cmp(edx, FACTORY->heap_number_map());
+  __ cmp(edx, factory->heap_number_map());
   __ j(not_equal, &true_result);
   __ fldz();
   __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
@@ -364,7 +369,8 @@
 
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
-    __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+    __ IncrementCounter(
+        masm->isolate()->counters()->generic_binary_stub_calls_regs(), 1);
   }
 
   // Call the stub.
@@ -400,7 +406,8 @@
 
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
-    __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+    __ IncrementCounter(
+        masm->isolate()->counters()->generic_binary_stub_calls_regs(), 1);
   }
 
   // Call the stub.
@@ -435,7 +442,8 @@
     }
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
-    __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+    Counters* counters = masm->isolate()->counters();
+    __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
   }
 
   // Call the stub.
@@ -878,7 +886,8 @@
 void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
   Label call_runtime;
 
-  __ IncrementCounter(COUNTERS->generic_binary_stub_calls(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->generic_binary_stub_calls(), 1);
 
   if (runtime_operands_type_ == BinaryOpIC::UNINIT_OR_SMI) {
     Label slow;
@@ -2200,7 +2209,8 @@
 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
   Label call_runtime;
 
-  __ IncrementCounter(COUNTERS->generic_binary_stub_calls(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->generic_binary_stub_calls(), 1);
 
   switch (op_) {
     case Token::ADD:
@@ -2516,7 +2526,8 @@
     __ bind(&input_not_smi);
     // Check if input is a HeapNumber.
     __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
-    __ cmp(Operand(ebx), Immediate(FACTORY->heap_number_map()));
+    Factory* factory = masm->isolate()->factory();
+    __ cmp(Operand(ebx), Immediate(factory->heap_number_map()));
     __ j(not_equal, &runtime_call);
     // Input is a HeapNumber. Push it on the FPU stack and load its
     // low and high words into ebx, edx.
@@ -2984,14 +2995,15 @@
 
   // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
   __ bind(&check_undefined_arg1);
-  __ cmp(edx, FACTORY->undefined_value());
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(edx, factory->undefined_value());
   __ j(not_equal, conversion_failure);
   __ mov(edx, Immediate(0));
   __ jmp(&load_arg2);
 
   __ bind(&arg1_is_object);
   __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
-  __ cmp(ebx, FACTORY->heap_number_map());
+  __ cmp(ebx, factory->heap_number_map());
   __ j(not_equal, &check_undefined_arg1);
 
   // Get the untagged integer version of the edx heap number in ecx.
@@ -3015,14 +3027,14 @@
 
   // If the argument is undefined it converts to zero (ECMA-262, section 9.5).
   __ bind(&check_undefined_arg2);
-  __ cmp(eax, FACTORY->undefined_value());
+  __ cmp(eax, factory->undefined_value());
   __ j(not_equal, conversion_failure);
   __ mov(ecx, Immediate(0));
   __ jmp(&done);
 
   __ bind(&arg2_is_object);
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
-  __ cmp(ebx, FACTORY->heap_number_map());
+  __ cmp(ebx, factory->heap_number_map());
   __ j(not_equal, &check_undefined_arg2);
 
   // Get the untagged integer version of the eax heap number in ecx.
@@ -3109,14 +3121,15 @@
   // Load operand in edx into xmm0, or branch to not_numbers.
   __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &load_smi_edx, not_taken);  // Argument in edx is a smi.
-  __ cmp(FieldOperand(edx, HeapObject::kMapOffset), FACTORY->heap_number_map());
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map());
   __ j(not_equal, not_numbers);  // Argument in edx is not a number.
   __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
   __ bind(&load_eax);
   // Load operand in eax into xmm1, or branch to not_numbers.
   __ test(eax, Immediate(kSmiTagMask));
   __ j(zero, &load_smi_eax, not_taken);  // Argument in eax is a smi.
-  __ cmp(FieldOperand(eax, HeapObject::kMapOffset), FACTORY->heap_number_map());
+  __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map());
   __ j(equal, &load_float_eax);
   __ jmp(not_numbers);  // Argument in eax is not a number.
   __ bind(&load_smi_edx);
@@ -3234,14 +3247,15 @@
   __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &test_other, not_taken);  // argument in edx is OK
   __ mov(scratch, FieldOperand(edx, HeapObject::kMapOffset));
-  __ cmp(scratch, FACTORY->heap_number_map());
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(scratch, factory->heap_number_map());
   __ j(not_equal, non_float);  // argument in edx is not a number -> NaN
 
   __ bind(&test_other);
   __ test(eax, Immediate(kSmiTagMask));
   __ j(zero, &done);  // argument in eax is OK
   __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
-  __ cmp(scratch, FACTORY->heap_number_map());
+  __ cmp(scratch, factory->heap_number_map());
   __ j(not_equal, non_float);  // argument in eax is not a number -> NaN
 
   // Fall-through: Both operands are numbers.
@@ -3287,7 +3301,7 @@
     }
 
     __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
-    __ cmp(edx, FACTORY->heap_number_map());
+    __ cmp(edx, masm->isolate()->factory()->heap_number_map());
     __ j(not_equal, &slow);
     if (overwrite_ == UNARY_OVERWRITE) {
       __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
@@ -3319,7 +3333,7 @@
 
     // Check if the operand is a heap number.
     __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
-    __ cmp(edx, FACTORY->heap_number_map());
+    __ cmp(edx, masm->isolate()->factory()->heap_number_map());
     __ j(not_equal, &slow, not_taken);
 
     // Convert the heap number in eax to an untagged integer in ecx.
@@ -3421,8 +3435,9 @@
   __ jmp(&powi);
   // exponent is smi and base is a heapnumber.
   __ bind(&base_nonsmi);
+  Factory* factory = masm->isolate()->factory();
   __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
-         FACTORY->heap_number_map());
+         factory->heap_number_map());
   __ j(not_equal, &call_runtime);
 
   __ movdbl(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
@@ -3474,7 +3489,7 @@
   // on doubles.
   __ bind(&exponent_nonsmi);
   __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
-         FACTORY->heap_number_map());
+         factory->heap_number_map());
   __ j(not_equal, &call_runtime);
   __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
   // Test if exponent is nan.
@@ -3491,7 +3506,7 @@
 
   __ bind(&base_not_smi);
   __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
-         FACTORY->heap_number_map());
+         factory->heap_number_map());
   __ j(not_equal, &call_runtime);
   __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
   __ and_(ecx, HeapNumber::kExponentMask);
@@ -3689,7 +3704,7 @@
   __ lea(edi, Operand(eax, GetArgumentsObjectSize()));
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi);
   __ mov(FieldOperand(edi, FixedArray::kMapOffset),
-         Immediate(FACTORY->fixed_array_map()));
+         Immediate(masm->isolate()->factory()->fixed_array_map()));
 
   __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx);
   // Untag the length for the loop below.
@@ -3818,7 +3833,8 @@
   // Check that the JSArray is in fast case.
   __ mov(ebx, FieldOperand(eax, JSArray::kElementsOffset));
   __ mov(eax, FieldOperand(ebx, HeapObject::kMapOffset));
-  __ cmp(eax, FACTORY->fixed_array_map());
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(eax, factory->fixed_array_map());
   __ j(not_equal, &runtime);
   // Check that the last match info has space for the capture registers and the
   // additional information.
@@ -3856,7 +3872,7 @@
   __ j(not_zero, &runtime);
   // String is a cons string.
   __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
-  __ cmp(Operand(edx), FACTORY->empty_string());
+  __ cmp(Operand(edx), factory->empty_string());
   __ j(not_equal, &runtime);
   __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
   __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
@@ -3906,7 +3922,8 @@
   // edx: code
   // edi: encoding of subject string (1 if ascii 0 if two_byte);
   // All checks done. Now push arguments for native regexp code.
-  __ IncrementCounter(COUNTERS->regexp_entry_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->regexp_entry_native(), 1);
 
   // Isolates: note we add an additional parameter here (isolate pointer).
   static const int kRegExpExecuteArguments = 8;
@@ -3994,7 +4011,7 @@
 
   // Special handling of termination exceptions which are uncatchable
   // by javascript code.
-  __ cmp(eax, FACTORY->termination_exception());
+  __ cmp(eax, factory->termination_exception());
   Label throw_termination_exception;
   __ j(equal, &throw_termination_exception);
 
@@ -4006,7 +4023,7 @@
 
   __ bind(&failure);
   // For failure to match, return null.
-  __ mov(Operand(eax), FACTORY->null_value());
+  __ mov(Operand(eax), factory->null_value());
   __ ret(4 * kPointerSize);
 
   // Load RegExp data.
@@ -4107,7 +4124,8 @@
   // Set elements to point to FixedArray allocated right after the JSArray.
   // Interleave operations for better latency.
   __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
-  __ mov(ecx, Immediate(FACTORY->empty_fixed_array()));
+  Factory* factory = masm->isolate()->factory();
+  __ mov(ecx, Immediate(factory->empty_fixed_array()));
   __ lea(ebx, Operand(eax, JSRegExpResult::kSize));
   __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
   __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
@@ -4130,12 +4148,12 @@
 
   // Set map.
   __ mov(FieldOperand(ebx, HeapObject::kMapOffset),
-         Immediate(FACTORY->fixed_array_map()));
+         Immediate(factory->fixed_array_map()));
   // Set length.
   __ mov(FieldOperand(ebx, FixedArray::kLengthOffset), ecx);
   // Fill contents of fixed-array with the-hole.
   __ SmiUntag(ecx);
-  __ mov(edx, Immediate(FACTORY->the_hole_value()));
+  __ mov(edx, Immediate(factory->the_hole_value()));
   __ lea(ebx, FieldOperand(ebx, FixedArray::kHeaderSize));
   // Fill fixed array elements with hole.
   // eax: JSArray.
@@ -4201,7 +4219,7 @@
     __ jmp(&smi_hash_calculated);
     __ bind(&not_smi);
     __ cmp(FieldOperand(object, HeapObject::kMapOffset),
-           FACTORY->heap_number_map());
+           masm->isolate()->factory()->heap_number_map());
     __ j(not_equal, not_found);
     STATIC_ASSERT(8 == kDoubleSize);
     __ mov(scratch, FieldOperand(object, HeapNumber::kValueOffset));
@@ -4251,7 +4269,8 @@
                       index,
                       times_twice_pointer_size,
                       FixedArray::kHeaderSize + kPointerSize));
-  __ IncrementCounter(COUNTERS->number_to_string_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->number_to_string_native(), 1);
 }
 
 
@@ -4317,14 +4336,14 @@
       // Check for undefined.  undefined OP undefined is false even though
       // undefined == undefined.
       NearLabel check_for_nan;
-      __ cmp(edx, FACTORY->undefined_value());
+      __ cmp(edx, masm->isolate()->factory()->undefined_value());
       __ j(not_equal, &check_for_nan);
       __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
       __ ret(0);
       __ bind(&check_for_nan);
     }
 
-    // Test for NaN. Sadly, we can't just compare to FACTORY->nan_value(),
+    // Test for NaN. Sadly, we can't just compare to factory->nan_value(),
     // so we do the second best thing - test it ourselves.
     // Note: if cc_ != equal, never_nan_nan_ is not used.
     if (never_nan_nan_ && (cc_ == equal)) {
@@ -4333,7 +4352,7 @@
     } else {
       NearLabel heap_number;
       __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
-             Immediate(FACTORY->heap_number_map()));
+             Immediate(masm->isolate()->factory()->heap_number_map()));
       __ j(equal, &heap_number);
       if (cc_ != equal) {
         // Call runtime on identical JSObjects.  Otherwise return equal.
@@ -4410,7 +4429,7 @@
 
     // Check if the non-smi operand is a heap number.
     __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
-           Immediate(FACTORY->heap_number_map()));
+           Immediate(masm->isolate()->factory()->heap_number_map()));
     // If heap number, handle it in the slow case.
     __ j(equal, &slow);
     // Return non-equal (ebx is not zero)
@@ -4674,8 +4693,8 @@
   __ Set(eax, Immediate(argc_));
   __ Set(ebx, Immediate(0));
   __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
-  Handle<Code> adaptor(masm->isolate()->builtins()->builtin(
-      Builtins::ArgumentsAdaptorTrampoline));
+  Handle<Code> adaptor =
+      masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
   __ jmp(adaptor, RelocInfo::CODE_TARGET);
 }
 
@@ -4742,7 +4761,7 @@
   // call as this may lead to crashes in the IC code later.
   if (FLAG_debug_code) {
     NearLabel okay;
-    __ cmp(eax, FACTORY->the_hole_value());
+    __ cmp(eax, masm->isolate()->factory()->the_hole_value());
     __ j(not_equal, &okay);
     __ int3();
     __ bind(&okay);
@@ -4800,7 +4819,7 @@
 
   // Special handling of termination exceptions which are uncatchable
   // by javascript code.
-  __ cmp(eax, FACTORY->termination_exception());
+  __ cmp(eax, masm->isolate()->factory()->termination_exception());
   __ j(equal, throw_termination_exception);
 
   // Handle normal exception.
@@ -4943,11 +4962,11 @@
   // stub, because the builtin stubs may not have been generated yet.
   if (is_construct) {
     ExternalReference construct_entry(
-        Builtins::JSConstructEntryTrampoline,
+        Builtins::kJSConstructEntryTrampoline,
         masm->isolate());
     __ mov(edx, Immediate(construct_entry));
   } else {
-    ExternalReference entry(Builtins::JSEntryTrampoline,
+    ExternalReference entry(Builtins::kJSEntryTrampoline,
                             masm->isolate());
     __ mov(edx, Immediate(entry));
   }
@@ -5101,7 +5120,8 @@
   __ bind(&loop);
   __ cmp(scratch, Operand(prototype));
   __ j(equal, &is_instance);
-  __ cmp(Operand(scratch), Immediate(FACTORY->null_value()));
+  Factory* factory = masm->isolate()->factory();
+  __ cmp(Operand(scratch), Immediate(factory->null_value()));
   __ j(equal, &is_not_instance);
   __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
   __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset));
@@ -5115,7 +5135,7 @@
                                 times_pointer_size, roots_address), eax);
   } else {
     // Get return address and delta to inlined map check.
-    __ mov(eax, FACTORY->true_value());
+    __ mov(eax, factory->true_value());
     __ mov(scratch, Operand(esp, 0 * kPointerSize));
     __ sub(scratch, Operand(esp, 1 * kPointerSize));
     if (FLAG_debug_code) {
@@ -5137,7 +5157,7 @@
         scratch, times_pointer_size, roots_address), eax);
   } else {
     // Get return address and delta to inlined map check.
-    __ mov(eax, FACTORY->false_value());
+    __ mov(eax, factory->false_value());
     __ mov(scratch, Operand(esp, 0 * kPointerSize));
     __ sub(scratch, Operand(esp, 1 * kPointerSize));
     if (FLAG_debug_code) {
@@ -5161,7 +5181,7 @@
   __ j(not_equal, &slow, not_taken);
 
   // Null is not instance of anything.
-  __ cmp(object, FACTORY->null_value());
+  __ cmp(object, factory->null_value());
   __ j(not_equal, &object_not_null);
   __ Set(eax, Immediate(Smi::FromInt(1)));
   __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
@@ -5202,10 +5222,10 @@
     NearLabel true_value, done;
     __ test(eax, Operand(eax));
     __ j(zero, &true_value);
-    __ mov(eax, FACTORY->false_value());
+    __ mov(eax, factory->false_value());
     __ jmp(&done);
     __ bind(&true_value);
-    __ mov(eax, FACTORY->true_value());
+    __ mov(eax, factory->true_value());
     __ bind(&done);
     __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize);
   }
@@ -5334,7 +5354,7 @@
   // the case we would rather go to the runtime system now to flatten
   // the string.
   __ cmp(FieldOperand(object_, ConsString::kSecondOffset),
-         Immediate(FACTORY->empty_string()));
+         Immediate(masm->isolate()->factory()->empty_string()));
   __ j(not_equal, &call_runtime_);
   // Get the first of the two strings and load its instance type.
   __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset));
@@ -5379,7 +5399,10 @@
   // Index is not a smi.
   __ bind(&index_not_smi_);
   // If index is a heap number, try converting it to an integer.
-  __ CheckMap(index_, FACTORY->heap_number_map(), index_not_number_, true);
+  __ CheckMap(index_,
+              masm->isolate()->factory()->heap_number_map(),
+              index_not_number_,
+              true);
   call_helper.BeforeCall(masm);
   __ push(object_);
   __ push(index_);
@@ -5440,7 +5463,8 @@
                     ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
   __ j(not_zero, &slow_case_, not_taken);
 
-  __ Set(result_, Immediate(FACTORY->single_character_string_cache()));
+  Factory* factory = masm->isolate()->factory();
+  __ Set(result_, Immediate(factory->single_character_string_cache()));
   STATIC_ASSERT(kSmiTag == 0);
   STATIC_ASSERT(kSmiTagSize == 1);
   STATIC_ASSERT(kSmiShiftSize == 0);
@@ -5448,7 +5472,7 @@
   __ mov(result_, FieldOperand(result_,
                                code_, times_half_pointer_size,
                                FixedArray::kHeaderSize));
-  __ cmp(result_, FACTORY->undefined_value());
+  __ cmp(result_, factory->undefined_value());
   __ j(equal, &slow_case_, not_taken);
   __ bind(&exit_);
 }
@@ -5534,7 +5558,8 @@
   __ test(ecx, Operand(ecx));
   __ j(not_zero, &second_not_zero_length);
   // Second string is empty, result is first string which is already in eax.
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
   __ bind(&second_not_zero_length);
   __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
@@ -5543,7 +5568,7 @@
   __ j(not_zero, &both_not_zero_length);
   // First string is empty, result is second string which is in edx.
   __ mov(eax, edx);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   // Both strings are non-empty.
@@ -5577,7 +5602,7 @@
   StringHelper::GenerateTwoCharacterSymbolTableProbe(
       masm, ebx, ecx, eax, edx, edi,
       &make_two_character_string_no_reload, &make_two_character_string);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   // Allocate a two character string.
@@ -5589,7 +5614,7 @@
   __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
   __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
   __ bind(&make_two_character_string_no_reload);
-  __ IncrementCounter(COUNTERS->string_add_make_two_char(), 1);
+  __ IncrementCounter(counters->string_add_make_two_char(), 1);
   __ AllocateAsciiString(eax,  // Result.
                          2,    // Length.
                          edi,  // Scratch 1.
@@ -5600,7 +5625,7 @@
   __ or_(ebx, Operand(ecx));
   // Set the characters in the new string.
   __ mov_w(FieldOperand(eax, SeqAsciiString::kHeaderSize), ebx);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   __ bind(&longer_than_two);
@@ -5631,7 +5656,7 @@
   __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax);
   __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx);
   __ mov(eax, ecx);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
   __ bind(&non_ascii);
   // At least one of the strings is two-byte. Check whether it happens
@@ -5708,7 +5733,7 @@
   // edx: first char of second argument
   // edi: length of second argument
   StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   // Handle creating a flat two byte result.
@@ -5749,7 +5774,7 @@
   // edx: first char of second argument
   // edi: length of second argument
   StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   // Just jump to runtime to add the two strings.
@@ -5975,9 +6000,10 @@
                         SymbolTable::kElementsStartOffset));
 
     // If entry is undefined no string with this hash can be found.
-    __ cmp(candidate, FACTORY->undefined_value());
+    Factory* factory = masm->isolate()->factory();
+    __ cmp(candidate, factory->undefined_value());
     __ j(equal, not_found);
-    __ cmp(candidate, FACTORY->null_value());
+    __ cmp(candidate, factory->null_value());
     __ j(equal, &next_probe[i]);
 
     // If length is not 2 the string is not a candidate.
@@ -6174,7 +6200,8 @@
   // esi: character of sub string start
   StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true);
   __ mov(esi, edx);  // Restore esi.
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(3 * kPointerSize);
 
   __ bind(&non_ascii_flat);
@@ -6215,7 +6242,7 @@
   __ mov(esi, edx);  // Restore esi.
 
   __ bind(&return_eax);
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+  __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(3 * kPointerSize);
 
   // Just jump to runtime to create the sub string.
@@ -6234,7 +6261,8 @@
   Label result_greater;
   Label compare_lengths;
 
-  __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->string_compare_native(), 1);
 
   // Find minimum length.
   NearLabel left_shorter;
@@ -6325,7 +6353,7 @@
   STATIC_ASSERT(EQUAL == 0);
   STATIC_ASSERT(kSmiTag == 0);
   __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
-  __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+  __ IncrementCounter(masm->isolate()->counters()->string_compare_native(), 1);
   __ ret(2 * kPointerSize);
 
   __ bind(&not_same);
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 7e93493..cf990a0 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -3347,7 +3347,7 @@
       __ mov(ecx, FieldOperand(eax, JSFunction::kCodeEntryOffset));
       __ sub(Operand(ecx), Immediate(Code::kHeaderSize - kHeapObjectTag));
       Handle<Code> apply_code(masm()->isolate()->builtins()->builtin(
-          Builtins::FunctionApply));
+          Builtins::kFunctionApply));
       __ cmp(Operand(ecx), Immediate(apply_code));
       __ j(not_equal, &build_args);
 
@@ -5696,7 +5696,8 @@
     FastCloneShallowArrayStub stub(
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
     clone = frame_->CallStub(&stub, 3);
-    __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1);
+    Counters* counters = masm()->isolate()->counters();
+    __ IncrementCounter(counters->cow_arrays_created_stub(), 1);
   } else if (node->depth() > 1) {
     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
@@ -9392,7 +9393,7 @@
   }
   __ Set(ecx, Immediate(name_));
   Handle<Code> ic(masm()->isolate()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+      Builtins::kLoadIC_Initialize));
   RelocInfo::Mode mode = is_contextual_
       ? RelocInfo::CODE_TARGET_CONTEXT
       : RelocInfo::CODE_TARGET;
@@ -9409,15 +9410,16 @@
   int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
   // Here we use masm_-> instead of the __ macro because this is the
   // instruction that gets patched and coverage code gets in the way.
+  Counters* counters = masm()->isolate()->counters();
   if (is_contextual_) {
     masm_->mov(is_dont_delete_ ? edx : ecx, -delta_to_patch_site);
-    __ IncrementCounter(COUNTERS->named_load_global_inline_miss(), 1);
+    __ IncrementCounter(counters->named_load_global_inline_miss(), 1);
     if (is_dont_delete_) {
-      __ IncrementCounter(COUNTERS->dont_delete_hint_miss(), 1);
+      __ IncrementCounter(counters->dont_delete_hint_miss(), 1);
     }
   } else {
     masm_->test(eax, Immediate(-delta_to_patch_site));
-    __ IncrementCounter(COUNTERS->named_load_inline_miss(), 1);
+    __ IncrementCounter(counters->named_load_inline_miss(), 1);
   }
 
   if (!dst_.is(eax)) __ mov(dst_, eax);
@@ -9472,7 +9474,7 @@
   // This means that we cannot allow test instructions after calls to
   // KeyedLoadIC stubs in other places.
   Handle<Code> ic(masm()->isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+      Builtins::kKeyedLoadIC_Initialize));
   __ call(ic, RelocInfo::CODE_TARGET);
   // The delta from the start of the map-compare instruction to the
   // test instruction.  We use masm_-> directly here instead of the __
@@ -9483,7 +9485,8 @@
   // Here we use masm_-> instead of the __ macro because this is the
   // instruction that gets patched and coverage code gets in the way.
   masm_->test(eax, Immediate(-delta_to_patch_site));
-  __ IncrementCounter(COUNTERS->keyed_load_inline_miss(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_inline_miss(), 1);
 
   if (!dst_.is(eax)) __ mov(dst_, eax);
 }
@@ -9519,7 +9522,8 @@
 
 
 void DeferredReferenceSetKeyedValue::Generate() {
-  __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_store_inline_miss(), 1);
   // Move value_ to eax, key_ to ecx, and receiver_ to edx.
   Register old_value = value_;
 
@@ -9574,8 +9578,8 @@
 
   // Call the IC stub.
   Handle<Code> ic(masm()->isolate()->builtins()->builtin(
-      (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
-                                    : Builtins::KeyedStoreIC_Initialize));
+      (strict_mode_ == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+                                    : Builtins::kKeyedStoreIC_Initialize));
   __ call(ic, RelocInfo::CODE_TARGET);
   // The delta from the start of the map-compare instruction to the
   // test instruction.  We use masm_-> directly here instead of the
@@ -9596,9 +9600,13 @@
   int original_height = frame()->height();
 #endif
 
+  Isolate* isolate = masm()->isolate();
+  Factory* factory = isolate->factory();
+  Counters* counters = isolate->counters();
+
   bool contextual_load_in_builtin =
       is_contextual &&
-      (masm()->isolate()->bootstrapper()->IsActive() ||
+      (isolate->bootstrapper()->IsActive() ||
        (!info_->closure().is_null() && info_->closure()->IsBuiltin()));
 
   Result result;
@@ -9644,7 +9652,7 @@
     // use the double underscore macro that may insert instructions).
     // Initially use an invalid map to force a failure.
     masm()->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
-                Immediate(FACTORY->null_value()));
+                Immediate(factory->null_value()));
     // This branch is always a forwards branch so it's always a fixed size
     // which allows the assert below to succeed and patching to work.
     deferred->Branch(not_equal);
@@ -9656,15 +9664,15 @@
 
     if (is_contextual) {
       // Load the (initialy invalid) cell and get its value.
-      masm()->mov(result.reg(), FACTORY->null_value());
+      masm()->mov(result.reg(), factory->null_value());
       if (FLAG_debug_code) {
         __ cmp(FieldOperand(result.reg(), HeapObject::kMapOffset),
-               FACTORY->global_property_cell_map());
+               factory->global_property_cell_map());
         __ Assert(equal, "Uninitialized inlined contextual load");
       }
       __ mov(result.reg(),
              FieldOperand(result.reg(), JSGlobalPropertyCell::kValueOffset));
-      __ cmp(result.reg(), FACTORY->the_hole_value());
+      __ cmp(result.reg(), factory->the_hole_value());
       deferred->Branch(equal);
       bool is_dont_delete = false;
       if (!info_->closure().is_null()) {
@@ -9684,15 +9692,15 @@
       }
       deferred->set_is_dont_delete(is_dont_delete);
       if (!is_dont_delete) {
-        __ cmp(result.reg(), FACTORY->the_hole_value());
+        __ cmp(result.reg(), factory->the_hole_value());
         deferred->Branch(equal);
       } else if (FLAG_debug_code) {
-        __ cmp(result.reg(), FACTORY->the_hole_value());
+        __ cmp(result.reg(), factory->the_hole_value());
         __ Check(not_equal, "DontDelete cells can't contain the hole");
       }
-      __ IncrementCounter(COUNTERS->named_load_global_inline(), 1);
+      __ IncrementCounter(counters->named_load_global_inline(), 1);
       if (is_dont_delete) {
-        __ IncrementCounter(COUNTERS->dont_delete_hint_hit(), 1);
+        __ IncrementCounter(counters->dont_delete_hint_hit(), 1);
       }
     } else {
       // The initial (invalid) offset has to be large enough to force a 32-bit
@@ -9700,7 +9708,7 @@
       // kMaxInt (minus kHeapObjectTag).
       int offset = kMaxInt;
       masm()->mov(result.reg(), FieldOperand(receiver.reg(), offset));
-      __ IncrementCounter(COUNTERS->named_load_inline(), 1);
+      __ IncrementCounter(counters->named_load_inline(), 1);
     }
 
     deferred->BindExit();
@@ -9888,7 +9896,7 @@
     result = elements;
     __ cmp(Operand(result.reg()), Immediate(FACTORY->the_hole_value()));
     deferred->Branch(equal);
-    __ IncrementCounter(COUNTERS->keyed_load_inline(), 1);
+    __ IncrementCounter(masm_->isolate()->counters()->keyed_load_inline(), 1);
 
     deferred->BindExit();
   } else {
@@ -9993,7 +10001,7 @@
 
     // Store the value.
     __ mov(FixedArrayElementOperand(tmp.reg(), key.reg()), result.reg());
-    __ IncrementCounter(COUNTERS->keyed_store_inline(), 1);
+    __ IncrementCounter(masm_->isolate()->counters()->keyed_store_inline(), 1);
 
     deferred->BindExit();
   } else {
@@ -10224,7 +10232,7 @@
     __ test(Operand(src), Immediate(0x0F));
     __ j(not_zero, &unaligned_source);
     {
-      __ IncrementCounter(COUNTERS->memcopy_aligned(), 1);
+      __ IncrementCounter(masm.isolate()->counters()->memcopy_aligned(), 1);
       // Copy loop for aligned source and destination.
       __ mov(edx, count);
       Register loop_count = ecx;
@@ -10272,7 +10280,7 @@
       // Copy loop for unaligned source and aligned destination.
       // If source is not aligned, we can't read it as efficiently.
       __ bind(&unaligned_source);
-      __ IncrementCounter(COUNTERS->memcopy_unaligned(), 1);
+      __ IncrementCounter(masm.isolate()->counters()->memcopy_unaligned(), 1);
       __ mov(edx, ecx);
       Register loop_count = ecx;
       Register count = edx;
@@ -10316,7 +10324,7 @@
     }
 
   } else {
-    __ IncrementCounter(COUNTERS->memcopy_noxmm(), 1);
+    __ IncrementCounter(masm.isolate()->counters()->memcopy_noxmm(), 1);
     // SSE2 not supported. Unlikely to happen in practice.
     __ push(edi);
     __ push(esi);
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index 4eaf7fe..026572f 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -55,12 +55,89 @@
 }
 
 
-void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
-  HandleScope scope;
-  AssertNoAllocation no_allocation;
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  Isolate* isolate = code->GetIsolate();
+  HandleScope scope(isolate);
 
+  // Compute the size of relocation information needed for the code
+  // patching in Deoptimizer::DeoptimizeFunction.
+  int min_reloc_size = 0;
+  Address prev_reloc_address = code->instruction_start();
+  Address code_start_address = code->instruction_start();
+  SafepointTable table(*code);
+  for (unsigned i = 0; i < table.length(); ++i) {
+    Address curr_reloc_address = code_start_address + table.GetPcOffset(i);
+    ASSERT_GE(curr_reloc_address, prev_reloc_address);
+    SafepointEntry safepoint_entry = table.GetEntry(i);
+    int deoptimization_index = safepoint_entry.deoptimization_index();
+    if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) {
+      // The gap code is needed to get to the state expected at the
+      // bailout and we need to skip the call opcode to get to the
+      // address that needs reloc.
+      curr_reloc_address += safepoint_entry.gap_code_size() + 1;
+      int pc_delta = curr_reloc_address - prev_reloc_address;
+      // We use RUNTIME_ENTRY reloc info which has a size of 2 bytes
+      // if encodable with small pc delta encoding and up to 6 bytes
+      // otherwise.
+      if (pc_delta <= RelocInfo::kMaxSmallPCDelta) {
+        min_reloc_size += 2;
+      } else {
+        min_reloc_size += 6;
+      }
+      prev_reloc_address = curr_reloc_address;
+    }
+  }
+
+  // If the relocation information is not big enough we create a new
+  // relocation info object that is padded with comments to make it
+  // big enough for lazy doptimization.
+  int reloc_length = code->relocation_info()->length();
+  if (min_reloc_size > reloc_length) {
+    int comment_reloc_size = RelocInfo::kMinRelocCommentSize;
+    // Padding needed.
+    int min_padding = min_reloc_size - reloc_length;
+    // Number of comments needed to take up at least that much space.
+    int additional_comments =
+        (min_padding + comment_reloc_size - 1) / comment_reloc_size;
+    // Actual padding size.
+    int padding = additional_comments * comment_reloc_size;
+    // Allocate new relocation info and copy old relocation to the end
+    // of the new relocation info array because relocation info is
+    // written and read backwards.
+    Factory* factory = isolate->factory();
+    Handle<ByteArray> new_reloc =
+        factory->NewByteArray(reloc_length + padding, TENURED);
+    memcpy(new_reloc->GetDataStartAddress() + padding,
+           code->relocation_info()->GetDataStartAddress(),
+           reloc_length);
+    // Create a relocation writer to write the comments in the padding
+    // space. Use position 0 for everything to ensure short encoding.
+    RelocInfoWriter reloc_info_writer(
+        new_reloc->GetDataStartAddress() + padding, 0);
+    intptr_t comment_string
+        = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString);
+    RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string);
+    for (int i = 0; i < additional_comments; ++i) {
+#ifdef DEBUG
+      byte* pos_before = reloc_info_writer.pos();
+#endif
+      reloc_info_writer.Write(&rinfo);
+      ASSERT(RelocInfo::kMinRelocCommentSize ==
+             pos_before - reloc_info_writer.pos());
+    }
+    // Replace relocation information on the code object.
+    code->set_relocation_info(*new_reloc);
+  }
+}
+
+
+void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
   if (!function->IsOptimized()) return;
 
+  Isolate* isolate = function->GetIsolate();
+  HandleScope scope(isolate);
+  AssertNoAllocation no_allocation;
+
   // Get the optimized code.
   Code* code = function->code();
   Address code_start_address = code->instruction_start();
@@ -119,11 +196,12 @@
   // a non-live object in the extra space at the end of the former reloc info.
   Address junk_address = reloc_info->address() + reloc_info->Size();
   ASSERT(junk_address <= reloc_end_address);
-  HEAP->CreateFillerObjectAt(junk_address, reloc_end_address - junk_address);
+  isolate->heap()->CreateFillerObjectAt(junk_address,
+                                        reloc_end_address - junk_address);
 
   // Add the deoptimizing code to the list.
   DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
-  DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
+  DeoptimizerData* data = isolate->deoptimizer_data();
   node->set_next(data->deoptimizing_code_list_);
   data->deoptimizing_code_list_ = node;
 
@@ -325,7 +403,7 @@
     output_[0]->SetPc(pc);
   }
   Code* continuation =
-      Isolate::Current()->builtins()->builtin(Builtins::NotifyOSR);
+      function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
   output_[0]->SetContinuation(
       reinterpret_cast<uint32_t>(continuation->entry()));
 
@@ -494,8 +572,8 @@
   if (is_topmost) {
     Builtins* builtins = isolate_->builtins();
     Code* continuation = (bailout_type_ == EAGER)
-        ? builtins->builtin(Builtins::NotifyDeoptimized)
-        : builtins->builtin(Builtins::NotifyLazyDeoptimized);
+        ? builtins->builtin(Builtins::kNotifyDeoptimized)
+        : builtins->builtin(Builtins::kNotifyLazyDeoptimized);
     output_frame->SetContinuation(
         reinterpret_cast<uint32_t>(continuation->entry()));
   }
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index cc2f849..d1c869a 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -1373,6 +1373,12 @@
             get_modrm(*data, &mod, &regop, &rm);
             AppendToBuffer("movsd %s,", NameOfXMMRegister(regop));
             data += PrintRightXMMOperand(data);
+          } else  if (b2 == 0x5A) {
+            data += 3;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("cvtsd2ss %s,", NameOfXMMRegister(regop));
+            data += PrintRightXMMOperand(data);
           } else {
             const char* mnem = "?";
             switch (b2) {
@@ -1422,25 +1428,39 @@
 
       case 0xF3:
         if (*(data+1) == 0x0F) {
-          if (*(data+2) == 0x2C) {
+          byte b2 = *(data+2);
+          if (b2 == 0x11) {
+            AppendToBuffer("movss ");
+            data += 3;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            data += PrintRightXMMOperand(data);
+            AppendToBuffer(",%s", NameOfXMMRegister(regop));
+          } else if (b2 == 0x10) {
+            data += 3;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("movss %s,", NameOfXMMRegister(regop));
+            data += PrintRightXMMOperand(data);
+          } else if (b2 == 0x2C) {
             data += 3;
             int mod, regop, rm;
             get_modrm(*data, &mod, &regop, &rm);
             AppendToBuffer("cvttss2si %s,", NameOfCPURegister(regop));
             data += PrintRightXMMOperand(data);
-          } else  if (*(data+2) == 0x5A) {
+          } else if (b2 == 0x5A) {
             data += 3;
             int mod, regop, rm;
             get_modrm(*data, &mod, &regop, &rm);
             AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
             data += PrintRightXMMOperand(data);
-          } else  if (*(data+2) == 0x6F) {
+          } else  if (b2 == 0x6F) {
             data += 3;
             int mod, regop, rm;
             get_modrm(*data, &mod, &regop, &rm);
             AppendToBuffer("movdqu %s,", NameOfXMMRegister(regop));
             data += PrintRightXMMOperand(data);
-          } else  if (*(data+2) == 0x7F) {
+          } else  if (b2 == 0x7F) {
             AppendToBuffer("movdqu ");
             data += 3;
             int mod, regop, rm;
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index b1c53d6..16c39c5 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -732,9 +732,9 @@
              prop->key()->AsLiteral()->handle()->IsSmi());
       __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle()));
 
-      Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
-          ? Builtins::KeyedStoreIC_Initialize_Strict
-          : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
     }
   }
@@ -1102,8 +1102,7 @@
   // load IC call.
   __ mov(eax, GlobalObjectOperand());
   __ mov(ecx, slot->var()->name());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
@@ -1186,8 +1185,8 @@
                  ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
                                                    slow));
           __ mov(eax, Immediate(key_literal->handle()));
-          Handle<Code> ic(isolate()->builtins()->builtin(
-              Builtins::KeyedLoadIC_Initialize));
+          Handle<Code> ic =
+              isolate()->builtins()->KeyedLoadIC_Initialize();
           EmitCallIC(ic, RelocInfo::CODE_TARGET);
           __ jmp(done);
         }
@@ -1210,8 +1209,7 @@
     // object on the stack.
     __ mov(eax, GlobalObjectOperand());
     __ mov(ecx, var->name());
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::LoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
     context()->Plug(eax);
 
@@ -1274,8 +1272,7 @@
     __ mov(eax, Immediate(key_literal->handle()));
 
     // Do a keyed property load.
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET);
 
     // Drop key and object left on the stack by IC.
@@ -1386,9 +1383,9 @@
             VisitForAccumulatorValue(value);
             __ mov(ecx, Immediate(key->handle()));
             __ mov(edx, Operand(esp, 0));
-            Handle<Code> ic(isolate()->builtins()->builtin(
-                is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                                 : Builtins::StoreIC_Initialize));
+            Handle<Code> ic = is_strict_mode()
+                ? isolate()->builtins()->StoreIC_Initialize_Strict()
+                : isolate()->builtins()->StoreIC_Initialize();
             EmitCallIC(ic, RelocInfo::CODE_TARGET);
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           } else {
@@ -1637,16 +1634,14 @@
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   __ mov(ecx, Immediate(key->handle()));
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 }
 
 
 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 }
 
@@ -1787,9 +1782,9 @@
       __ mov(edx, eax);
       __ pop(eax);  // Restore value.
       __ mov(ecx, prop->key()->AsLiteral()->handle());
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                           : Builtins::StoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->StoreIC_Initialize_Strict()
+          : isolate()->builtins()->StoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       break;
     }
@@ -1810,9 +1805,9 @@
         __ pop(edx);
       }
       __ pop(eax);  // Restore value.
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                           : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       break;
     }
@@ -1836,9 +1831,9 @@
     // ecx, and the global object on the stack.
     __ mov(ecx, var->name());
     __ mov(edx, GlobalObjectOperand());
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                         : Builtins::StoreIC_Initialize));
+    Handle<Code> ic = is_strict_mode()
+        ? isolate()->builtins()->StoreIC_Initialize_Strict()
+        : isolate()->builtins()->StoreIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
 
   } else if (op == Token::INIT_CONST) {
@@ -1939,9 +1934,9 @@
   } else {
     __ pop(edx);
   }
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                       : Builtins::StoreIC_Initialize));
+  Handle<Code> ic = is_strict_mode()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 
   // If the assignment ends an initialization block, revert to fast case.
@@ -1979,9 +1974,9 @@
   }
   // Record source code position before IC call.
   SetSourcePosition(expr->position());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                       : Builtins::KeyedStoreIC_Initialize));
+  Handle<Code> ic = is_strict_mode()
+      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+      : isolate()->builtins()->KeyedStoreIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 
   // If the assignment ends an initialization block, revert to fast case.
@@ -2102,7 +2097,7 @@
   if (arg_count > 0) {
     __ push(Operand(esp, arg_count * kPointerSize));
   } else {
-    __ push(Immediate(FACTORY->undefined_value()));
+    __ push(Immediate(isolate()->factory()->undefined_value()));
   }
 
   // Push the receiver of the enclosing function.
@@ -2257,8 +2252,7 @@
         // Record source code position for IC call.
         SetSourcePosition(prop->position());
 
-        Handle<Code> ic(isolate()->builtins()->builtin(
-            Builtins::KeyedLoadIC_Initialize));
+        Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
         EmitCallIC(ic, RelocInfo::CODE_TARGET);
         // Push result (function).
         __ push(eax);
@@ -2326,8 +2320,8 @@
   __ Set(eax, Immediate(arg_count));
   __ mov(edi, Operand(esp, arg_count * kPointerSize));
 
-  Handle<Code> construct_builtin(isolate()->builtins()->builtin(
-      Builtins::JSConstructCall));
+  Handle<Code> construct_builtin =
+      isolate()->builtins()->JSConstructCall();
   __ call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
   context()->Plug(eax);
 }
@@ -2806,8 +2800,12 @@
   VisitForStackValue(args->at(0));
   VisitForStackValue(args->at(1));
 
-  MathPowStub stub;
-  __ CallStub(&stub);
+  if (isolate()->cpu_features()->IsSupported(SSE2)) {
+    MathPowStub stub;
+    __ CallStub(&stub);
+  } else {
+    __ CallRuntime(Runtime::kMath_pow, 2);
+  }
   context()->Plug(eax);
 }
 
@@ -3309,7 +3307,7 @@
   __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset));
   __ SmiUntag(array_length);
   __ j(not_zero, &non_trivial_array);
-  __ mov(result_operand, FACTORY->empty_string());
+  __ mov(result_operand, isolate()->factory()->empty_string());
   __ jmp(&done);
 
   // Save the array length.
@@ -3520,7 +3518,7 @@
 
 
   __ bind(&bailout);
-  __ mov(result_operand, FACTORY->undefined_value());
+  __ mov(result_operand, isolate()->factory()->undefined_value());
   __ bind(&done);
   __ mov(eax, result_operand);
   // Drop temp values from the stack, and restore context register.
@@ -3873,9 +3871,9 @@
     case NAMED_PROPERTY: {
       __ mov(ecx, prop->key()->AsLiteral()->handle());
       __ pop(edx);
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                           : Builtins::StoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->StoreIC_Initialize_Strict()
+          : isolate()->builtins()->StoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
@@ -3890,9 +3888,9 @@
     case KEYED_PROPERTY: {
       __ pop(ecx);
       __ pop(edx);
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                           : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
@@ -3918,8 +3916,7 @@
     Comment cmnt(masm_, "Global variable");
     __ mov(eax, GlobalObjectOperand());
     __ mov(ecx, Immediate(proxy->name()));
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::LoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
     EmitCallIC(ic, RelocInfo::CODE_TARGET);
@@ -4227,18 +4224,19 @@
 
 
 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
+  Counters* counters = isolate()->counters();
   switch (ic->kind()) {
     case Code::LOAD_IC:
-      __ IncrementCounter(COUNTERS->named_load_full(), 1);
+      __ IncrementCounter(counters->named_load_full(), 1);
       break;
     case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
+      __ IncrementCounter(counters->keyed_load_full(), 1);
       break;
     case Code::STORE_IC:
-      __ IncrementCounter(COUNTERS->named_store_full(), 1);
+      __ IncrementCounter(counters->named_store_full(), 1);
       break;
     case Code::KEYED_STORE_IC:
-      __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
+      __ IncrementCounter(counters->keyed_store_full(), 1);
     default:
       break;
   }
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index f2558bf..48ffc73 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -555,7 +555,9 @@
                         eax,
                         NULL,
                         &slow);
-  __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1);
+  Isolate* isolate = masm->isolate();
+  Counters* counters = isolate->counters();
+  __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
   __ ret(0);
 
   __ bind(&check_number_dictionary);
@@ -568,7 +570,7 @@
   // ebx: untagged index
   // eax: key
   // ecx: elements
-  __ CheckMap(ecx, FACTORY->hash_table_map(), &slow, true);
+  __ CheckMap(ecx, isolate->factory()->hash_table_map(), &slow, true);
   Label slow_pop_receiver;
   // Push receiver on the stack to free up a register for the dictionary
   // probing.
@@ -593,7 +595,7 @@
   // Slow case: jump to runtime.
   // edx: receiver
   // eax: key
-  __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
   GenerateRuntimeGetProperty(masm);
 
   __ bind(&check_string);
@@ -606,7 +608,7 @@
   // cache. Otherwise probe the dictionary.
   __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
   __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
-         Immediate(FACTORY->hash_table_map()));
+         Immediate(isolate->factory()->hash_table_map()));
   __ j(equal, &probe_dictionary);
 
   // Load the map of the receiver, compute the keyed lookup cache hash
@@ -648,7 +650,7 @@
   __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
   __ add(ecx, Operand(edi));
   __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
-  __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
   __ ret(0);
 
   // Load property array property.
@@ -656,7 +658,7 @@
   __ mov(eax, FieldOperand(edx, JSObject::kPropertiesOffset));
   __ mov(eax, FieldOperand(eax, edi, times_pointer_size,
                            FixedArray::kHeaderSize));
-  __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
   __ ret(0);
 
   // Do a quick inline probe of the receiver's dictionary, if it
@@ -668,7 +670,7 @@
   GenerateGlobalInstanceTypeCheck(masm, ecx, &slow);
 
   GenerateDictionaryLoad(masm, &slow, ebx, eax, ecx, edi, eax);
-  __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
   __ ret(0);
 
   __ bind(&index_string);
@@ -967,10 +969,11 @@
   //  -- esp[(argc + 1) * 4] : receiver
   // -----------------------------------
 
+  Counters* counters = masm->isolate()->counters();
   if (id == IC::kCallIC_Miss) {
-    __ IncrementCounter(COUNTERS->call_miss(), 1);
+    __ IncrementCounter(counters->call_miss(), 1);
   } else {
-    __ IncrementCounter(COUNTERS->keyed_call_miss(), 1);
+    __ IncrementCounter(counters->keyed_call_miss(), 1);
   }
 
   // Get the receiver of the function from the stack; 1 ~ return address.
@@ -1092,7 +1095,9 @@
 
   GenerateFastArrayLoad(
       masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1);
+  Isolate* isolate = masm->isolate();
+  Counters* counters = isolate->counters();
+  __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1);
 
   __ bind(&do_call);
   // receiver in edx is not used after this point.
@@ -1104,14 +1109,14 @@
   // eax: elements
   // ecx: smi key
   // Check whether the elements is a number dictionary.
-  __ CheckMap(eax, FACTORY->hash_table_map(), &slow_load, true);
+  __ CheckMap(eax, isolate->factory()->hash_table_map(), &slow_load, true);
   __ mov(ebx, ecx);
   __ SmiUntag(ebx);
   // ebx: untagged index
   // Receiver in edx will be clobbered, need to reload it on miss.
   GenerateNumberDictionaryLoad(
       masm, &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
   __ jmp(&do_call);
 
   __ bind(&slow_reload_receiver);
@@ -1120,7 +1125,7 @@
   __ bind(&slow_load);
   // This branch is taken when calling KeyedCallIC_Miss is neither required
   // nor beneficial.
-  __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
   __ EnterInternalFrame();
   __ push(ecx);  // save the key
   __ push(edx);  // pass the receiver
@@ -1142,14 +1147,17 @@
       masm, edx, eax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache);
 
   __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
-  __ CheckMap(ebx, FACTORY->hash_table_map(), &lookup_monomorphic_cache, true);
+  __ CheckMap(ebx,
+              isolate->factory()->hash_table_map(),
+              &lookup_monomorphic_cache,
+              true);
 
   GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
   __ jmp(&do_call);
 
   __ bind(&lookup_monomorphic_cache);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
   GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
   // Fall through on miss.
 
@@ -1160,7 +1168,7 @@
   // - the value loaded is not a function,
   // - there is hope that the runtime will create a monomorphic call stub
   //   that will get fetched next time.
-  __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
   GenerateMiss(masm, argc);
 
   __ bind(&index_string);
@@ -1251,7 +1259,7 @@
   //  -- esp[0] : return address
   // -----------------------------------
 
-  __ IncrementCounter(COUNTERS->load_miss(), 1);
+  __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
 
   __ pop(ebx);
   __ push(eax);  // receiver
@@ -1438,7 +1446,7 @@
   //  -- esp[0] : return address
   // -----------------------------------
 
-  __ IncrementCounter(COUNTERS->keyed_load_miss(), 1);
+  __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1);
 
   __ pop(ebx);
   __ push(edx);  // receiver
@@ -1589,14 +1597,15 @@
   __ push(edx);
   GenerateDictionaryStore(masm, &restore_miss, ebx, ecx, eax, edx, edi);
   __ Drop(1);
-  __ IncrementCounter(COUNTERS->store_normal_hit(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->store_normal_hit(), 1);
   __ ret(0);
 
   __ bind(&restore_miss);
   __ pop(edx);
 
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->store_normal_miss(), 1);
+  __ IncrementCounter(counters->store_normal_miss(), 1);
   GenerateMiss(masm);
 }
 
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index ef30b68..fff754b 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -31,6 +31,7 @@
 
 #include "ia32/lithium-codegen-ia32.h"
 #include "code-stubs.h"
+#include "deoptimizer.h"
 #include "stub-cache.h"
 
 namespace v8 {
@@ -43,20 +44,13 @@
  public:
   SafepointGenerator(LCodeGen* codegen,
                      LPointerMap* pointers,
-                     int deoptimization_index,
-                     bool ensure_reloc_space = false)
+                     int deoptimization_index)
       : codegen_(codegen),
         pointers_(pointers),
-        deoptimization_index_(deoptimization_index),
-        ensure_reloc_space_(ensure_reloc_space) { }
+        deoptimization_index_(deoptimization_index) {}
   virtual ~SafepointGenerator() { }
 
   virtual void Generate() {
-    // Ensure that we have enough space in the reloc info to patch
-    // this with calls when doing deoptimization.
-    if (ensure_reloc_space_) {
-      codegen_->EnsureRelocSpaceForDeoptimization();
-    }
     codegen_->RecordSafepoint(pointers_, deoptimization_index_);
   }
 
@@ -64,7 +58,6 @@
   LCodeGen* codegen_;
   LPointerMap* pointers_;
   int deoptimization_index_;
-  bool ensure_reloc_space_;
 };
 
 
@@ -78,7 +71,6 @@
   return GeneratePrologue() &&
       GenerateBody() &&
       GenerateDeferredCode() &&
-      GenerateRelocPadding() &&
       GenerateSafepointTable();
 }
 
@@ -88,6 +80,7 @@
   code->set_stack_slots(StackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
   PopulateDeoptimizationData(code);
+  Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
 }
 
 
@@ -385,22 +378,6 @@
 }
 
 
-void LCodeGen::EnsureRelocSpaceForDeoptimization() {
-  // Since we patch the reloc info with RUNTIME_ENTRY calls every patch
-  // site will take up 2 bytes + any pc-jumps.
-  // We are conservative and always reserver 6 bytes in case where a
-  // simple pc-jump is not enough.
-  uint32_t pc_delta =
-      masm()->pc_offset() - deoptimization_reloc_size.last_pc_offset;
-  if (is_uintn(pc_delta, 6)) {
-    deoptimization_reloc_size.min_size += 2;
-  } else {
-    deoptimization_reloc_size.min_size += 6;
-  }
-  deoptimization_reloc_size.last_pc_offset = masm()->pc_offset();
-}
-
-
 void LCodeGen::AddToTranslation(Translation* translation,
                                 LOperand* op,
                                 bool is_tagged) {
@@ -454,7 +431,6 @@
   }
   __ call(code, mode);
 
-  EnsureRelocSpaceForDeoptimization();
   RegisterLazyDeoptimization(instr);
 
   // Signal that we don't inline smi code before these stubs in the
@@ -479,6 +455,7 @@
     __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   }
   __ CallRuntime(fun, argc);
+
   RegisterLazyDeoptimization(instr);
 }
 
@@ -2113,7 +2090,7 @@
 
 
 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
-  Register object = ToRegister(instr->InputAt(0));
+  Register object = ToRegister(instr->object());
   Register result = ToRegister(instr->result());
   if (instr->hydrogen()->is_in_object()) {
     __ mov(result, FieldOperand(object, instr->hydrogen()->offset()));
@@ -2124,13 +2101,76 @@
 }
 
 
+void LCodeGen::EmitLoadField(Register result,
+                             Register object,
+                             Handle<Map> type,
+                             Handle<String> name) {
+  LookupResult lookup;
+  type->LookupInDescriptors(NULL, *name, &lookup);
+  ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
+  int index = lookup.GetLocalFieldIndexFromMap(*type);
+  int offset = index * kPointerSize;
+  if (index < 0) {
+    // Negative property indices are in-object properties, indexed
+    // from the end of the fixed part of the object.
+    __ mov(result, FieldOperand(object, offset + type->instance_size()));
+  } else {
+    // Non-negative property indices are in the properties array.
+    __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset));
+    __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
+  }
+}
+
+
+void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
+  Register object = ToRegister(instr->object());
+  Register result = ToRegister(instr->result());
+
+  int map_count = instr->hydrogen()->types()->length();
+  Handle<String> name = instr->hydrogen()->name();
+  if (map_count == 0) {
+    ASSERT(instr->hydrogen()->need_generic());
+    __ mov(ecx, name);
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+    CallCode(ic, RelocInfo::CODE_TARGET, instr, false);
+  } else {
+    NearLabel done;
+    for (int i = 0; i < map_count - 1; ++i) {
+      Handle<Map> map = instr->hydrogen()->types()->at(i);
+      NearLabel next;
+      __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+      __ j(not_equal, &next);
+      EmitLoadField(result, object, map, name);
+      __ jmp(&done);
+      __ bind(&next);
+    }
+    Handle<Map> map = instr->hydrogen()->types()->last();
+    __ cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+    if (instr->hydrogen()->need_generic()) {
+      NearLabel generic;
+      __ j(not_equal, &generic);
+      EmitLoadField(result, object, map, name);
+      __ jmp(&done);
+      __ bind(&generic);
+      __ mov(ecx, name);
+      Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+      CallCode(ic, RelocInfo::CODE_TARGET, instr, false);
+    } else {
+      DeoptimizeIf(not_equal, instr->environment());
+      EmitLoadField(result, object, map, name);
+    }
+    __ bind(&done);
+  }
+}
+
+
 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
   ASSERT(ToRegister(instr->context()).is(esi));
   ASSERT(ToRegister(instr->object()).is(eax));
   ASSERT(ToRegister(instr->result()).is(eax));
 
   __ mov(ecx, instr->name());
-  Handle<Code> ic(isolate()->builtins()->builtin(Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2187,11 +2227,16 @@
            Immediate(factory()->fixed_array_map()));
     __ j(equal, &done);
     __ cmp(FieldOperand(result, HeapObject::kMapOffset),
-           Immediate(factory()->external_pixel_array_map()));
-    __ j(equal, &done);
-    __ cmp(FieldOperand(result, HeapObject::kMapOffset),
            Immediate(factory()->fixed_cow_array_map()));
-    __ Check(equal, "Check for fast elements or pixel array failed.");
+    __ j(equal, &done);
+    Register temp((result.is(eax)) ? ebx : eax);
+    __ push(temp);
+    __ mov(temp, FieldOperand(result, HeapObject::kMapOffset));
+    __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
+    __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
+    __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount));
+    __ pop(temp);
+    __ Check(below, "Check for fast elements or pixel array failed.");
     __ bind(&done);
   }
 }
@@ -2239,14 +2284,47 @@
 }
 
 
-void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
+void LCodeGen::DoLoadKeyedSpecializedArrayElement(
+    LLoadKeyedSpecializedArrayElement* instr) {
   Register external_pointer = ToRegister(instr->external_pointer());
   Register key = ToRegister(instr->key());
-  Register result = ToRegister(instr->result());
-  ASSERT(result.is(external_pointer));
-
-  // Load the result.
-  __ movzx_b(result, Operand(external_pointer, key, times_1, 0));
+  ExternalArrayType array_type = instr->array_type();
+  if (array_type == kExternalFloatArray) {
+    XMMRegister result(ToDoubleRegister(instr->result()));
+    __ movss(result, Operand(external_pointer, key, times_4, 0));
+    __ cvtss2sd(result, result);
+  } else {
+    Register result(ToRegister(instr->result()));
+    switch (array_type) {
+      case kExternalByteArray:
+        __ movsx_b(result, Operand(external_pointer, key, times_1, 0));
+        break;
+      case kExternalUnsignedByteArray:
+      case kExternalPixelArray:
+        __ movzx_b(result, Operand(external_pointer, key, times_1, 0));
+        break;
+      case kExternalShortArray:
+        __ movsx_w(result, Operand(external_pointer, key, times_2, 0));
+        break;
+      case kExternalUnsignedShortArray:
+        __ movzx_w(result, Operand(external_pointer, key, times_2, 0));
+        break;
+      case kExternalIntArray:
+        __ mov(result, Operand(external_pointer, key, times_4, 0));
+        break;
+      case kExternalUnsignedIntArray:
+        __ mov(result, Operand(external_pointer, key, times_4, 0));
+        __ test(Operand(result), Immediate(0x80000000));
+        // TODO(danno): we could be more clever here, perhaps having a special
+        // version of the stub that detects if the overflow case actually
+        // happens, and generate code that returns a double rather than int.
+        DeoptimizeIf(not_zero, instr->environment());
+        break;
+      case kExternalFloatArray:
+        UNREACHABLE();
+        break;
+    }
+  }
 }
 
 
@@ -2255,8 +2333,7 @@
   ASSERT(ToRegister(instr->object()).is(edx));
   ASSERT(ToRegister(instr->key()).is(eax));
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2370,8 +2447,7 @@
   RegisterEnvironmentForDeoptimization(env);
   SafepointGenerator safepoint_generator(this,
                                          pointers,
-                                         env->deoptimization_index(),
-                                         true);
+                                         env->deoptimization_index());
   v8::internal::ParameterCount actual(eax);
   __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
 }
@@ -2443,7 +2519,6 @@
     __ CallSelf();
   } else {
     __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
-    EnsureRelocSpaceForDeoptimization();
   }
 
   // Setup deoptimization.
@@ -2813,8 +2888,7 @@
   ASSERT(ToRegister(instr->constructor()).is(edi));
   ASSERT(ToRegister(instr->result()).is(eax));
 
-  Handle<Code> builtin(isolate()->builtins()->builtin(
-      Builtins::JSConstructCall));
+  Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
   __ Set(eax, Immediate(instr->arity()));
   CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
 }
@@ -2861,9 +2935,9 @@
   ASSERT(ToRegister(instr->value()).is(eax));
 
   __ mov(ecx, instr->name());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      info_->is_strict() ? Builtins::StoreIC_Initialize_Strict
-                         : Builtins::StoreIC_Initialize));
+  Handle<Code> ic = info_->is_strict()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2874,22 +2948,52 @@
 }
 
 
-void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) {
+void LCodeGen::DoStoreKeyedSpecializedArrayElement(
+    LStoreKeyedSpecializedArrayElement* instr) {
   Register external_pointer = ToRegister(instr->external_pointer());
   Register key = ToRegister(instr->key());
-  Register value = ToRegister(instr->value());
-  ASSERT(ToRegister(instr->TempAt(0)).is(eax));
-
-  __ mov(eax, value);
-  {  // Clamp the value to [0..255].
-    NearLabel done;
-    __ test(eax, Immediate(0xFFFFFF00));
-    __ j(zero, &done);
-    __ setcc(negative, eax);  // 1 if negative, 0 if positive.
-    __ dec_b(eax);  // 0 if negative, 255 if positive.
-    __ bind(&done);
+  ExternalArrayType array_type = instr->array_type();
+  if (array_type == kExternalFloatArray) {
+    __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
+    __ movss(Operand(external_pointer, key, times_4, 0), xmm0);
+  } else {
+    Register value = ToRegister(instr->value());
+    switch (array_type) {
+      case kExternalPixelArray: {
+        // Clamp the value to [0..255].
+        Register temp = ToRegister(instr->TempAt(0));
+        // The dec_b below requires that the clamped value is in a byte
+        // register. eax is an arbitrary choice to satisfy this requirement, we
+        // hinted the register allocator to give us eax when building the
+        // instruction.
+        ASSERT(temp.is(eax));
+        __ mov(temp, ToRegister(instr->value()));
+        NearLabel done;
+        __ test(temp, Immediate(0xFFFFFF00));
+        __ j(zero, &done);
+        __ setcc(negative, temp);  // 1 if negative, 0 if positive.
+        __ dec_b(temp);  // 0 if negative, 255 if positive.
+        __ bind(&done);
+        __ mov_b(Operand(external_pointer, key, times_1, 0), temp);
+        break;
+      }
+      case kExternalByteArray:
+      case kExternalUnsignedByteArray:
+        __ mov_b(Operand(external_pointer, key, times_1, 0), value);
+        break;
+      case kExternalShortArray:
+      case kExternalUnsignedShortArray:
+        __ mov_w(Operand(external_pointer, key, times_2, 0), value);
+        break;
+      case kExternalIntArray:
+      case kExternalUnsignedIntArray:
+        __ mov(Operand(external_pointer, key, times_4, 0), value);
+        break;
+      case kExternalFloatArray:
+        UNREACHABLE();
+        break;
+    }
   }
-  __ mov_b(Operand(external_pointer, key, times_1, 0), eax);
 }
 
 
@@ -2931,9 +3035,9 @@
   ASSERT(ToRegister(instr->key()).is(ecx));
   ASSERT(ToRegister(instr->value()).is(eax));
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
-                         : Builtins::KeyedStoreIC_Initialize));
+  Handle<Code> ic = info_->is_strict()
+      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+      : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3973,8 +4077,7 @@
   // builtin)
   SafepointGenerator safepoint_generator(this,
                                          pointers,
-                                         env->deoptimization_index(),
-                                         true);
+                                         env->deoptimization_index());
   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
   __ push(Immediate(Smi::FromInt(strict_mode_flag())));
   __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h
index d06603c..4414e6a 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -246,6 +246,10 @@
   // Caller should branch on equal condition.
   void EmitIsConstructCall(Register temp);
 
+  void EmitLoadField(Register result,
+                     Register object,
+                     Handle<Map> type,
+                     Handle<String> name);
 
   LChunk* const chunk_;
   MacroAssembler* const masm_;
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 96b7937..d23ccdc 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1790,6 +1790,21 @@
 }
 
 
+LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
+    HLoadNamedFieldPolymorphic* instr) {
+  ASSERT(instr->representation().IsTagged());
+  if (instr->need_generic()) {
+    LOperand* obj = UseFixed(instr->object(), eax);
+    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    return MarkAsCall(DefineFixed(result, eax), instr);
+  } else {
+    LOperand* obj = UseRegisterAtStart(instr->object());
+    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    return AssignEnvironment(DefineAsRegister(result));
+  }
+}
+
+
 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
   LOperand* context = UseFixed(instr->context(), esi);
   LOperand* object = UseFixed(instr->object(), eax);
@@ -1830,16 +1845,24 @@
 }
 
 
-LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
-    HLoadPixelArrayElement* instr) {
-  ASSERT(instr->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
+    HLoadKeyedSpecializedArrayElement* instr) {
+  ExternalArrayType array_type = instr->array_type();
+  Representation representation(instr->representation());
+  ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+         (representation.IsDouble() && array_type == kExternalFloatArray));
   ASSERT(instr->key()->representation().IsInteger32());
-  LOperand* external_pointer =
-      UseRegisterAtStart(instr->external_pointer());
-  LOperand* key = UseRegisterAtStart(instr->key());
-  LLoadPixelArrayElement* result =
-      new LLoadPixelArrayElement(external_pointer, key);
-  return DefineSameAsFirst(result);
+  LOperand* external_pointer = UseRegister(instr->external_pointer());
+  LOperand* key = UseRegister(instr->key());
+  LLoadKeyedSpecializedArrayElement* result =
+      new LLoadKeyedSpecializedArrayElement(external_pointer,
+                                            key);
+  LInstruction* load_instr = DefineAsRegister(result);
+  // An unsigned int array load might overflow and cause a deopt, make sure it
+  // has an environment.
+  return (array_type == kExternalUnsignedIntArray)
+      ? AssignEnvironment(load_instr)
+      : load_instr;
 }
 
 
@@ -1872,20 +1895,31 @@
 }
 
 
-LInstruction* LChunkBuilder::DoStorePixelArrayElement(
-    HStorePixelArrayElement* instr) {
-  ASSERT(instr->value()->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
+    HStoreKeyedSpecializedArrayElement* instr) {
+  Representation representation(instr->value()->representation());
+  ExternalArrayType array_type = instr->array_type();
+  ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+         (representation.IsDouble() && array_type == kExternalFloatArray));
   ASSERT(instr->external_pointer()->representation().IsExternal());
   ASSERT(instr->key()->representation().IsInteger32());
 
   LOperand* external_pointer = UseRegister(instr->external_pointer());
   LOperand* val = UseRegister(instr->value());
   LOperand* key = UseRegister(instr->key());
-  // The generated code requires that the clamped value is in a byte
-  // register. eax is an arbitrary choice to satisfy this requirement.
-  LOperand* clamped = FixedTemp(eax);
+  LOperand* temp = NULL;
 
-  return new LStorePixelArrayElement(external_pointer, key, val, clamped);
+  if (array_type == kExternalPixelArray) {
+    // The generated code for pixel array stores requires that the clamped value
+    // is in a byte register. eax is an arbitrary choice to satisfy this
+    // requirement.
+    temp = FixedTemp(eax);
+  }
+
+  return new LStoreKeyedSpecializedArrayElement(external_pointer,
+                                                key,
+                                                val,
+                                                temp);
 }
 
 
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 70ec962..a9d769b 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -124,9 +124,10 @@
   V(LoadGlobal)                                 \
   V(LoadKeyedFastElement)                       \
   V(LoadKeyedGeneric)                           \
+  V(LoadKeyedSpecializedArrayElement)           \
   V(LoadNamedField)                             \
+  V(LoadNamedFieldPolymorphic)                  \
   V(LoadNamedGeneric)                           \
-  V(LoadPixelArrayElement)                      \
   V(ModI)                                       \
   V(MulI)                                       \
   V(NumberTagD)                                 \
@@ -148,9 +149,9 @@
   V(StoreGlobal)                                \
   V(StoreKeyedFastElement)                      \
   V(StoreKeyedGeneric)                          \
+  V(StoreKeyedSpecializedArrayElement)          \
   V(StoreNamedField)                            \
   V(StoreNamedGeneric)                          \
-  V(StorePixelArrayElement)                     \
   V(StringCharCodeAt)                           \
   V(StringCharFromCode)                         \
   V(StringLength)                               \
@@ -1171,6 +1172,21 @@
 
   DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
   DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
+
+  LOperand* object() { return inputs_[0]; }
+};
+
+
+class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LLoadNamedFieldPolymorphic(LOperand* object) {
+    inputs_[0] = object;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
+  DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
+
+  LOperand* object() { return inputs_[0]; }
 };
 
 
@@ -1240,19 +1256,23 @@
 };
 
 
-class LLoadPixelArrayElement: public LTemplateInstruction<1, 2, 0> {
+class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
  public:
-  LLoadPixelArrayElement(LOperand* external_pointer, LOperand* key) {
+  LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
+                                    LOperand* key) {
     inputs_[0] = external_pointer;
     inputs_[1] = key;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
-                               "load-pixel-array-element")
-  DECLARE_HYDROGEN_ACCESSOR(LoadPixelArrayElement)
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+                               "load-keyed-specialized-array-element")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
+  ExternalArrayType array_type() const {
+    return hydrogen()->array_type();
+  }
 };
 
 
@@ -1658,25 +1678,28 @@
 };
 
 
-class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 1> {
+class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 1> {
  public:
-  LStorePixelArrayElement(LOperand* external_pointer,
-                          LOperand* key,
-                          LOperand* val,
-                          LOperand* clamped) {
+  LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
+                                     LOperand* key,
+                                     LOperand* val,
+                                     LOperand* temp) {
     inputs_[0] = external_pointer;
     inputs_[1] = key;
     inputs_[2] = val;
-    temps_[0] = clamped;
+    temps_[0] = temp;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
-                               "store-pixel-array-element")
-  DECLARE_HYDROGEN_ACCESSOR(StorePixelArrayElement)
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+                               "store-keyed-specialized-array-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
+  ExternalArrayType array_type() const {
+    return hydrogen()->array_type();
+  }
 };
 
 
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 950cf31..ba30c49 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -45,7 +45,7 @@
     : Assembler(buffer, size),
       generating_stub_(false),
       allow_stub_calls_(true),
-      code_object_(HEAP->undefined_value()) {
+      code_object_(isolate()->heap()->undefined_value()) {
 }
 
 
@@ -250,7 +250,7 @@
   test(object, Immediate(kSmiTagMask));
   j(zero, &ok);
   cmp(FieldOperand(object, HeapObject::kMapOffset),
-      FACTORY->heap_number_map());
+      isolate()->factory()->heap_number_map());
   Assert(equal, "Operand not a number");
   bind(&ok);
 }
@@ -286,7 +286,7 @@
   push(Immediate(Smi::FromInt(type)));
   push(Immediate(CodeObject()));
   if (emit_debug_code()) {
-    cmp(Operand(esp, 0), Immediate(FACTORY->undefined_value()));
+    cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value()));
     Check(not_equal, "code object not properly patched");
   }
 }
@@ -577,7 +577,7 @@
     push(scratch);
     // Read the first word and compare to global_context_map.
     mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
-    cmp(scratch, FACTORY->global_context_map());
+    cmp(scratch, isolate()->factory()->global_context_map());
     Check(equal, "JSGlobalObject::global_context should be a global context.");
     pop(scratch);
   }
@@ -598,13 +598,13 @@
 
   // Check the context is a global context.
   if (emit_debug_code()) {
-    cmp(holder_reg, FACTORY->null_value());
+    cmp(holder_reg, isolate()->factory()->null_value());
     Check(not_equal, "JSGlobalProxy::context() should not be null.");
 
     push(holder_reg);
     // Read the first word and compare to global_context_map(),
     mov(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
-    cmp(holder_reg, FACTORY->global_context_map());
+    cmp(holder_reg, isolate()->factory()->global_context_map());
     Check(equal, "JSGlobalObject::global_context should be a global context.");
     pop(holder_reg);
   }
@@ -843,7 +843,7 @@
 
   // Set the map.
   mov(FieldOperand(result, HeapObject::kMapOffset),
-      Immediate(FACTORY->heap_number_map()));
+      Immediate(isolate()->factory()->heap_number_map()));
 }
 
 
@@ -873,7 +873,7 @@
 
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
-      Immediate(FACTORY->string_map()));
+      Immediate(isolate()->factory()->string_map()));
   mov(scratch1, length);
   SmiTag(scratch1);
   mov(FieldOperand(result, String::kLengthOffset), scratch1);
@@ -908,7 +908,7 @@
 
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
-      Immediate(FACTORY->ascii_string_map()));
+      Immediate(isolate()->factory()->ascii_string_map()));
   mov(scratch1, length);
   SmiTag(scratch1);
   mov(FieldOperand(result, String::kLengthOffset), scratch1);
@@ -934,7 +934,7 @@
 
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
-      Immediate(FACTORY->ascii_string_map()));
+      Immediate(isolate()->factory()->ascii_string_map()));
   mov(FieldOperand(result, String::kLengthOffset),
       Immediate(Smi::FromInt(length)));
   mov(FieldOperand(result, String::kHashFieldOffset),
@@ -956,7 +956,7 @@
 
   // Set the map. The other fields are left uninitialized.
   mov(FieldOperand(result, HeapObject::kMapOffset),
-      Immediate(FACTORY->cons_string_map()));
+      Immediate(isolate()->factory()->cons_string_map()));
 }
 
 
@@ -974,7 +974,7 @@
 
   // Set the map. The other fields are left uninitialized.
   mov(FieldOperand(result, HeapObject::kMapOffset),
-      Immediate(FACTORY->cons_ascii_string_map()));
+      Immediate(isolate()->factory()->cons_ascii_string_map()));
 }
 
 
@@ -1092,7 +1092,7 @@
   // If the prototype or initial map is the hole, don't return it and
   // simply miss the cache instead. This will allow us to allocate a
   // prototype object on-demand in the runtime system.
-  cmp(Operand(result), Immediate(FACTORY->the_hole_value()));
+  cmp(Operand(result), Immediate(isolate()->factory()->the_hole_value()));
   j(equal, miss, not_taken);
 
   // If the function does not have an initial map, we're done.
@@ -1158,7 +1158,7 @@
   if (num_arguments > 0) {
     add(Operand(esp), Immediate(num_arguments * kPointerSize));
   }
-  mov(eax, Immediate(FACTORY->undefined_value()));
+  mov(eax, Immediate(isolate()->factory()->undefined_value()));
 }
 
 
@@ -1229,7 +1229,7 @@
     IllegalOperation(num_arguments);
     // Since we did not call the stub, there was no allocation failure.
     // Return some non-failure object.
-    return HEAP->undefined_value();
+    return isolate()->heap()->undefined_value();
   }
 
   // TODO(1236192): Most runtime routines don't need the number of
@@ -1403,7 +1403,7 @@
   }
   bind(&empty_handle);
   // It was zero; the result is undefined.
-  mov(eax, FACTORY->undefined_value());
+  mov(eax, isolate()->factory()->undefined_value());
   jmp(&prologue);
 
   // HandleScope limit has changed. Delete allocated extensions.
@@ -1486,8 +1486,7 @@
 
   if (!definitely_matches) {
     Handle<Code> adaptor =
-        Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::ArgumentsAdaptorTrampoline));
+        isolate()->builtins()->ArgumentsAdaptorTrampoline();
     if (!code_constant.is_null()) {
       mov(edx, Immediate(code_constant));
       add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag));
@@ -1665,7 +1664,7 @@
   mov(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
   if (emit_debug_code()) {
     Label ok, fail;
-    CheckMap(map, FACTORY->meta_map(), &fail, false);
+    CheckMap(map, isolate()->factory()->meta_map(), &fail, false);
     jmp(&ok);
     bind(&fail);
     Abort("Global functions must have initial map");
@@ -1813,12 +1812,13 @@
 
 void MacroAssembler::AssertFastElements(Register elements) {
   if (emit_debug_code()) {
+    Factory* factory = isolate()->factory();
     Label ok;
     cmp(FieldOperand(elements, HeapObject::kMapOffset),
-        Immediate(FACTORY->fixed_array_map()));
+        Immediate(factory->fixed_array_map()));
     j(equal, &ok);
     cmp(FieldOperand(elements, HeapObject::kMapOffset),
-        Immediate(FACTORY->fixed_cow_array_map()));
+        Immediate(factory->fixed_cow_array_map()));
     j(equal, &ok);
     Abort("JSObject with fast elements map has slow elements");
     bind(&ok);
@@ -1883,7 +1883,7 @@
   if (emit_debug_code()) AbortIfSmi(reg);
   if (!info.IsNumber()) {
     cmp(FieldOperand(reg, HeapObject::kMapOffset),
-        FACTORY->heap_number_map());
+        isolate()->factory()->heap_number_map());
     j(not_equal, on_not_number);
   }
 }
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index a5243a8..bb8d2d3 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -114,8 +114,9 @@
                                              Register r0,
                                              Register r1) {
   ASSERT(name->IsSymbol());
-  __ IncrementCounter(COUNTERS->negative_lookups(), 1);
-  __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->negative_lookups(), 1);
+  __ IncrementCounter(counters->negative_lookups_miss(), 1);
 
   Label done;
   __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
@@ -198,7 +199,7 @@
   }
 
   __ bind(&done);
-  __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1);
+  __ DecrementCounter(counters->negative_lookups_miss(), 1);
 }
 
 
@@ -276,11 +277,11 @@
     MacroAssembler* masm, int index, Register prototype, Label* miss) {
   // Check we're still in the same context.
   __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
-         Isolate::Current()->global());
+         masm->isolate()->global());
   __ j(not_equal, miss);
   // Get the global function with the given index.
-  JSFunction* function = JSFunction::cast(
-      Isolate::Current()->global_context()->get(index));
+  JSFunction* function =
+      JSFunction::cast(masm->isolate()->global_context()->get(index));
   // Load its initial map. The global functions all have initial maps.
   __ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
   // Load the prototype from the initial map.
@@ -398,7 +399,7 @@
                                      JSObject* holder_obj) {
   __ push(name);
   InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
-  ASSERT(!HEAP->InNewSpace(interceptor));
+  ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor));
   Register scratch = name;
   __ mov(scratch, Immediate(Handle<Object>(interceptor)));
   __ push(scratch);
@@ -484,7 +485,7 @@
   __ mov(Operand(esp, 2 * kPointerSize), edi);
   Object* call_data = optimization.api_call_info()->data();
   Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
-  if (HEAP->InNewSpace(call_data)) {
+  if (masm->isolate()->heap()->InNewSpace(call_data)) {
     __ mov(ecx, api_call_info_handle);
     __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
     __ mov(Operand(esp, 3 * kPointerSize), ebx);
@@ -578,7 +579,7 @@
                      name,
                      holder,
                      miss);
-      return HEAP->undefined_value();  // Success.
+      return masm->isolate()->heap()->undefined_value();  // Success.
     }
   }
 
@@ -614,10 +615,11 @@
                              (depth2 != kInvalidProtoDepth);
     }
 
-    __ IncrementCounter(COUNTERS->call_const_interceptor(), 1);
+    Counters* counters = masm->isolate()->counters();
+    __ IncrementCounter(counters->call_const_interceptor(), 1);
 
     if (can_do_fast_api_call) {
-      __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1);
+      __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1);
       ReserveSpaceForFastApiCall(masm, scratch1);
     }
 
@@ -676,7 +678,7 @@
       FreeSpaceForFastApiCall(masm, scratch1);
     }
 
-    return HEAP->undefined_value();  // Success.
+    return masm->isolate()->heap()->undefined_value();  // Success.
   }
 
   void CompileRegular(MacroAssembler* masm,
@@ -746,9 +748,9 @@
   ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
   Code* code = NULL;
   if (kind == Code::LOAD_IC) {
-    code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss);
+    code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
   } else {
-    code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
+    code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
   }
 
   Handle<Code> ic(code);
@@ -913,6 +915,9 @@
   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
   ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
          && !scratch2.is(scratch1));
+
+  Heap* heap = isolate()->heap();
+
   // Keep track of the current object in register reg.
   Register reg = object_reg;
   JSObject* current = object;
@@ -937,7 +942,7 @@
         !current->IsJSGlobalObject() &&
         !current->IsJSGlobalProxy()) {
       if (!name->IsSymbol()) {
-        MaybeObject* maybe_lookup_result = HEAP->LookupSymbol(name);
+        MaybeObject* maybe_lookup_result = heap->LookupSymbol(name);
         Object* lookup_result = NULL;  // Initialization to please compiler.
         if (!maybe_lookup_result->ToObject(&lookup_result)) {
           set_failure(Failure::cast(maybe_lookup_result));
@@ -957,7 +962,7 @@
       __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
       reg = holder_reg;  // from now the object is in holder_reg
       __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-    } else if (HEAP->InNewSpace(prototype)) {
+    } else if (heap->InNewSpace(prototype)) {
       // Get the map of the current object.
       __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
       __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map())));
@@ -1087,7 +1092,7 @@
   ASSERT(!scratch2.is(reg));
   __ push(reg);  // holder
   // Push data from AccessorInfo.
-  if (HEAP->InNewSpace(callback_handle->data())) {
+  if (isolate()->heap()->InNewSpace(callback_handle->data())) {
     __ mov(scratch1, Immediate(callback_handle));
     __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));
   } else {
@@ -1283,7 +1288,7 @@
 
     ExternalReference ref =
         ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
-                          masm()->isolate());
+                          isolate());
     __ TailCallExternalReference(ref, 5, 1);
   }
 }
@@ -1334,7 +1339,7 @@
   }
 
   // Check that the cell contains the same function.
-  if (HEAP->InNewSpace(function)) {
+  if (isolate()->heap()->InNewSpace(function)) {
     // We can't embed a pointer to a function in new space so we have
     // to verify that the shared function info is unchanged. This has
     // the nice side effect that multiple closures based on the same
@@ -1358,8 +1363,8 @@
 
 MaybeObject* CallStubCompiler::GenerateMissBranch() {
   MaybeObject* maybe_obj =
-      Isolate::Current()->stub_cache()->ComputeCallMiss(
-          arguments().immediate(), kind_);
+      isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
+                                                       kind_);
   Object* obj;
   if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
@@ -1437,7 +1442,9 @@
   // -----------------------------------
 
   // If object is not an array, bail out to regular call.
-  if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value();
+  if (!object->IsJSArray() || cell != NULL) {
+    return isolate()->heap()->undefined_value();
+  }
 
   Label miss;
 
@@ -1515,11 +1522,10 @@
         __ jmp(&call_builtin);
       }
 
-      Isolate* isolate = masm()->isolate();
       ExternalReference new_space_allocation_top =
-          ExternalReference::new_space_allocation_top_address(isolate);
+          ExternalReference::new_space_allocation_top_address(isolate());
       ExternalReference new_space_allocation_limit =
-          ExternalReference::new_space_allocation_limit_address(isolate);
+          ExternalReference::new_space_allocation_limit_address(isolate());
 
       const int kAllocationDelta = 4;
       // Load top.
@@ -1561,7 +1567,7 @@
 
     __ bind(&call_builtin);
     __ TailCallExternalReference(
-        ExternalReference(Builtins::c_ArrayPush, masm()->isolate()),
+        ExternalReference(Builtins::c_ArrayPush, isolate()),
         argc + 1,
         1);
   }
@@ -1589,7 +1595,9 @@
   // -----------------------------------
 
   // If object is not an array, bail out to regular call.
-  if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value();
+  if (!object->IsJSArray() || cell != NULL) {
+    return isolate()->heap()->undefined_value();
+  }
 
   Label miss, return_undefined, call_builtin;
 
@@ -1644,7 +1652,7 @@
 
   __ bind(&call_builtin);
   __ TailCallExternalReference(
-      ExternalReference(Builtins::c_ArrayPop, masm()->isolate()),
+      ExternalReference(Builtins::c_ArrayPop, isolate()),
       argc + 1,
       1);
 
@@ -1673,7 +1681,7 @@
 
   // If object is not a string, bail out to regular call.
   if (!object->IsString() || cell != NULL) {
-    return masm()->isolate()->heap()->undefined_value();
+    return isolate()->heap()->undefined_value();
   }
 
   const int argc = arguments().immediate();
@@ -1756,7 +1764,9 @@
   // -----------------------------------
 
   // If object is not a string, bail out to regular call.
-  if (!object->IsString() || cell != NULL) return HEAP->undefined_value();
+  if (!object->IsString() || cell != NULL) {
+    return isolate()->heap()->undefined_value();
+  }
 
   const int argc = arguments().immediate();
 
@@ -1843,7 +1853,9 @@
 
   // If the object is not a JSObject or we got an unexpected number of
   // arguments, bail out to the regular call.
-  if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
+  if (!object->IsJSObject() || argc != 1) {
+    return isolate()->heap()->undefined_value();
+  }
 
   Label miss;
   GenerateNameCheck(name, &miss);
@@ -1911,15 +1923,19 @@
   //  -- esp[(argc + 1) * 4] : receiver
   // -----------------------------------
 
-  if (!Isolate::Current()->cpu_features()->IsSupported(SSE2))
-    return HEAP->undefined_value();
+  if (isolate()->cpu_features()->IsSupported(SSE2)) {
+    return isolate()->heap()->undefined_value();
+  }
+
   CpuFeatures::Scope use_sse2(SSE2);
 
   const int argc = arguments().immediate();
 
   // If the object is not a JSObject or we got an unexpected number of
   // arguments, bail out to the regular call.
-  if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
+  if (!object->IsJSObject() || argc != 1) {
+    return isolate()->heap()->undefined_value();
+  }
 
   Label miss;
   GenerateNameCheck(name, &miss);
@@ -2041,7 +2057,9 @@
 
   // If the object is not a JSObject or we got an unexpected number of
   // arguments, bail out to the regular call.
-  if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value();
+  if (!object->IsJSObject() || argc != 1) {
+    return isolate()->heap()->undefined_value();
+  }
 
   Label miss;
   GenerateNameCheck(name, &miss);
@@ -2137,11 +2155,12 @@
   ASSERT(optimization.is_simple_api_call());
   // Bail out if object is a global object as we don't want to
   // repatch it to global receiver.
-  if (object->IsGlobalObject()) return HEAP->undefined_value();
-  if (cell != NULL) return HEAP->undefined_value();
+  Heap* heap = isolate()->heap();
+  if (object->IsGlobalObject()) return heap->undefined_value();
+  if (cell != NULL) return heap->undefined_value();
   int depth = optimization.GetPrototypeDepthOfExpectedType(
             JSObject::cast(object), holder);
-  if (depth == kInvalidProtoDepth) return HEAP->undefined_value();
+  if (depth == kInvalidProtoDepth) return heap->undefined_value();
 
   Label miss, miss_before_stack_reserved;
 
@@ -2155,8 +2174,9 @@
   __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &miss_before_stack_reserved, not_taken);
 
-  __ IncrementCounter(COUNTERS->call_const(), 1);
-  __ IncrementCounter(COUNTERS->call_const_fast_api(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->call_const(), 1);
+  __ IncrementCounter(counters->call_const_fast_api(), 1);
 
   // Allocate space for v8::Arguments implicit values. Must be initialized
   // before calling any runtime function.
@@ -2230,7 +2250,7 @@
   SharedFunctionInfo* function_info = function->shared();
   switch (check) {
     case RECEIVER_MAP_CHECK:
-      __ IncrementCounter(COUNTERS->call_const(), 1);
+      __ IncrementCounter(isolate()->counters()->call_const(), 1);
 
       // Check that the maps haven't changed.
       CheckPrototypes(JSObject::cast(object), edx, holder,
@@ -2430,7 +2450,8 @@
   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
 
   // Jump to the cached code (tail call).
-  __ IncrementCounter(COUNTERS->call_global_inline(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->call_global_inline(), 1);
   ASSERT(function->is_compiled());
   ParameterCount expected(function->shared()->formal_parameter_count());
   if (V8::UseCrankshaft()) {
@@ -2447,7 +2468,7 @@
 
   // Handle call cache miss.
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1);
+  __ IncrementCounter(counters->call_global_inline_miss(), 1);
   MaybeObject* maybe_result = GenerateMissBranch();
   if (maybe_result->IsFailure()) return maybe_result;
 
@@ -2479,8 +2500,7 @@
   // Handle store cache miss.
   __ bind(&miss);
   __ mov(ecx, Immediate(Handle<String>(name)));  // restore name
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2525,14 +2545,13 @@
   __ push(ebx);  // restore return address
 
   // Do tail-call to the runtime system.
-  Isolate* isolate = masm()->isolate();
   ExternalReference store_callback_property =
-      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate);
+      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
   __ TailCallExternalReference(store_callback_property, 4, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss));
+  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2576,14 +2595,13 @@
   __ push(ebx);  // restore return address
 
   // Do tail-call to the runtime system.
-  Isolate* isolate = masm()->isolate();
   ExternalReference store_ic_property =
-      ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate);
+      ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
   __ TailCallExternalReference(store_ic_property, 4, 1);
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(isolate->builtins()->builtin(Builtins::StoreIC_Miss));
+  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2626,14 +2644,14 @@
   __ mov(cell_operand, eax);
 
   // Return the value (register eax).
-  __ IncrementCounter(COUNTERS->named_store_global_inline(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->named_store_global_inline(), 1);
   __ ret(0);
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
+  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2653,7 +2671,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_store_field(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_store_field(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(ecx), Immediate(Handle<String>(name)));
@@ -2669,9 +2688,8 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_store_field(), 1);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedStoreIC_Miss));
+  __ DecrementCounter(counters->keyed_store_field(), 1);
+  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2728,8 +2746,7 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(
-      Isolate::Current()->builtins()->builtin(Builtins::KeyedStoreIC_Miss));
+  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2774,14 +2791,14 @@
 
   // Return undefined if maps of the full prototype chain are still the
   // same and no global property with this name contains a value.
-  __ mov(eax, FACTORY->undefined_value());
+  __ mov(eax, isolate()->factory()->undefined_value());
   __ ret(0);
 
   __ bind(&miss);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
 
   // Return the generated code.
-  return GetCode(NONEXISTENT, HEAP->empty_string());
+  return GetCode(NONEXISTENT, isolate()->heap()->empty_string());
 }
 
 
@@ -2925,12 +2942,13 @@
     __ Check(not_equal, "DontDelete cells can't contain the hole");
   }
 
-  __ IncrementCounter(COUNTERS->named_load_global_stub(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->named_load_global_stub(), 1);
   __ mov(eax, ebx);
   __ ret(0);
 
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1);
+  __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
 
   // Return the generated code.
@@ -2949,7 +2967,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_field(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_field(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -2958,7 +2977,7 @@
   GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
 
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_field(), 1);
+  __ DecrementCounter(counters->keyed_load_field(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -2978,7 +2997,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_callback(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_callback(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -2993,7 +3013,7 @@
 
   __ bind(&miss);
 
-  __ DecrementCounter(COUNTERS->keyed_load_callback(), 1);
+  __ DecrementCounter(counters->keyed_load_callback(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -3012,7 +3032,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_constant_function(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3021,7 +3042,7 @@
   GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi,
                        value, name, &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+  __ DecrementCounter(counters->keyed_load_constant_function(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -3039,7 +3060,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_interceptor(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3058,7 +3080,7 @@
                           name,
                           &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+  __ DecrementCounter(counters->keyed_load_interceptor(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -3074,7 +3096,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_array_length(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3082,7 +3105,7 @@
 
   GenerateLoadArrayLength(masm(), edx, ecx, &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1);
+  __ DecrementCounter(counters->keyed_load_array_length(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -3098,7 +3121,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_string_length(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3106,7 +3130,7 @@
 
   GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1);
+  __ DecrementCounter(counters->keyed_load_string_length(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -3122,7 +3146,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
 
   // Check that the name has not changed.
   __ cmp(Operand(eax), Immediate(Handle<String>(name)));
@@ -3130,7 +3155,7 @@
 
   GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+  __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -3270,7 +3295,7 @@
       int arg_number = shared->GetThisPropertyAssignmentArgument(i);
       __ mov(ebx, edi);
       __ cmp(eax, arg_number);
-      if (Isolate::Current()->cpu_features()->IsSupported(CMOV)) {
+      if (isolate()->cpu_features()->IsSupported(CMOV)) {
         CpuFeatures::Scope use_cmov(CMOV);
         __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
       } else {
@@ -3305,16 +3330,16 @@
   __ pop(ecx);
   __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
   __ push(ecx);
-  __ IncrementCounter(COUNTERS->constructed_objects(), 1);
-  __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->constructed_objects(), 1);
+  __ IncrementCounter(counters->constructed_objects_stub(), 1);
   __ ret(0);
 
   // Jump to the generic stub in case the specialized code cannot handle the
   // construction.
   __ bind(&generic_stub_call);
-  Code* code = Isolate::Current()->builtins()->builtin(
-      Builtins::JSConstructStubGeneric);
-  Handle<Code> generic_construct_stub(code);
+  Handle<Code> generic_construct_stub =
+      isolate()->builtins()->JSConstructStubGeneric();
   __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -3454,7 +3479,8 @@
 
   // Slow case: Jump to runtime.
   __ bind(&slow);
-  __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
   // ----------- S t a t e -------------
   //  -- eax    : key
   //  -- edx    : receiver
@@ -3588,10 +3614,10 @@
       // processors that don't support SSE2. The code in IntegerConvert
       // (code-stubs-ia32.cc) is roughly what is needed here though the
       // conversion failure case does not need to be handled.
-      if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) {
+      if (isolate()->cpu_features()->IsSupported(SSE2)) {
         if (array_type != kExternalIntArray &&
             array_type != kExternalUnsignedIntArray) {
-          ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
+          ASSERT(isolate()->cpu_features()->IsSupported(SSE2));
           CpuFeatures::Scope scope(SSE2);
           __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
           // ecx: untagged integer value
@@ -3619,7 +3645,7 @@
               break;
           }
         } else {
-          if (Isolate::Current()->cpu_features()->IsSupported(SSE3)) {
+          if (isolate()->cpu_features()->IsSupported(SSE3)) {
             CpuFeatures::Scope scope(SSE3);
             // fisttp stores values as signed integers. To represent the
             // entire range of int and unsigned int arrays, store as a
@@ -3632,7 +3658,7 @@
             __ pop(ecx);
             __ add(Operand(esp), Immediate(kPointerSize));
           } else {
-            ASSERT(Isolate::Current()->cpu_features()->IsSupported(SSE2));
+            ASSERT(isolate()->cpu_features()->IsSupported(SSE2));
             CpuFeatures::Scope scope(SSE2);
             // We can easily implement the correct rounding behavior for the
             // range [0, 2^31-1]. For the time being, to keep this code simple,
diff --git a/src/ia32/virtual-frame-ia32.cc b/src/ia32/virtual-frame-ia32.cc
index 317028d..2613caf 100644
--- a/src/ia32/virtual-frame-ia32.cc
+++ b/src/ia32/virtual-frame-ia32.cc
@@ -1017,7 +1017,7 @@
   MoveResultsToRegisters(&name, &receiver, ecx, eax);
 
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+      Builtins::kLoadIC_Initialize));
   return RawCallCodeObject(ic, mode);
 }
 
@@ -1030,7 +1030,7 @@
   MoveResultsToRegisters(&key, &receiver, eax, edx);
 
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+      Builtins::kKeyedLoadIC_Initialize));
   return RawCallCodeObject(ic, mode);
 }
 
@@ -1041,8 +1041,8 @@
   // Value and (if not contextual) receiver are on top of the frame.
   // The IC expects name in ecx, value in eax, and receiver in edx.
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      (strict_mode == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
-                                   : Builtins::StoreIC_Initialize));
+      (strict_mode == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+                                   : Builtins::kStoreIC_Initialize));
 
   Result value = Pop();
   RelocInfo::Mode mode;
@@ -1108,8 +1108,8 @@
   }
 
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      (strict_mode == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
-                                   : Builtins::KeyedStoreIC_Initialize));
+      (strict_mode == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+                                   : Builtins::kKeyedStoreIC_Initialize));
   return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
 }
 
@@ -1158,7 +1158,7 @@
   // IC expects arg count in eax, function in edi, and the arguments
   // and receiver on the stack.
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::JSConstructCall));
+      Builtins::kJSConstructCall));
   // Duplicate the function before preparing the frame.
   PushElementAt(arg_count);
   Result function = Pop();
diff --git a/src/ic.cc b/src/ic.cc
index 7e87b1b..01d4ca0 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -878,14 +878,14 @@
           const int offset = String::kLengthOffset;
           PatchInlinedLoad(address(), map, offset);
           set_target(isolate()->builtins()->builtin(
-              Builtins::LoadIC_StringLength));
+              Builtins::kLoadIC_StringLength));
         } else {
           set_target(isolate()->builtins()->builtin(
-              Builtins::LoadIC_StringWrapperLength));
+              Builtins::kLoadIC_StringWrapperLength));
         }
       } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
         set_target(isolate()->builtins()->builtin(
-            Builtins::LoadIC_StringWrapperLength));
+            Builtins::kLoadIC_StringWrapperLength));
       } else {
         set_target(non_monomorphic_stub);
       }
@@ -908,7 +908,7 @@
         const int offset = JSArray::kLengthOffset;
         PatchInlinedLoad(address(), map, offset);
         set_target(isolate()->builtins()->builtin(
-            Builtins::LoadIC_ArrayLength));
+            Builtins::kLoadIC_ArrayLength));
       } else {
         set_target(non_monomorphic_stub);
       }
@@ -924,7 +924,7 @@
 #endif
       if (state == PREMONOMORPHIC) {
         set_target(isolate()->builtins()->builtin(
-            Builtins::LoadIC_FunctionPrototype));
+            Builtins::kLoadIC_FunctionPrototype));
       } else {
         set_target(non_monomorphic_stub);
       }
@@ -1451,8 +1451,8 @@
     if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
 #endif
     Builtins::Name target = (strict_mode == kStrictMode)
-        ? Builtins::StoreIC_ArrayLength_Strict
-        : Builtins::StoreIC_ArrayLength;
+        ? Builtins::kStoreIC_ArrayLength_Strict
+        : Builtins::kStoreIC_ArrayLength;
     set_target(isolate()->builtins()->builtin(target));
     return receiver->SetProperty(*name, *value, NONE, strict_mode);
   }
diff --git a/src/ic.h b/src/ic.h
index 91a626f..f226660 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -316,15 +316,15 @@
   // Stub accessors.
   Code* megamorphic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::LoadIC_Megamorphic);
+        Builtins::kLoadIC_Megamorphic);
   }
   static Code* initialize_stub() {
     return Isolate::Current()->builtins()->builtin(
-        Builtins::LoadIC_Initialize);
+        Builtins::kLoadIC_Initialize);
   }
   Code* pre_monomorphic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::LoadIC_PreMonomorphic);
+        Builtins::kLoadIC_PreMonomorphic);
   }
 
   static void Clear(Address address, Code* target);
@@ -382,28 +382,28 @@
   // Stub accessors.
   static Code* initialize_stub() {
     return Isolate::Current()->builtins()->builtin(
-        Builtins::KeyedLoadIC_Initialize);
+        Builtins::kKeyedLoadIC_Initialize);
   }
   Code* megamorphic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_Generic);
+        Builtins::kKeyedLoadIC_Generic);
   }
   Code* generic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_Generic);
+        Builtins::kKeyedLoadIC_Generic);
   }
   Code* pre_monomorphic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_PreMonomorphic);
+        Builtins::kKeyedLoadIC_PreMonomorphic);
   }
   Code* string_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_String);
+        Builtins::kKeyedLoadIC_String);
   }
 
   Code* indexed_interceptor_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_IndexedInterceptor);
+        Builtins::kKeyedLoadIC_IndexedInterceptor);
   }
 
   static void Clear(Address address, Code* target);
@@ -465,27 +465,27 @@
   // Stub accessors.
   Code* megamorphic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::StoreIC_Megamorphic);
+        Builtins::kStoreIC_Megamorphic);
   }
   Code* megamorphic_stub_strict() {
     return isolate()->builtins()->builtin(
-        Builtins::StoreIC_Megamorphic_Strict);
+        Builtins::kStoreIC_Megamorphic_Strict);
   }
   static Code* initialize_stub() {
     return Isolate::Current()->builtins()->builtin(
-        Builtins::StoreIC_Initialize);
+        Builtins::kStoreIC_Initialize);
   }
   static Code* initialize_stub_strict() {
     return Isolate::Current()->builtins()->builtin(
-        Builtins::StoreIC_Initialize_Strict);
+        Builtins::kStoreIC_Initialize_Strict);
   }
   Code* global_proxy_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::StoreIC_GlobalProxy);
+        Builtins::kStoreIC_GlobalProxy);
   }
   Code* global_proxy_stub_strict() {
     return isolate()->builtins()->builtin(
-        Builtins::StoreIC_GlobalProxy_Strict);
+        Builtins::kStoreIC_GlobalProxy_Strict);
   }
 
   static void Clear(Address address, Code* target);
@@ -540,27 +540,27 @@
   // Stub accessors.
   static Code* initialize_stub() {
     return Isolate::Current()->builtins()->builtin(
-        Builtins::KeyedStoreIC_Initialize);
+        Builtins::kKeyedStoreIC_Initialize);
   }
   Code* megamorphic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedStoreIC_Generic);
+        Builtins::kKeyedStoreIC_Generic);
   }
   static Code* initialize_stub_strict() {
     return Isolate::Current()->builtins()->builtin(
-        Builtins::KeyedStoreIC_Initialize_Strict);
+        Builtins::kKeyedStoreIC_Initialize_Strict);
   }
   Code* megamorphic_stub_strict() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedStoreIC_Generic_Strict);
+        Builtins::kKeyedStoreIC_Generic_Strict);
   }
   Code* generic_stub() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedStoreIC_Generic);
+        Builtins::kKeyedStoreIC_Generic);
   }
   Code* generic_stub_strict() {
     return isolate()->builtins()->builtin(
-        Builtins::KeyedStoreIC_Generic_Strict);
+        Builtins::kKeyedStoreIC_Generic_Strict);
   }
 
   static void Clear(Address address, Code* target);
diff --git a/src/isolate.h b/src/isolate.h
index 13ffc13..90fce61 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -402,7 +402,8 @@
 
   // Returns the isolate inside which the current thread is running.
   INLINE(static Isolate* Current()) {
-    Isolate* isolate = UncheckedCurrent();
+    Isolate* isolate = reinterpret_cast<Isolate*>(
+        Thread::GetExistingThreadLocal(isolate_key_));
     ASSERT(isolate != NULL);
     return isolate;
   }
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 2db8ddf..d5f59ea 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -501,7 +501,8 @@
   }
   Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate);
 
-  if (IrregexpInterpreter::Match(byte_codes,
+  if (IrregexpInterpreter::Match(isolate,
+                                 byte_codes,
                                  subject,
                                  register_vector,
                                  index)) {
diff --git a/src/jump-target-heavy.cc b/src/jump-target-heavy.cc
index 28e22c0..f73e027 100644
--- a/src/jump-target-heavy.cc
+++ b/src/jump-target-heavy.cc
@@ -140,7 +140,7 @@
   // the directionality of the block.  Compute: an entry frame for the
   // block.
 
-  COUNTERS->compute_entry_frame()->Increment();
+  Isolate::Current()->counters()->compute_entry_frame()->Increment();
 #ifdef DEBUG
   if (Isolate::Current()->jump_target_compiling_deferred_code()) {
     ASSERT(reaching_frames_.length() > 1);
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 555e082..dbcf5ef 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -1033,7 +1033,7 @@
 
   shared_info->set_construct_stub(
       Isolate::Current()->builtins()->builtin(
-          Builtins::JSConstructStubGeneric));
+          Builtins::kJSConstructStubGeneric));
 
   DeoptimizeDependentFunctions(*shared_info);
   Isolate::Current()->compilation_cache()->Remove(shared_info);
@@ -1404,7 +1404,7 @@
     *mode = Debug::FRAME_DROPPED_IN_DEBUG_SLOT_CALL;
   } else if (pre_top_frame_code ==
       Isolate::Current()->builtins()->builtin(
-          Builtins::FrameDropper_LiveEdit)) {
+          Builtins::kFrameDropper_LiveEdit)) {
     // OK, we can drop our own code.
     *mode = Debug::FRAME_DROPPED_IN_DIRECT_CALL;
   } else if (pre_top_frame_code->kind() == Code::STUB &&
@@ -1430,8 +1430,7 @@
   // Make sure FixTryCatchHandler is idempotent.
   ASSERT(!FixTryCatchHandler(pre_top_frame, bottom_js_frame));
 
-  Handle<Code> code(Isolate::Current()->builtins()->builtin(
-      Builtins::FrameDropper_LiveEdit));
+  Handle<Code> code = Isolate::Current()->builtins()->FrameDropper_LiveEdit();
   top_frame->set_pc(code->entry());
   pre_top_frame->SetCallerFp(bottom_js_frame->fp());
 
diff --git a/src/log.cc b/src/log.cc
index 310e197..dc7906c 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -52,24 +52,25 @@
 //
 class SlidingStateWindow {
  public:
-  SlidingStateWindow();
+  explicit SlidingStateWindow(Isolate* isolate);
   ~SlidingStateWindow();
   void AddState(StateTag state);
 
  private:
   static const int kBufferSize = 256;
+  Counters* counters_;
   int current_index_;
   bool is_full_;
   byte buffer_[kBufferSize];
 
 
   void IncrementStateCounter(StateTag state) {
-    COUNTERS->state_counters(state)->Increment();
+    counters_->state_counters(state)->Increment();
   }
 
 
   void DecrementStateCounter(StateTag state) {
-    COUNTERS->state_counters(state)->Decrement();
+    counters_->state_counters(state)->Decrement();
   }
 };
 
@@ -238,11 +239,12 @@
 //
 // SlidingStateWindow implementation.
 //
-SlidingStateWindow::SlidingStateWindow(): current_index_(0), is_full_(false) {
+SlidingStateWindow::SlidingStateWindow(Isolate* isolate)
+    : counters_(isolate->counters()), current_index_(0), is_full_(false) {
   for (int i = 0; i < kBufferSize; i++) {
     buffer_[i] = static_cast<byte>(OTHER);
   }
-  LOGGER->ticker_->SetWindow(this);
+  isolate->logger()->ticker_->SetWindow(this);
 }
 
 
@@ -617,7 +619,7 @@
       class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   SmartPointer<char> property_name =
       String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-  LOGGER->ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
+  ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
 #endif
 }
 
@@ -629,7 +631,7 @@
   String* class_name_obj = holder->class_name();
   SmartPointer<char> class_name =
       class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-  LOGGER->ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
+  ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
 #endif
 }
 
@@ -639,7 +641,7 @@
   String* class_name_obj = object->class_name();
   SmartPointer<char> class_name =
       class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-  LOGGER->ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
+  ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
 #endif
 }
 
@@ -647,7 +649,7 @@
 void Logger::ApiEntryCall(const char* name) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_api) return;
-  LOGGER->ApiEvent("api,%s\n", name);
+  ApiEvent("api,%s\n", name);
 #endif
 }
 
@@ -787,7 +789,7 @@
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (!log_->IsEnabled() || !FLAG_log_code) return;
   if (code == Isolate::Current()->builtins()->builtin(
-      Builtins::LazyCompile))
+      Builtins::kLazyCompile))
     return;
 
   LogMessageBuilder msg(this);
@@ -1416,7 +1418,7 @@
   // GetScriptLineNumber call.
   for (int i = 0; i < compiled_funcs_count; ++i) {
     if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
-        Builtins::LazyCompile))
+        Builtins::kLazyCompile))
       continue;
     Handle<SharedFunctionInfo> shared = sfis[i];
     Handle<String> func_name(shared->DebugName());
@@ -1515,8 +1517,9 @@
 
   ticker_ = new Ticker(Isolate::Current(), kSamplingIntervalMs);
 
+  Isolate* isolate = Isolate::Current();
   if (FLAG_sliding_state_window && sliding_state_window_ == NULL) {
-    sliding_state_window_ = new SlidingStateWindow();
+    sliding_state_window_ = new SlidingStateWindow(isolate);
   }
 
   bool start_logging = FLAG_log || FLAG_log_runtime || FLAG_log_api
@@ -1528,7 +1531,7 @@
   }
 
   if (FLAG_prof) {
-    profiler_ = new Profiler(Isolate::Current());
+    profiler_ = new Profiler(isolate);
     if (!FLAG_prof_auto) {
       profiler_->pause();
     } else {
@@ -1603,7 +1606,7 @@
   // Otherwise, if the sliding state window computation has not been
   // started we do it now.
   if (sliding_state_window_ == NULL) {
-    sliding_state_window_ = new SlidingStateWindow();
+    sliding_state_window_ = new SlidingStateWindow(Isolate::Current());
   }
 #endif
 }
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 08cf7d7..1f73388 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -247,7 +247,7 @@
 
  private:
   void ProcessJSFunctionCandidates() {
-    Code* lazy_compile = isolate_->builtins()->builtin(Builtins::LazyCompile);
+    Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
 
     JSFunction* candidate = jsfunction_candidates_head_;
     JSFunction* next_candidate;
@@ -272,7 +272,7 @@
 
 
   void ProcessSharedFunctionInfoCandidates() {
-    Code* lazy_compile = isolate_->builtins()->builtin(Builtins::LazyCompile);
+    Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
 
     SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
     SharedFunctionInfo* next_candidate;
@@ -570,12 +570,12 @@
 
   inline static bool IsCompiled(JSFunction* function) {
     return function->unchecked_code() !=
-        Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
+        Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
   }
 
   inline static bool IsCompiled(SharedFunctionInfo* function) {
     return function->unchecked_code() !=
-        Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
+        Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
   }
 
   inline static bool IsFlushable(JSFunction* function) {
@@ -1101,11 +1101,11 @@
   ASSERT(contents->IsFixedArray());
   ASSERT(contents->length() >= 2);
   SetMark(contents);
-  // Contents contains (value, details) pairs.  If the details say that
-  // the type of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION, or
-  // NULL_DESCRIPTOR, we don't mark the value as live.  Only for
-  // MAP_TRANSITION and CONSTANT_TRANSITION is the value an Object* (a
-  // Map*).
+  // Contents contains (value, details) pairs.  If the details say that the type
+  // of descriptor is MAP_TRANSITION, CONSTANT_TRANSITION,
+  // EXTERNAL_ARRAY_TRANSITION or NULL_DESCRIPTOR, we don't mark the value as
+  // live.  Only for MAP_TRANSITION, EXTERNAL_ARRAY_TRANSITION and
+  // CONSTANT_TRANSITION is the value an Object* (a Map*).
   for (int i = 0; i < contents->length(); i += 2) {
     // If the pair (value, details) at index i, i+1 is not
     // a transition or null descriptor, mark the value.
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 416f887..99e9819 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -170,14 +170,15 @@
 
 // A copy of the PropertyType enum from global.h
 PropertyType = {};
-PropertyType.Normal             = 0;
-PropertyType.Field              = 1;
-PropertyType.ConstantFunction   = 2;
-PropertyType.Callbacks          = 3;
-PropertyType.Interceptor        = 4;
-PropertyType.MapTransition      = 5;
-PropertyType.ConstantTransition = 6;
-PropertyType.NullDescriptor     = 7;
+PropertyType.Normal                  = 0;
+PropertyType.Field                   = 1;
+PropertyType.ConstantFunction        = 2;
+PropertyType.Callbacks               = 3;
+PropertyType.Interceptor             = 4;
+PropertyType.MapTransition           = 5;
+PropertyType.ExternalArrayTransition = 6;
+PropertyType.ConstantTransition      = 7;
+PropertyType.NullDescriptor          = 8;
 
 
 // Different attributes for a property.
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 922c054..36e5c6f 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1722,7 +1722,8 @@
 
 bool DescriptorArray::IsTransition(int descriptor_number) {
   PropertyType t = GetType(descriptor_number);
-  return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
+  return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
+      t == EXTERNAL_ARRAY_TRANSITION;
 }
 
 
@@ -2871,21 +2872,6 @@
 }
 
 
-MaybeObject* Map::NewExternalArrayElementsMap() {
-  // TODO(danno): Special case empty object map (or most common case)
-  // to return a pre-canned pixel array map.
-  Object* obj;
-  { MaybeObject* maybe_obj = CopyDropTransitions();
-    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-  }
-  Map* new_map = Map::cast(obj);
-  new_map->set_has_fast_elements(false);
-  new_map->set_has_external_array_elements(true);
-  isolate()->counters()->map_to_external_array_elements()->Increment();
-  return new_map;
-}
-
-
 ACCESSORS(Map, instance_descriptors, DescriptorArray,
           kInstanceDescriptorsOffset)
 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
@@ -3220,7 +3206,7 @@
 
 bool SharedFunctionInfo::is_compiled() {
   return code() !=
-      Isolate::Current()->builtins()->builtin(Builtins::LazyCompile);
+      Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
 }
 
 
@@ -3280,7 +3266,7 @@
 
 
 bool JSFunction::IsMarkedForLazyRecompilation() {
-  return code() == GetIsolate()->builtins()->builtin(Builtins::LazyRecompile);
+  return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
 }
 
 
@@ -3394,7 +3380,7 @@
 
 
 bool JSFunction::is_compiled() {
-  return code() != GetIsolate()->builtins()->builtin(Builtins::LazyCompile);
+  return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
 }
 
 
diff --git a/src/objects.cc b/src/objects.cc
index a2b35ef..a0d1536 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1282,12 +1282,21 @@
     }
   }
 
-  // Only allow map transition if the object's map is NOT equal to the
-  // global object_function's map and there is not a transition for name.
+  // Only allow map transition if the object isn't the global object and there
+  // is not a transition for the name, or there's a transition for the name but
+  // it's unrelated to properties.
+  int descriptor_index = old_descriptors->Search(name);
+
+  // External array transitions are stored in the descriptor for property "",
+  // which is not a identifier and should have forced a switch to slow
+  // properties above.
+  ASSERT(descriptor_index == DescriptorArray::kNotFound ||
+      old_descriptors->GetType(descriptor_index) != EXTERNAL_ARRAY_TRANSITION);
+  bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound ||
+      old_descriptors->GetType(descriptor_index) == EXTERNAL_ARRAY_TRANSITION;
   bool allow_map_transition =
-        !old_descriptors->Contains(name) &&
-        (isolate->context()->global_context()->object_function()->
-            map() != map());
+      can_insert_transition &&
+      (isolate->context()->global_context()->object_function()->map() != map());
 
   ASSERT(index < map()->inobject_properties() ||
          (index - map()->inobject_properties()) < properties()->length() ||
@@ -1438,13 +1447,19 @@
 
 MaybeObject* JSObject::AddProperty(String* name,
                                    Object* value,
-                                   PropertyAttributes attributes) {
+                                   PropertyAttributes attributes,
+                                   StrictModeFlag strict_mode) {
   ASSERT(!IsJSGlobalProxy());
   Heap* heap = GetHeap();
   if (!map()->is_extensible()) {
-    Handle<Object> args[1] = {Handle<String>(name)};
-    return heap->isolate()->Throw(
-        *FACTORY->NewTypeError("object_not_extensible", HandleVector(args, 1)));
+    if (strict_mode == kNonStrictMode) {
+      return heap->undefined_value();
+    } else {
+      Handle<Object> args[1] = {Handle<String>(name)};
+      return heap->isolate()->Throw(
+          *FACTORY->NewTypeError("object_not_extensible",
+                                 HandleVector(args, 1)));
+    }
   }
   if (HasFastProperties()) {
     // Ensure the descriptor array does not get too big.
@@ -1485,7 +1500,7 @@
     return SetProperty(&result, name, value, attributes, strict_mode);
   }
   // Add a new real property.
-  return AddProperty(name, value, attributes);
+  return AddProperty(name, value, attributes, strict_mode);
 }
 
 
@@ -1819,6 +1834,77 @@
 }
 
 
+MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type,
+                                              bool safe_to_add_transition) {
+  DescriptorArray* descriptors = instance_descriptors();
+  String* external_array_sentinel_name = GetIsolate()->heap()->empty_symbol();
+
+  if (safe_to_add_transition) {
+    // It's only safe to manipulate the descriptor array if it would be
+    // safe to add a transition.
+
+    ASSERT(!is_shared());  // no transitions can be added to shared maps.
+    // Check if the external array transition already exists.
+    DescriptorLookupCache* cache = heap()->isolate()->descriptor_lookup_cache();
+    int index = cache->Lookup(descriptors, external_array_sentinel_name);
+    if (index == DescriptorLookupCache::kAbsent) {
+      index = descriptors->Search(external_array_sentinel_name);
+      cache->Update(descriptors,
+                    external_array_sentinel_name,
+                    index);
+    }
+
+    // If the transition already exists, check the type. If there is a match,
+    // return it.
+    if (index != DescriptorArray::kNotFound) {
+      PropertyDetails details(PropertyDetails(descriptors->GetDetails(index)));
+      if (details.type() == EXTERNAL_ARRAY_TRANSITION &&
+          details.array_type() == array_type) {
+        return descriptors->GetValue(index);
+      } else {
+        safe_to_add_transition = false;
+      }
+    }
+  }
+
+  // No transition to an existing external array map. Make a new one.
+  Object* obj;
+  { MaybeObject* maybe_map = CopyDropTransitions();
+    if (!maybe_map->ToObject(&obj)) return maybe_map;
+  }
+  Map* new_map = Map::cast(obj);
+
+  new_map->set_has_fast_elements(false);
+  new_map->set_has_external_array_elements(true);
+  GetIsolate()->counters()->map_to_external_array_elements()->Increment();
+
+  // Only remember the map transition if the object's map is NOT equal to the
+  // global object_function's map and there is not an already existing
+  // non-matching external array transition.
+  bool allow_map_transition =
+      safe_to_add_transition &&
+      (GetIsolate()->context()->global_context()->object_function()->map() !=
+       map());
+  if (allow_map_transition) {
+    // Allocate new instance descriptors for the old map with map transition.
+    ExternalArrayTransitionDescriptor desc(external_array_sentinel_name,
+                                           Map::cast(new_map),
+                                           array_type);
+    Object* new_descriptors;
+    MaybeObject* maybe_new_descriptors = descriptors->CopyInsert(
+        &desc,
+        KEEP_TRANSITIONS);
+    if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
+      return maybe_new_descriptors;
+    }
+    descriptors = DescriptorArray::cast(new_descriptors);
+    set_instance_descriptors(descriptors);
+  }
+
+  return new_map;
+}
+
+
 void JSObject::LocalLookupRealNamedProperty(String* name,
                                             LookupResult* result) {
   if (IsJSGlobalProxy()) {
@@ -1989,7 +2075,7 @@
   }
   if (!result->IsFound()) {
     // Neither properties nor transitions found.
-    return AddProperty(name, value, attributes);
+    return AddProperty(name, value, attributes, strict_mode);
   }
   if (result->IsReadOnly() && result->IsProperty()) {
     if (strict_mode == kStrictMode) {
@@ -2051,6 +2137,7 @@
       return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
     }
     case NULL_DESCRIPTOR:
+    case EXTERNAL_ARRAY_TRANSITION:
       return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
     default:
       UNREACHABLE();
@@ -2096,7 +2183,7 @@
   // Check for accessor in prototype chain removed here in clone.
   if (!result.IsFound()) {
     // Neither properties nor transitions found.
-    return AddProperty(name, value, attributes);
+    return AddProperty(name, value, attributes, kNonStrictMode);
   }
 
   PropertyDetails details = PropertyDetails(attributes, NORMAL);
@@ -2130,6 +2217,7 @@
       // if the value is a function.
       return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
     case NULL_DESCRIPTOR:
+    case EXTERNAL_ARRAY_TRANSITION:
       return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
     default:
       UNREACHABLE();
@@ -2273,6 +2361,7 @@
 
 MaybeObject* NormalizedMapCache::Get(JSObject* obj,
                                      PropertyNormalizationMode mode) {
+  Isolate* isolate = obj->GetIsolate();
   Map* fast = obj->map();
   int index = Hash(fast) % kEntries;
   Object* result = get(index);
@@ -2299,7 +2388,7 @@
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
   set(index, result);
-  COUNTERS->normalized_maps()->Increment();
+  isolate->counters()->normalized_maps()->Increment();
 
   return result;
 }
@@ -2359,7 +2448,7 @@
                                                      UNIQUE_NORMALIZED_MAP);
       if (!maybe_obj->ToObject(&obj)) return maybe_obj;
     }
-    COUNTERS->normalized_maps()->Increment();
+    GetIsolate()->counters()->normalized_maps()->Increment();
 
     set_map(Map::cast(obj));
   }
@@ -5484,6 +5573,7 @@
   DescriptorArray* descriptors = instance_descriptors();
   for (int i = 0; i < descriptors->number_of_descriptors(); i++) {
     if (descriptors->GetType(i) == MAP_TRANSITION ||
+        descriptors->GetType(i) == EXTERNAL_ARRAY_TRANSITION ||
         descriptors->GetType(i) == CONSTANT_TRANSITION) {
       // Get target.
       Map* target = Map::cast(descriptors->GetValue(i));
@@ -5526,6 +5616,7 @@
     // non-live object.
     PropertyDetails details(Smi::cast(contents->get(i + 1)));
     if (details.type() == MAP_TRANSITION ||
+        details.type() == EXTERNAL_ARRAY_TRANSITION ||
         details.type() == CONSTANT_TRANSITION) {
       Map* target = reinterpret_cast<Map*>(contents->get(i));
       ASSERT(target->IsHeapObject());
@@ -5557,7 +5648,7 @@
   ASSERT(shared()->allows_lazy_compilation() ||
          code()->optimizable());
   Builtins* builtins = GetIsolate()->builtins();
-  ReplaceCode(builtins->builtin(Builtins::LazyRecompile));
+  ReplaceCode(builtins->builtin(Builtins::kLazyRecompile));
 }
 
 
@@ -5937,9 +6028,9 @@
   }
   set_initial_map(map);
   Builtins* builtins = map->heap()->isolate()->builtins();
-  ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric),
+  ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric),
             construct_stub());
-  set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown));
+  set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown));
 }
 
 
@@ -5958,9 +6049,9 @@
   // several more GCs) CompleteInobjectSlackTracking will eventually be called.
   set_initial_map(map->heap()->raw_unchecked_undefined_value());
   Builtins* builtins = map->heap()->isolate()->builtins();
-  ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown),
+  ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown),
             *RawField(this, kConstructStubOffset));
-  set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric));
+  set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric));
   // It is safe to clear the flag: it will be set again if the map is live.
   set_live_objects_may_exist(false);
 }
@@ -5974,9 +6065,9 @@
   // Resume inobject slack tracking.
   set_initial_map(map);
   Builtins* builtins = map->heap()->isolate()->builtins();
-  ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric),
+  ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubGeneric),
             *RawField(this, kConstructStubOffset));
-  set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown));
+  set_construct_stub(builtins->builtin(Builtins::kJSConstructStubCountdown));
   // The map survived the gc, so there may be objects referencing it.
   set_live_objects_may_exist(true);
 }
@@ -6008,9 +6099,9 @@
   Heap* heap = map->heap();
   set_initial_map(heap->undefined_value());
   Builtins* builtins = heap->isolate()->builtins();
-  ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown),
+  ASSERT_EQ(builtins->builtin(Builtins::kJSConstructStubCountdown),
             construct_stub());
-  set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric));
+  set_construct_stub(builtins->builtin(Builtins::kJSConstructStubGeneric));
 
   int slack = map->unused_property_fields();
   map->TraverseTransitionTree(&GetMinInobjectSlack, &slack);
@@ -6399,6 +6490,7 @@
     case CALLBACKS: return "CALLBACKS";
     case INTERCEPTOR: return "INTERCEPTOR";
     case MAP_TRANSITION: return "MAP_TRANSITION";
+    case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION";
     case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
     case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
   }
@@ -7345,13 +7437,17 @@
         // When we set the is_extensible flag to false we always force
         // the element into dictionary mode (and force them to stay there).
         if (!map()->is_extensible()) {
-          Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
-          Handle<String> index_string(
-              isolate->factory()->NumberToString(number));
-          Handle<Object> args[1] = { index_string };
-          return isolate->Throw(
-              *isolate->factory()->NewTypeError("object_not_extensible",
-                                                HandleVector(args, 1)));
+          if (strict_mode == kNonStrictMode) {
+            return isolate->heap()->undefined_value();
+          } else {
+            Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
+            Handle<String> index_string(
+                isolate->factory()->NumberToString(number));
+            Handle<Object> args[1] = { index_string };
+            return isolate->Throw(
+                *isolate->factory()->NewTypeError("object_not_extensible",
+                                                  HandleVector(args, 1)));
+          }
         }
         Object* result;
         { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value);
@@ -7489,9 +7585,9 @@
   // callbacks or interceptor calls.
   AssertNoContextChange ncc;
   HandleScope scope(isolate);
-  Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
-  Handle<Object> this_handle(receiver);
-  Handle<JSObject> holder_handle(this);
+  Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate);
+  Handle<Object> this_handle(receiver, isolate);
+  Handle<JSObject> holder_handle(this, isolate);
 
   if (!interceptor->getter()->IsUndefined()) {
     v8::IndexedPropertyGetter getter =
diff --git a/src/objects.h b/src/objects.h
index e0ea064..96e5cb6 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -135,19 +135,37 @@
   PropertyDetails(PropertyAttributes attributes,
                   PropertyType type,
                   int index = 0) {
+    ASSERT(type != EXTERNAL_ARRAY_TRANSITION);
     ASSERT(TypeField::is_valid(type));
     ASSERT(AttributesField::is_valid(attributes));
-    ASSERT(IndexField::is_valid(index));
+    ASSERT(StorageField::is_valid(index));
 
     value_ = TypeField::encode(type)
         | AttributesField::encode(attributes)
-        | IndexField::encode(index);
+        | StorageField::encode(index);
 
     ASSERT(type == this->type());
     ASSERT(attributes == this->attributes());
     ASSERT(index == this->index());
   }
 
+  PropertyDetails(PropertyAttributes attributes,
+                  PropertyType type,
+                  ExternalArrayType array_type) {
+    ASSERT(type == EXTERNAL_ARRAY_TRANSITION);
+    ASSERT(TypeField::is_valid(type));
+    ASSERT(AttributesField::is_valid(attributes));
+    ASSERT(StorageField::is_valid(static_cast<int>(array_type)));
+
+    value_ = TypeField::encode(type)
+        | AttributesField::encode(attributes)
+        | StorageField::encode(static_cast<int>(array_type));
+
+    ASSERT(type == this->type());
+    ASSERT(attributes == this->attributes());
+    ASSERT(array_type == this->array_type());
+  }
+
   // Conversion for storing details as Object*.
   inline PropertyDetails(Smi* smi);
   inline Smi* AsSmi();
@@ -157,7 +175,8 @@
   bool IsTransition() {
     PropertyType t = type();
     ASSERT(t != INTERCEPTOR);
-    return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
+    return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
+        t == EXTERNAL_ARRAY_TRANSITION;
   }
 
   bool IsProperty() {
@@ -166,11 +185,18 @@
 
   PropertyAttributes attributes() { return AttributesField::decode(value_); }
 
-  int index() { return IndexField::decode(value_); }
+  int index() { return StorageField::decode(value_); }
+
+  ExternalArrayType array_type() {
+    ASSERT(type() == EXTERNAL_ARRAY_TRANSITION);
+    return static_cast<ExternalArrayType>(StorageField::decode(value_));
+  }
 
   inline PropertyDetails AsDeleted();
 
-  static bool IsValidIndex(int index) { return IndexField::is_valid(index); }
+  static bool IsValidIndex(int index) {
+    return StorageField::is_valid(index);
+  }
 
   bool IsReadOnly() { return (attributes() & READ_ONLY) != 0; }
   bool IsDontDelete() { return (attributes() & DONT_DELETE) != 0; }
@@ -179,10 +205,10 @@
 
   // Bit fields in value_ (type, shift, size). Must be public so the
   // constants can be embedded in generated code.
-  class TypeField:       public BitField<PropertyType,       0, 3> {};
-  class AttributesField: public BitField<PropertyAttributes, 3, 3> {};
-  class DeletedField:    public BitField<uint32_t,           6, 1> {};
-  class IndexField:      public BitField<uint32_t,           7, 32-7> {};
+  class TypeField:       public BitField<PropertyType,       0, 4> {};
+  class AttributesField: public BitField<PropertyAttributes, 4, 3> {};
+  class DeletedField:    public BitField<uint32_t,           7, 1> {};
+  class StorageField:    public BitField<uint32_t,           8, 32-8> {};
 
   static const int kInitialIndex = 1;
  private:
@@ -557,6 +583,8 @@
   FIRST_FUNCTION_CLASS_TYPE = JS_REGEXP_TYPE
 };
 
+static const int kExternalArrayTypeCount = LAST_EXTERNAL_ARRAY_TYPE -
+    FIRST_EXTERNAL_ARRAY_TYPE + 1;
 
 STATIC_CHECK(JS_OBJECT_TYPE == Internals::kJSObjectType);
 STATIC_CHECK(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType);
@@ -1691,7 +1719,8 @@
   // Add a property to an object.
   MUST_USE_RESULT MaybeObject* AddProperty(String* name,
                                            Object* value,
-                                           PropertyAttributes attributes);
+                                           PropertyAttributes attributes,
+                                           StrictModeFlag strict_mode);
 
   // Convert the object to use the canonical dictionary
   // representation. If the object is expected to have additional properties
@@ -3502,18 +3531,18 @@
   static const int kFlagsICStateShift        = 0;
   static const int kFlagsICInLoopShift       = 3;
   static const int kFlagsTypeShift           = 4;
-  static const int kFlagsKindShift           = 7;
-  static const int kFlagsICHolderShift       = 11;
-  static const int kFlagsExtraICStateShift   = 12;
-  static const int kFlagsArgumentsCountShift = 14;
+  static const int kFlagsKindShift           = 8;
+  static const int kFlagsICHolderShift       = 12;
+  static const int kFlagsExtraICStateShift   = 13;
+  static const int kFlagsArgumentsCountShift = 15;
 
   static const int kFlagsICStateMask        = 0x00000007;  // 00000000111
   static const int kFlagsICInLoopMask       = 0x00000008;  // 00000001000
-  static const int kFlagsTypeMask           = 0x00000070;  // 00001110000
-  static const int kFlagsKindMask           = 0x00000780;  // 11110000000
-  static const int kFlagsCacheInPrototypeMapMask = 0x00000800;
-  static const int kFlagsExtraICStateMask   = 0x00003000;
-  static const int kFlagsArgumentsCountMask = 0xFFFFC000;
+  static const int kFlagsTypeMask           = 0x000000F0;  // 00001110000
+  static const int kFlagsKindMask           = 0x00000F00;  // 11110000000
+  static const int kFlagsCacheInPrototypeMapMask = 0x00001000;
+  static const int kFlagsExtraICStateMask   = 0x00006000;
+  static const int kFlagsArgumentsCountMask = 0xFFFF8000;
 
   static const int kFlagsNotUsedInLookup =
       (kFlagsICInLoopMask | kFlagsTypeMask | kFlagsCacheInPrototypeMapMask);
@@ -3715,7 +3744,9 @@
 
   // Returns a new map with all transitions dropped from the descriptors and the
   // external array elements bit set.
-  MUST_USE_RESULT inline MaybeObject* NewExternalArrayElementsMap();
+  MUST_USE_RESULT MaybeObject* GetExternalArrayElementsMap(
+      ExternalArrayType array_type,
+      bool safe_to_add_transition);
 
   // Returns the property index for name (only valid for FAST MODE).
   int PropertyIndexFor(String* name);
diff --git a/src/parser.cc b/src/parser.cc
index 7dbb09d..eefe7cf 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -284,7 +284,7 @@
     symbol_cache_.at(symbol_id) = result;
     return result;
   }
-  COUNTERS->total_preparse_symbols_skipped()->Increment();
+  isolate()->counters()->total_preparse_symbols_skipped()->Increment();
   return result;
 }
 
@@ -599,8 +599,8 @@
                                       StrictModeFlag strict_mode) {
   CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
 
-  HistogramTimerScope timer(COUNTERS->parse());
-  COUNTERS->total_parse_size()->Increment(source->length());
+  HistogramTimerScope timer(isolate()->counters()->parse());
+  isolate()->counters()->total_parse_size()->Increment(source->length());
   fni_ = new FuncNameInferrer();
 
   // Initialize parser state.
@@ -681,9 +681,9 @@
 
 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
   CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
-  HistogramTimerScope timer(COUNTERS->parse_lazy());
+  HistogramTimerScope timer(isolate()->counters()->parse_lazy());
   Handle<String> source(String::cast(script_->source()));
-  COUNTERS->total_parse_size()->Increment(source->length());
+  isolate()->counters()->total_parse_size()->Increment(source->length());
 
   Handle<SharedFunctionInfo> shared_info = info->shared_info();
   // Initialize parser state.
@@ -3608,7 +3608,7 @@
         // End position greater than end of stream is safe, and hard to check.
         ReportInvalidPreparseData(name, CHECK_OK);
       }
-      COUNTERS->total_preparse_skipped()->Increment(
+      isolate()->counters()->total_preparse_skipped()->Increment(
           end_pos - function_block_pos);
       // Seek to position just before terminal '}'.
       scanner().SeekForward(end_pos - 1);
diff --git a/src/platform-tls-mac.h b/src/platform-tls-mac.h
new file mode 100644
index 0000000..86a3347
--- /dev/null
+++ b/src/platform-tls-mac.h
@@ -0,0 +1,62 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PLATFORM_TLS_MAC_H_
+#define V8_PLATFORM_TLS_MAC_H_
+
+#include "globals.h"
+
+namespace v8 {
+namespace internal {
+
+#if defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64)
+
+#define V8_FAST_TLS_SUPPORTED 1
+
+INLINE(intptr_t InternalGetExistingThreadLocal(intptr_t index));
+
+inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
+  // The constants below are taken from pthreads.s from the XNU kernel
+  // sources archive at www.opensource.apple.com.
+  intptr_t result;
+#if defined(V8_HOST_ARCH_IA32)
+  asm("movl %%gs:0x48(,%1,4), %0;"
+      :"=r"(result)  // Output must be a writable register.
+      :"0"(index));  // Input is the same as output.
+#else
+  asm("movq %%gs:0x60(,%1,8), %0;"
+      :"=r"(result)
+      :"0"(index));
+#endif
+  return result;
+}
+
+#endif
+
+} }  // namespace v8::internal
+
+#endif  // V8_PLATFORM_TLS_MAC_H_
diff --git a/src/platform-tls-win32.h b/src/platform-tls-win32.h
new file mode 100644
index 0000000..4056e8c
--- /dev/null
+++ b/src/platform-tls-win32.h
@@ -0,0 +1,62 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PLATFORM_TLS_WIN32_H_
+#define V8_PLATFORM_TLS_WIN32_H_
+
+#include "checks.h"
+#include "globals.h"
+#include "win32-headers.h"
+
+namespace v8 {
+namespace internal {
+
+#if defined(_WIN32) && !defined(_WIN64)
+
+#define V8_FAST_TLS_SUPPORTED 1
+
+inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
+  const intptr_t kTibInlineTlsOffset = 0xE10;
+  const intptr_t kTibExtraTlsOffset = 0xF94;
+  const intptr_t kMaxInlineSlots = 64;
+  const intptr_t kMaxSlots = kMaxInlineSlots + 1024;
+  ASSERT(0 <= index && index < kMaxSlots);
+  if (index < kMaxInlineSlots) {
+    return static_cast<intptr_t>(__readfsdword(kTibInlineTlsOffset +
+                                               kPointerSize * index));
+  }
+  intptr_t extra = static_cast<intptr_t>(__readfsdword(kTibExtraTlsOffset));
+  ASSERT(extra != 0);
+  return *reinterpret_cast<intptr_t*>(extra +
+                                      kPointerSize * (index - kMaxInlineSlots));
+}
+
+#endif
+
+} }  // namespace v8::internal
+
+#endif  // V8_PLATFORM_TLS_WIN32_H_
diff --git a/src/platform-tls.h b/src/platform-tls.h
new file mode 100644
index 0000000..5649175
--- /dev/null
+++ b/src/platform-tls.h
@@ -0,0 +1,50 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Platform and architecture specific thread local store functions.
+
+#ifndef V8_PLATFORM_TLS_H_
+#define V8_PLATFORM_TLS_H_
+
+#ifdef V8_FAST_TLS
+
+// When fast TLS is requested we include the appropriate
+// implementation header.
+//
+// The implementation header defines V8_FAST_TLS_SUPPORTED if it
+// provides fast TLS support for the current platform and architecture
+// combination.
+
+#if defined(_MSC_VER) && (defined(_WIN32) || defined(_WIN64))
+#include "platform-tls-win32.h"
+#elif defined(__APPLE__)
+#include "platform-tls-mac.h"
+#endif
+
+#endif
+
+#endif  // V8_PLATFORM_TLS_H_
diff --git a/src/platform.h b/src/platform.h
index 43291cf..4f34abe 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -114,6 +114,7 @@
 #endif  // __GNUC__
 
 #include "atomicops.h"
+#include "platform-tls.h"
 #include "utils.h"
 #include "v8globals.h"
 
@@ -428,6 +429,19 @@
     return GetThreadLocal(key) != NULL;
   }
 
+#ifdef V8_FAST_TLS_SUPPORTED
+  static inline void* GetExistingThreadLocal(LocalStorageKey key) {
+    void* result = reinterpret_cast<void*>(
+        InternalGetExistingThreadLocal(static_cast<intptr_t>(key)));
+    ASSERT(result == GetThreadLocal(key));
+    return result;
+  }
+#else
+  static inline void* GetExistingThreadLocal(LocalStorageKey key) {
+    return GetThreadLocal(key);
+  }
+#endif
+
   // A hint to the scheduler to let another thread run.
   static void YieldCPU();
 
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index 42467c3..043ad1c 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
@@ -606,7 +606,8 @@
     ast_printer_->inc_indent();
   }
 
-  explicit IndentedScope(const char* txt, AstNode* node = NULL) {
+  IndentedScope(AstPrinter* printer, const char* txt, AstNode* node = NULL)
+      : ast_printer_(printer) {
     ast_printer_->PrintIndented(txt);
     if (node != NULL && node->AsExpression() != NULL) {
       Expression* expr = node->AsExpression();
@@ -698,14 +699,14 @@
 
 
 void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
-  IndentedScope indent(s, node);
+  IndentedScope indent(this, s, node);
   Visit(node);
 }
 
 
 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
   Init();
-  { IndentedScope indent("FUNC");
+  { IndentedScope indent(this, "FUNC");
     PrintLiteralIndented("NAME", program->name(), true);
     PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
     PrintParameters(program->scope());
@@ -718,7 +719,7 @@
 
 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
   if (declarations->length() > 0) {
-    IndentedScope indent("DECLS");
+    IndentedScope indent(this, "DECLS");
     for (int i = 0; i < declarations->length(); i++) {
       Visit(declarations->at(i));
     }
@@ -728,7 +729,7 @@
 
 void AstPrinter::PrintParameters(Scope* scope) {
   if (scope->num_parameters() > 0) {
-    IndentedScope indent("PARAMS");
+    IndentedScope indent(this, "PARAMS");
     for (int i = 0; i < scope->num_parameters(); i++) {
       PrintLiteralWithModeIndented("VAR", scope->parameter(i),
                                    scope->parameter(i)->name(),
@@ -754,10 +755,10 @@
 
 void AstPrinter::PrintCaseClause(CaseClause* clause) {
   if (clause->is_default()) {
-    IndentedScope indent("DEFAULT");
+    IndentedScope indent(this, "DEFAULT");
     PrintStatements(clause->statements());
   } else {
-    IndentedScope indent("CASE");
+    IndentedScope indent(this, "CASE");
     Visit(clause->label());
     PrintStatements(clause->statements());
   }
@@ -766,7 +767,7 @@
 
 void AstPrinter::VisitBlock(Block* node) {
   const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
-  IndentedScope indent(block_txt);
+  IndentedScope indent(this, block_txt);
   PrintStatements(node->statements());
 }
 
@@ -834,7 +835,7 @@
 
 
 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
-  IndentedScope indent("SWITCH");
+  IndentedScope indent(this, "SWITCH");
   PrintLabelsIndented(NULL, node->labels());
   PrintIndentedVisit("TAG", node->tag());
   for (int i = 0; i < node->cases()->length(); i++) {
@@ -844,7 +845,7 @@
 
 
 void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
-  IndentedScope indent("DO");
+  IndentedScope indent(this, "DO");
   PrintLabelsIndented(NULL, node->labels());
   PrintIndentedVisit("BODY", node->body());
   PrintIndentedVisit("COND", node->cond());
@@ -852,7 +853,7 @@
 
 
 void AstPrinter::VisitWhileStatement(WhileStatement* node) {
-  IndentedScope indent("WHILE");
+  IndentedScope indent(this, "WHILE");
   PrintLabelsIndented(NULL, node->labels());
   PrintIndentedVisit("COND", node->cond());
   PrintIndentedVisit("BODY", node->body());
@@ -860,7 +861,7 @@
 
 
 void AstPrinter::VisitForStatement(ForStatement* node) {
-  IndentedScope indent("FOR");
+  IndentedScope indent(this, "FOR");
   PrintLabelsIndented(NULL, node->labels());
   if (node->init()) PrintIndentedVisit("INIT", node->init());
   if (node->cond()) PrintIndentedVisit("COND", node->cond());
@@ -870,7 +871,7 @@
 
 
 void AstPrinter::VisitForInStatement(ForInStatement* node) {
-  IndentedScope indent("FOR IN");
+  IndentedScope indent(this, "FOR IN");
   PrintIndentedVisit("FOR", node->each());
   PrintIndentedVisit("IN", node->enumerable());
   PrintIndentedVisit("BODY", node->body());
@@ -878,7 +879,7 @@
 
 
 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
-  IndentedScope indent("TRY CATCH");
+  IndentedScope indent(this, "TRY CATCH");
   PrintIndentedVisit("TRY", node->try_block());
   PrintIndentedVisit("CATCHVAR", node->catch_var());
   PrintIndentedVisit("CATCH", node->catch_block());
@@ -886,19 +887,19 @@
 
 
 void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
-  IndentedScope indent("TRY FINALLY");
+  IndentedScope indent(this, "TRY FINALLY");
   PrintIndentedVisit("TRY", node->try_block());
   PrintIndentedVisit("FINALLY", node->finally_block());
 }
 
 
 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
-  IndentedScope indent("DEBUGGER");
+  IndentedScope indent(this, "DEBUGGER");
 }
 
 
 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
-  IndentedScope indent("FUNC LITERAL");
+  IndentedScope indent(this, "FUNC LITERAL");
   PrintLiteralIndented("NAME", node->name(), false);
   PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
   PrintParameters(node->scope());
@@ -911,13 +912,13 @@
 
 void AstPrinter::VisitSharedFunctionInfoLiteral(
     SharedFunctionInfoLiteral* node) {
-  IndentedScope indent("FUNC LITERAL");
+  IndentedScope indent(this, "FUNC LITERAL");
   PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true);
 }
 
 
 void AstPrinter::VisitConditional(Conditional* node) {
-  IndentedScope indent("CONDITIONAL");
+  IndentedScope indent(this, "CONDITIONAL");
   PrintIndentedVisit("?", node->condition());
   PrintIndentedVisit("THEN", node->then_expression());
   PrintIndentedVisit("ELSE", node->else_expression());
@@ -930,14 +931,14 @@
 
 
 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
-  IndentedScope indent("REGEXP LITERAL");
+  IndentedScope indent(this, "REGEXP LITERAL");
   PrintLiteralIndented("PATTERN", node->pattern(), false);
   PrintLiteralIndented("FLAGS", node->flags(), false);
 }
 
 
 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
-  IndentedScope indent("OBJ LITERAL");
+  IndentedScope indent(this, "OBJ LITERAL");
   for (int i = 0; i < node->properties()->length(); i++) {
     const char* prop_kind = NULL;
     switch (node->properties()->at(i)->kind()) {
@@ -962,7 +963,7 @@
       default:
         UNREACHABLE();
     }
-    IndentedScope prop(prop_kind);
+    IndentedScope prop(this, prop_kind);
     PrintIndentedVisit("KEY", node->properties()->at(i)->key());
     PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
   }
@@ -970,9 +971,9 @@
 
 
 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
-  IndentedScope indent("ARRAY LITERAL");
+  IndentedScope indent(this, "ARRAY LITERAL");
   if (node->values()->length() > 0) {
-    IndentedScope indent("VALUES");
+    IndentedScope indent(this, "VALUES");
     for (int i = 0; i < node->values()->length(); i++) {
       Visit(node->values()->at(i));
     }
@@ -981,7 +982,7 @@
 
 
 void AstPrinter::VisitCatchExtensionObject(CatchExtensionObject* node) {
-  IndentedScope indent("CatchExtensionObject");
+  IndentedScope indent(this, "CatchExtensionObject");
   PrintIndentedVisit("KEY", node->key());
   PrintIndentedVisit("VALUE", node->value());
 }
@@ -1006,7 +1007,7 @@
 
 
 void AstPrinter::VisitAssignment(Assignment* node) {
-  IndentedScope indent(Token::Name(node->op()), node);
+  IndentedScope indent(this, Token::Name(node->op()), node);
   Visit(node->target());
   Visit(node->value());
 }
@@ -1018,7 +1019,7 @@
 
 
 void AstPrinter::VisitProperty(Property* node) {
-  IndentedScope indent("PROPERTY", node);
+  IndentedScope indent(this, "PROPERTY", node);
   Visit(node->obj());
   Literal* literal = node->key()->AsLiteral();
   if (literal != NULL && literal->handle()->IsSymbol()) {
@@ -1030,14 +1031,14 @@
 
 
 void AstPrinter::VisitCall(Call* node) {
-  IndentedScope indent("CALL");
+  IndentedScope indent(this, "CALL");
   Visit(node->expression());
   PrintArguments(node->arguments());
 }
 
 
 void AstPrinter::VisitCallNew(CallNew* node) {
-  IndentedScope indent("CALL NEW");
+  IndentedScope indent(this, "CALL NEW");
   Visit(node->expression());
   PrintArguments(node->arguments());
 }
@@ -1076,14 +1077,14 @@
 
 
 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
-  IndentedScope indent(Token::Name(node->op()), node);
+  IndentedScope indent(this, Token::Name(node->op()), node);
   Visit(node->left());
   Visit(node->right());
 }
 
 
 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
-  IndentedScope indent(Token::Name(node->op()), node);
+  IndentedScope indent(this, Token::Name(node->op()), node);
   Visit(node->left());
   Visit(node->right());
 }
@@ -1093,13 +1094,13 @@
   const char* name = node->is_strict()
       ? "COMPARE-TO-NULL-STRICT"
       : "COMPARE-TO-NULL";
-  IndentedScope indent(name, node);
+  IndentedScope indent(this, name, node);
   Visit(node->expression());
 }
 
 
 void AstPrinter::VisitThisFunction(ThisFunction* node) {
-  IndentedScope indent("THIS-FUNCTION");
+  IndentedScope indent(this, "THIS-FUNCTION");
 }
 
 
diff --git a/src/property.cc b/src/property.cc
index 9677433..c35fb83 100644
--- a/src/property.cc
+++ b/src/property.cc
@@ -52,6 +52,12 @@
       GetTransitionMap()->Print(out);
       PrintF(out, "\n");
       break;
+    case EXTERNAL_ARRAY_TRANSITION:
+      PrintF(out, " -type = external array transition\n");
+      PrintF(out, " -map:\n");
+      GetTransitionMap()->Print(out);
+      PrintF(out, "\n");
+      break;
     case CONSTANT_FUNCTION:
       PrintF(out, " -type = constant function\n");
       PrintF(out, " -function:\n");
diff --git a/src/property.h b/src/property.h
index 98d1c89..fa3916e 100644
--- a/src/property.h
+++ b/src/property.h
@@ -110,6 +110,16 @@
       : Descriptor(key, map, attributes, MAP_TRANSITION) { }
 };
 
+class ExternalArrayTransitionDescriptor: public Descriptor {
+ public:
+  ExternalArrayTransitionDescriptor(String* key,
+                                    Map* map,
+                                    ExternalArrayType array_type)
+      : Descriptor(key, map, PropertyDetails(NONE,
+                                             EXTERNAL_ARRAY_TRANSITION,
+                                             array_type)) { }
+};
+
 // Marks a field name in a map so that adding the field is guaranteed
 // to create a FIELD descriptor in the new map.  Used after adding
 // a constant function the first time, creating a CONSTANT_FUNCTION
@@ -262,7 +272,8 @@
 
   Map* GetTransitionMap() {
     ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
-    ASSERT(type() == MAP_TRANSITION || type() == CONSTANT_TRANSITION);
+    ASSERT(type() == MAP_TRANSITION || type() == CONSTANT_TRANSITION ||
+           type() == EXTERNAL_ARRAY_TRANSITION);
     return Map::cast(GetValue());
   }
 
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 98dc00b..c6e2b46 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -197,7 +197,7 @@
   MaybeObject* maybe_check_code = check_stub.TryGetCode();
   if (maybe_check_code->ToObject(&check_code)) {
     Code* replacement_code =
-        isolate_->builtins()->builtin(Builtins::OnStackReplacement);
+        isolate_->builtins()->builtin(Builtins::kOnStackReplacement);
     Code* unoptimized_code = shared->code();
     Deoptimizer::PatchStackCheckCode(unoptimized_code,
                                      Code::cast(check_code),
diff --git a/src/runtime.cc b/src/runtime.cc
index 363d799..c979849 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -593,7 +593,7 @@
   }
   if (JSObject::cast(*boilerplate)->elements()->map() ==
       isolate->heap()->fixed_cow_array_map()) {
-    COUNTERS->cow_arrays_created_runtime()->Increment();
+    isolate->counters()->cow_arrays_created_runtime()->Increment();
   }
   return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
 }
@@ -1811,13 +1811,13 @@
   ASSERT(args.length() == 1);
   CONVERT_ARG_CHECKED(JSObject, holder, 0);
 
-  InstallBuiltin(isolate, holder, "pop", Builtins::ArrayPop);
-  InstallBuiltin(isolate, holder, "push", Builtins::ArrayPush);
-  InstallBuiltin(isolate, holder, "shift", Builtins::ArrayShift);
-  InstallBuiltin(isolate, holder, "unshift", Builtins::ArrayUnshift);
-  InstallBuiltin(isolate, holder, "slice", Builtins::ArraySlice);
-  InstallBuiltin(isolate, holder, "splice", Builtins::ArraySplice);
-  InstallBuiltin(isolate, holder, "concat", Builtins::ArrayConcat);
+  InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
+  InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
+  InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
+  InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
+  InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
+  InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
+  InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
 
   return *holder;
 }
@@ -5230,8 +5230,9 @@
   int final_length = static_cast<int>(
       write_cursor - reinterpret_cast<Char*>(
           new_string->address() + SeqAsciiString::kHeaderSize));
-  isolate->heap()->new_space()->ShrinkStringAtAllocationBoundary<StringType>(
-      new_string, final_length);
+  isolate->heap()->new_space()->
+      template ShrinkStringAtAllocationBoundary<StringType>(
+          new_string, final_length);
   return new_string;
 }
 
@@ -7650,8 +7651,7 @@
   }
   StackCheckStub check_stub;
   Handle<Code> check_code = check_stub.GetCode();
-  Handle<Code> replacement_code(
-      isolate->builtins()->builtin(Builtins::OnStackReplacement));
+  Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement();
   Deoptimizer::RevertStackCheckCode(*unoptimized,
                                     *check_code,
                                     *replacement_code);
@@ -9308,6 +9308,7 @@
     }
     case INTERCEPTOR:
     case MAP_TRANSITION:
+    case EXTERNAL_ARRAY_TRANSITION:
     case CONSTANT_TRANSITION:
     case NULL_DESCRIPTOR:
       return heap->undefined_value();
@@ -12217,16 +12218,17 @@
 
 
 void Runtime::PerformGC(Object* result) {
+  Isolate* isolate = Isolate::Current();
   Failure* failure = Failure::cast(result);
   if (failure->IsRetryAfterGC()) {
     // Try to do a garbage collection; ignore it if it fails. The C
     // entry stub will throw an out-of-memory exception in that case.
-    HEAP->CollectGarbage(failure->allocation_space());
+    isolate->heap()->CollectGarbage(failure->allocation_space());
   } else {
     // Handle last resort GC and make sure to allow future allocations
     // to grow the heap without causing GCs (if possible).
-    COUNTERS->gc_last_resort_from_js()->Increment();
-    HEAP->CollectAllGarbage(false);
+    isolate->counters()->gc_last_resort_from_js()->Increment();
+    isolate->heap()->CollectAllGarbage(false);
   }
 }
 
diff --git a/src/serialize.cc b/src/serialize.cc
index 260abd8..12e9613 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -196,7 +196,7 @@
 
 #define DEF_ENTRY_C(name, ignored) \
   { BUILTIN, \
-    Builtins::name, \
+    Builtins::k##name, \
     "Builtins::" #name },
 #define DEF_ENTRY_A(name, kind, state, extra) DEF_ENTRY_C(name, ignored)
 
diff --git a/src/small-pointer-list.h b/src/small-pointer-list.h
new file mode 100644
index 0000000..6291d9e
--- /dev/null
+++ b/src/small-pointer-list.h
@@ -0,0 +1,163 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_SMALL_POINTER_LIST_H_
+#define V8_SMALL_POINTER_LIST_H_
+
+#include "checks.h"
+#include "v8globals.h"
+#include "zone.h"
+
+namespace v8 {
+namespace internal {
+
+// SmallPointerList is a list optimized for storing no or just a
+// single value. When more values are given it falls back to ZoneList.
+//
+// The interface tries to be as close to List from list.h as possible.
+template <typename T>
+class SmallPointerList {
+ public:
+  SmallPointerList() : data_(kEmptyTag) {}
+
+  bool is_empty() const { return length() == 0; }
+
+  int length() const {
+    if ((data_ & kTagMask) == kEmptyTag) return 0;
+    if ((data_ & kTagMask) == kSingletonTag) return 1;
+    return list()->length();
+  }
+
+  void Add(T* pointer) {
+    ASSERT(IsAligned(reinterpret_cast<intptr_t>(pointer), kPointerAlignment));
+    if ((data_ & kTagMask) == kEmptyTag) {
+      data_ = reinterpret_cast<intptr_t>(pointer) | kSingletonTag;
+      return;
+    }
+    if ((data_ & kTagMask) == kSingletonTag) {
+      PointerList* list = new PointerList(2);
+      list->Add(single_value());
+      list->Add(pointer);
+      ASSERT(IsAligned(reinterpret_cast<intptr_t>(list), kPointerAlignment));
+      data_ = reinterpret_cast<intptr_t>(list) | kListTag;
+      return;
+    }
+    list()->Add(pointer);
+  }
+
+  // Note: returns T* and not T*& (unlike List from list.h).
+  // This makes the implementation simpler and more const correct.
+  T* at(int i) const {
+    ASSERT((data_ & kTagMask) != kEmptyTag);
+    if ((data_ & kTagMask) == kSingletonTag) {
+      ASSERT(i == 0);
+      return single_value();
+    }
+    return list()->at(i);
+  }
+
+  // See the note above.
+  T* operator[](int i) const { return at(i); }
+
+  // Remove the given element from the list (if present).
+  void RemoveElement(T* pointer) {
+    if ((data_ & kTagMask) == kEmptyTag) return;
+    if ((data_ & kTagMask) == kSingletonTag) {
+      if (pointer == single_value()) {
+        data_ = kEmptyTag;
+      }
+      return;
+    }
+    list()->RemoveElement(pointer);
+  }
+
+  T* RemoveLast() {
+    ASSERT((data_ & kTagMask) != kEmptyTag);
+    if ((data_ & kTagMask) == kSingletonTag) {
+      T* result = single_value();
+      data_ = kEmptyTag;
+      return result;
+    }
+    return list()->RemoveLast();
+  }
+
+  void Rewind(int pos) {
+    if ((data_ & kTagMask) == kEmptyTag) {
+      ASSERT(pos == 0);
+      return;
+    }
+    if ((data_ & kTagMask) == kSingletonTag) {
+      ASSERT(pos == 0 || pos == 1);
+      if (pos == 0) {
+        data_ = kEmptyTag;
+      }
+      return;
+    }
+    list()->Rewind(pos);
+  }
+
+  int CountOccurrences(T* pointer, int start, int end) const {
+    if ((data_ & kTagMask) == kEmptyTag) return 0;
+    if ((data_ & kTagMask) == kSingletonTag) {
+      if (start == 0 && end >= 0) {
+        return (single_value() == pointer) ? 1 : 0;
+      }
+      return 0;
+    }
+    return list()->CountOccurrences(pointer, start, end);
+  }
+
+ private:
+  typedef ZoneList<T*> PointerList;
+
+  static const intptr_t kEmptyTag = 1;
+  static const intptr_t kSingletonTag = 0;
+  static const intptr_t kListTag = 2;
+  static const intptr_t kTagMask = 3;
+  static const intptr_t kValueMask = ~kTagMask;
+
+  STATIC_ASSERT(kTagMask + 1 <= kPointerAlignment);
+
+  T* single_value() const {
+    ASSERT((data_ & kTagMask) == kSingletonTag);
+    STATIC_ASSERT(kSingletonTag == 0);
+    return reinterpret_cast<T*>(data_);
+  }
+
+  PointerList* list() const {
+    ASSERT((data_ & kTagMask) == kListTag);
+    return reinterpret_cast<PointerList*>(data_ & kValueMask);
+  }
+
+  intptr_t data_;
+
+  DISALLOW_COPY_AND_ASSIGN(SmallPointerList);
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_SMALL_POINTER_LIST_H_
diff --git a/src/spaces.cc b/src/spaces.cc
index ca76189..20700e1 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -393,7 +393,7 @@
 #ifdef DEBUG
   ZapBlock(reinterpret_cast<Address>(mem), alloced);
 #endif
-  COUNTERS->memory_allocated()->Increment(alloced);
+  isolate_->counters()->memory_allocated()->Increment(alloced);
   return mem;
 }
 
@@ -409,7 +409,7 @@
   } else {
     OS::Free(mem, length);
   }
-  COUNTERS->memory_allocated()->Decrement(static_cast<int>(length));
+  isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(length));
   size_ -= static_cast<int>(length);
   if (executable == EXECUTABLE) size_executable_ -= static_cast<int>(length);
 
@@ -537,7 +537,7 @@
 #ifdef DEBUG
   ZapBlock(start, size);
 #endif
-  COUNTERS->memory_allocated()->Increment(static_cast<int>(size));
+  isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size));
 
   // So long as we correctly overestimated the number of chunks we should not
   // run out of chunk ids.
@@ -561,7 +561,7 @@
 #ifdef DEBUG
   ZapBlock(start, size);
 #endif
-  COUNTERS->memory_allocated()->Increment(static_cast<int>(size));
+  isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size));
   return true;
 }
 
@@ -574,7 +574,7 @@
   ASSERT(InInitialChunk(start + size - 1));
 
   if (!initial_chunk_->Uncommit(start, size)) return false;
-  COUNTERS->memory_allocated()->Decrement(static_cast<int>(size));
+  isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size));
   return true;
 }
 
@@ -675,7 +675,8 @@
     // TODO(1240712): VirtualMemory::Uncommit has a return value which
     // is ignored here.
     initial_chunk_->Uncommit(c.address(), c.size());
-    COUNTERS->memory_allocated()->Decrement(static_cast<int>(c.size()));
+    Counters* counters = isolate_->counters();
+    counters->memory_allocated()->Decrement(static_cast<int>(c.size()));
   } else {
     LOG(isolate_, DeleteEvent("PagedChunk", c.address()));
     ObjectSpace space = static_cast<ObjectSpace>(1 << c.owner_identity());
@@ -2753,7 +2754,7 @@
   LargeObjectChunk* chunk = reinterpret_cast<LargeObjectChunk*>(mem);
   chunk->size_ = size;
   Page* page = Page::FromAddress(RoundUp(chunk->address(), Page::kPageSize));
-  page->heap_ = Isolate::Current()->heap();
+  page->heap_ = isolate->heap();
   return chunk;
 }
 
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 0e78af4..cd198e2 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -84,7 +84,7 @@
 
   // If the primary entry has useful data in it, we retire it to the
   // secondary cache before overwriting it.
-  if (hit != isolate_->builtins()->builtin(Builtins::Illegal)) {
+  if (hit != isolate_->builtins()->builtin(Builtins::kIllegal)) {
     Code::Flags primary_flags = Code::RemoveTypeFromFlags(hit->flags());
     int secondary_offset =
         SecondaryOffset(primary->key, primary_flags, primary_offset);
@@ -245,7 +245,7 @@
 
 
 MaybeObject* StubCache::ComputeLoadNormal() {
-  return isolate_->builtins()->builtin(Builtins::LoadIC_Normal);
+  return isolate_->builtins()->builtin(Builtins::kLoadIC_Normal);
 }
 
 
@@ -649,7 +649,7 @@
     }
     Object* result;
     { MaybeObject* maybe_result =
-          receiver->map()->UpdateCodeCache(name, Code::cast(code));
+          receiver->UpdateMapCodeCache(name, Code::cast(code));
       if (!maybe_result->ToObject(&result)) return maybe_result;
     }
   }
@@ -659,8 +659,8 @@
 
 MaybeObject* StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) {
   return isolate_->builtins()->builtin((strict_mode == kStrictMode)
-                            ? Builtins::StoreIC_Normal_Strict
-                            : Builtins::StoreIC_Normal);
+                            ? Builtins::kStoreIC_Normal_Strict
+                            : Builtins::kStoreIC_Normal);
 }
 
 
@@ -1221,12 +1221,12 @@
   for (int i = 0; i < kPrimaryTableSize; i++) {
     primary_[i].key = isolate_->heap()->empty_string();
     primary_[i].value = isolate_->builtins()->builtin(
-        Builtins::Illegal);
+        Builtins::kIllegal);
   }
   for (int j = 0; j < kSecondaryTableSize; j++) {
     secondary_[j].key = isolate_->heap()->empty_string();
     secondary_[j].value = isolate_->builtins()->builtin(
-        Builtins::Illegal);
+        Builtins::kIllegal);
   }
 }
 
@@ -1500,7 +1500,7 @@
         GetCodeWithFlags(flags, "CompileCallInitialize");
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-  COUNTERS->call_initialize_stubs()->Increment();
+  isolate()->counters()->call_initialize_stubs()->Increment();
   Code* code = Code::cast(result);
   USE(code);
   PROFILE(isolate(),
@@ -1527,7 +1527,7 @@
         GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-  COUNTERS->call_premonomorphic_stubs()->Increment();
+  isolate()->counters()->call_premonomorphic_stubs()->Increment();
   Code* code = Code::cast(result);
   USE(code);
   PROFILE(isolate(),
@@ -1551,7 +1551,7 @@
   { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallNormal");
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-  COUNTERS->call_normal_stubs()->Increment();
+  isolate()->counters()->call_normal_stubs()->Increment();
   Code* code = Code::cast(result);
   USE(code);
   PROFILE(isolate(),
@@ -1576,7 +1576,7 @@
         GetCodeWithFlags(flags, "CompileCallMegamorphic");
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-  COUNTERS->call_megamorphic_stubs()->Increment();
+  isolate()->counters()->call_megamorphic_stubs()->Increment();
   Code* code = Code::cast(result);
   USE(code);
   PROFILE(isolate(),
@@ -1600,7 +1600,7 @@
   { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss");
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
-  COUNTERS->call_megamorphic_stubs()->Increment();
+  isolate()->counters()->call_megamorphic_stubs()->Increment();
   Code* code = Code::cast(result);
   USE(code);
   PROFILE(isolate(),
diff --git a/src/type-info.cc b/src/type-info.cc
index 7367390..78f693c 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -335,7 +335,7 @@
   Handle<Object> object = GetInfo(position);
   if (object->IsUndefined() || object->IsSmi()) return NULL;
 
-  if (*object == isolate->builtins()->builtin(Builtins::StoreIC_GlobalProxy)) {
+  if (*object == isolate->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
     // TODO(fschneider): We could collect the maps and signal that
     // we need a generic store (or load) here.
     ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC);
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 27c2a96..04482e8 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -207,8 +207,6 @@
   SC(memcopy_noxmm, V8.MemCopyNoXMM)                                  \
   SC(enum_cache_hits, V8.EnumCacheHits)                               \
   SC(enum_cache_misses, V8.EnumCacheMisses)                           \
-  SC(reloc_info_count, V8.RelocInfoCount)                             \
-  SC(reloc_info_size, V8.RelocInfoSize)                               \
   SC(zone_segment_bytes, V8.ZoneSegmentBytes)                         \
   SC(compute_entry_frame, V8.ComputeEntryFrame)                       \
   SC(generic_binary_stub_calls, V8.GenericBinaryStubCalls)            \
@@ -311,8 +309,6 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(Counters);
 };
 
-#define COUNTERS Isolate::Current()->counters()
-
 } }  // namespace v8::internal
 
 #endif  // V8_V8_COUNTERS_H_
diff --git a/src/v8globals.h b/src/v8globals.h
index 0933acf..7ff464a 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -318,14 +318,15 @@
 // Must fit in the BitField PropertyDetails::TypeField.
 // A copy of this is in mirror-debugger.js.
 enum PropertyType {
-  NORMAL              = 0,  // only in slow mode
-  FIELD               = 1,  // only in fast mode
-  CONSTANT_FUNCTION   = 2,  // only in fast mode
-  CALLBACKS           = 3,
-  INTERCEPTOR         = 4,  // only in lookup results, not in descriptors.
-  MAP_TRANSITION      = 5,  // only in fast mode
-  CONSTANT_TRANSITION = 6,  // only in fast mode
-  NULL_DESCRIPTOR     = 7,  // only in fast mode
+  NORMAL                    = 0,  // only in slow mode
+  FIELD                     = 1,  // only in fast mode
+  CONSTANT_FUNCTION         = 2,  // only in fast mode
+  CALLBACKS                 = 3,
+  INTERCEPTOR               = 4,  // only in lookup results, not in descriptors.
+  MAP_TRANSITION            = 5,  // only in fast mode
+  EXTERNAL_ARRAY_TRANSITION = 6,
+  CONSTANT_TRANSITION       = 7,  // only in fast mode
+  NULL_DESCRIPTOR           = 8,  // only in fast mode
   // All properties before MAP_TRANSITION are real.
   FIRST_PHANTOM_PROPERTY_TYPE = MAP_TRANSITION,
   // There are no IC stubs for NULL_DESCRIPTORS. Therefore,
diff --git a/src/version.cc b/src/version.cc
index d1c85f3..e90c1cb 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,9 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     2
-#define BUILD_NUMBER      4
-#define PATCH_LEVEL       2
+#define BUILD_NUMBER      5
+#define PATCH_LEVEL       0
+
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 9a031ee..0744b8a 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -415,8 +415,6 @@
   desc->reloc_size =
       static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
   desc->origin = this;
-
-  COUNTERS->reloc_info_size()->Increment(desc->reloc_size);
 }
 
 
@@ -946,6 +944,12 @@
   emit(0xF8);
 }
 
+void Assembler::cld() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0xFC);
+}
+
 void Assembler::cdq() {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 5d91436..52aca63 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -1137,6 +1137,7 @@
 
   // Miscellaneous
   void clc();
+  void cld();
   void cpuid();
   void hlt();
   void int3();
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 3db449c..21d3e54 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -98,8 +98,8 @@
   // Set expected number of arguments to zero (not changing rax).
   __ movq(rbx, Immediate(0));
   __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
-  __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
-        ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+          RelocInfo::CODE_TARGET);
 }
 
 
@@ -339,8 +339,8 @@
   // Call the function.
   if (is_api_function) {
     __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
-    Handle<Code> code = Handle<Code>(masm->isolate()->builtins()->builtin(
-        Builtins::HandleApiCallConstruct));
+    Handle<Code> code =
+        masm->isolate()->builtins()->HandleApiCallConstruct();
     ParameterCount expected(0);
     __ InvokeCode(code, expected, expected,
                   RelocInfo::CODE_TARGET, CALL_FUNCTION);
@@ -379,7 +379,8 @@
   SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
   __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
   __ push(rcx);
-  __ IncrementCounter(COUNTERS->constructed_objects(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->constructed_objects(), 1);
   __ ret(0);
 }
 
@@ -492,8 +493,8 @@
   // Invoke the code.
   if (is_construct) {
     // Expects rdi to hold function pointer.
-    __ Call(Handle<Code>(masm->isolate()->builtins()->builtin(
-        Builtins::JSConstructCall)), RelocInfo::CODE_TARGET);
+    __ Call(masm->isolate()->builtins()->JSConstructCall(),
+            RelocInfo::CODE_TARGET);
   } else {
     ParameterCount actual(rax);
     // Function must be in rdi.
@@ -733,8 +734,8 @@
     __ j(not_zero, &function);
     __ Set(rbx, 0);
     __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
-    __ Jump(Handle<Code>(masm->isolate()->builtins()->builtin(
-        ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+            RelocInfo::CODE_TARGET);
     __ bind(&function);
   }
 
@@ -748,8 +749,8 @@
   __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
   __ cmpq(rax, rbx);
   __ j(not_equal,
-       Handle<Code>(masm->isolate()->builtins()->builtin(
-           ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET);
+       masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+       RelocInfo::CODE_TARGET);
 
   ParameterCount expected(0);
   __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION);
@@ -863,8 +864,8 @@
   __ movq(rdx, Operand(rbp, kArgumentsOffset));  // load arguments
 
   // Use inline caching to speed up access to arguments.
-  Handle<Code> ic(masm->isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic =
+      masm->isolate()->builtins()->KeyedLoadIC_Initialize();
   __ Call(ic, RelocInfo::CODE_TARGET);
   // It is important that we do not have a test instruction after the
   // call.  A test instruction after the call is used to indicate that
@@ -1138,7 +1139,8 @@
                        r8,
                        kPreallocatedArrayElements,
                        call_generic_code);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->array_function_native(), 1);
   __ movq(rax, rbx);
   __ ret(kPointerSize);
 
@@ -1169,7 +1171,7 @@
                   r9,
                   true,
                   call_generic_code);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1);
+  __ IncrementCounter(counters->array_function_native(), 1);
   __ movq(rax, rbx);
   __ ret(2 * kPointerSize);
 
@@ -1191,7 +1193,7 @@
                   r9,
                   false,
                   call_generic_code);
-  __ IncrementCounter(COUNTERS->array_function_native(), 1);
+  __ IncrementCounter(counters->array_function_native(), 1);
 
   // rax: argc
   // rbx: JSArray
@@ -1265,9 +1267,8 @@
   // Jump to the generic array code in case the specialized code cannot handle
   // the construction.
   __ bind(&generic_array_code);
-  Code* code =
-      masm->isolate()->builtins()->builtin(Builtins::ArrayCodeGeneric);
-  Handle<Code> array_code(code);
+  Handle<Code> array_code =
+      masm->isolate()->builtins()->ArrayCodeGeneric();
   __ Jump(array_code, RelocInfo::CODE_TARGET);
 }
 
@@ -1300,9 +1301,8 @@
   // Jump to the generic construct code in case the specialized code cannot
   // handle the construction.
   __ bind(&generic_constructor);
-  Code* code =
-      masm->isolate()->builtins()->builtin(Builtins::JSConstructStubGeneric);
-  Handle<Code> generic_construct_stub(code);
+  Handle<Code> generic_construct_stub =
+      masm->isolate()->builtins()->JSConstructStubGeneric();
   __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
 }
 
@@ -1356,7 +1356,8 @@
   // -----------------------------------
 
   Label invoke, dont_adapt_arguments;
-  __ IncrementCounter(COUNTERS->arguments_adaptors(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->arguments_adaptors(), 1);
 
   Label enough, too_few;
   __ cmpq(rax, rbx);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 9196e3a..e6f4696 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -359,7 +359,8 @@
 
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
-    __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+    Counters* counters = masm->isolate()->counters();
+    __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
   }
 
   // Call the stub.
@@ -395,7 +396,8 @@
 
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
-    __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+  Counters* counters = masm->isolate()->counters();
+    __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
   }
 
   // Call the stub.
@@ -430,7 +432,8 @@
     }
     // Update flags to indicate that arguments are in registers.
     SetArgsInRegisters();
-    __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1);
+  Counters* counters = masm->isolate()->counters();
+    __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1);
   }
 
   // Call the stub.
@@ -2599,7 +2602,8 @@
   // rcx: encoding of subject string (1 if ascii 0 if two_byte);
   // r11: code
   // All checks done. Now push arguments for native regexp code.
-  __ IncrementCounter(COUNTERS->regexp_entry_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->regexp_entry_native(), 1);
 
   // Isolates: note we add an additional parameter here (isolate pointer).
   static const int kRegExpExecuteArguments = 8;
@@ -2951,7 +2955,8 @@
                        index,
                        times_1,
                        FixedArray::kHeaderSize + kPointerSize));
-  __ IncrementCounter(COUNTERS->number_to_string_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->number_to_string_native(), 1);
 }
 
 
@@ -3327,8 +3332,8 @@
   __ Set(rax, argc_);
   __ Set(rbx, 0);
   __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
-  Handle<Code> adaptor(Isolate::Current()->builtins()->builtin(
-      Builtins::ArgumentsAdaptorTrampoline));
+  Handle<Code> adaptor =
+      Isolate::Current()->builtins()->ArgumentsAdaptorTrampoline();
   __ Jump(adaptor, RelocInfo::CODE_TARGET);
 }
 
@@ -3651,11 +3656,11 @@
   // directly in the code, because the builtin stubs may not have been
   // generated yet at the time this code is generated.
   if (is_construct) {
-    ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline,
+    ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
                                       isolate);
     __ Load(rax, construct_entry);
   } else {
-    ExternalReference entry(Builtins::JSEntryTrampoline, isolate);
+    ExternalReference entry(Builtins::kJSEntryTrampoline, isolate);
     __ Load(rax, entry);
   }
   __ lea(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
@@ -4173,7 +4178,8 @@
   __ SmiTest(rcx);
   __ j(not_zero, &second_not_zero_length);
   // Second string is empty, result is first string which is already in rax.
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
   __ bind(&second_not_zero_length);
   __ movq(rbx, FieldOperand(rax, String::kLengthOffset));
@@ -4181,7 +4187,7 @@
   __ j(not_zero, &both_not_zero_length);
   // First string is empty, result is second string which is in rdx.
   __ movq(rax, rdx);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   // Both strings are non-empty.
@@ -4225,7 +4231,7 @@
   Label make_two_character_string, make_flat_ascii_string;
   StringHelper::GenerateTwoCharacterSymbolTableProbe(
       masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   __ bind(&make_two_character_string);
@@ -4265,7 +4271,7 @@
   __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax);
   __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx);
   __ movq(rax, rcx);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
   __ bind(&non_ascii);
   // At least one of the strings is two-byte. Check whether it happens
@@ -4339,7 +4345,7 @@
   // rdi: length of second argument
   StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, true);
   __ movq(rax, rbx);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   // Handle creating a flat two byte result.
@@ -4376,7 +4382,7 @@
   // rdi: length of second argument
   StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, false);
   __ movq(rax, rbx);
-  __ IncrementCounter(COUNTERS->string_add_native(), 1);
+  __ IncrementCounter(counters->string_add_native(), 1);
   __ ret(2 * kPointerSize);
 
   // Just jump to runtime to add the two strings.
@@ -4791,7 +4797,8 @@
   // rsi: character of sub string start
   StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
   __ movq(rsi, rdx);  // Restore rsi.
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(kArgumentsSize);
 
   __ bind(&non_ascii_flat);
@@ -4828,7 +4835,7 @@
   __ movq(rsi, rdx);  // Restore esi.
 
   __ bind(&return_rax);
-  __ IncrementCounter(COUNTERS->sub_string_native(), 1);
+  __ IncrementCounter(counters->sub_string_native(), 1);
   __ ret(kArgumentsSize);
 
   // Just jump to runtime to create the sub string.
@@ -4942,7 +4949,8 @@
   __ cmpq(rdx, rax);
   __ j(not_equal, &not_same);
   __ Move(rax, Smi::FromInt(EQUAL));
-  __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->string_compare_native(), 1);
   __ ret(2 * kPointerSize);
 
   __ bind(&not_same);
@@ -4951,7 +4959,7 @@
   __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime);
 
   // Inline comparison of ascii strings.
-  __ IncrementCounter(COUNTERS->string_compare_native(), 1);
+  __ IncrementCounter(counters->string_compare_native(), 1);
   // Drop arguments from the stack
   __ pop(rcx);
   __ addq(rsp, Immediate(2 * kPointerSize));
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 33c5752..6f34cf7 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -2561,8 +2561,7 @@
       __ j(not_equal, &build_args);
       __ movq(rcx, FieldOperand(rax, JSFunction::kCodeEntryOffset));
       __ subq(rcx, Immediate(Code::kHeaderSize - kHeapObjectTag));
-      Handle<Code> apply_code(Isolate::Current()->builtins()->builtin(
-          Builtins::FunctionApply));
+      Handle<Code> apply_code = Isolate::Current()->builtins()->FunctionApply();
       __ Cmp(rcx, apply_code);
       __ j(not_equal, &build_args);
 
@@ -4982,7 +4981,8 @@
     FastCloneShallowArrayStub stub(
         FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS, length);
     clone = frame_->CallStub(&stub, 3);
-    __ IncrementCounter(COUNTERS->cow_arrays_created_stub(), 1);
+    Counters* counters = masm()->isolate()->counters();
+    __ IncrementCounter(counters->cow_arrays_created_stub(), 1);
   } else if (node->depth() > 1) {
     clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
   } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
@@ -7998,8 +7998,7 @@
     __ movq(rax, receiver_);
   }
   __ Move(rcx, name_);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+  Handle<Code> ic = Isolate::Current()->builtins()->LoadIC_Initialize();
   __ Call(ic, RelocInfo::CODE_TARGET);
   // The call must be followed by a test rax instruction to indicate
   // that the inobject property case was inlined.
@@ -8011,7 +8010,8 @@
   // Here we use masm_-> instead of the __ macro because this is the
   // instruction that gets patched and coverage code gets in the way.
   masm_->testl(rax, Immediate(-delta_to_patch_site));
-  __ IncrementCounter(COUNTERS->named_load_inline_miss(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->named_load_inline_miss(), 1);
 
   if (!dst_.is(rax)) __ movq(dst_, rax);
 }
@@ -8064,8 +8064,7 @@
   // it in the IC initialization code and patch the movq instruction.
   // This means that we cannot allow test instructions after calls to
   // KeyedLoadIC stubs in other places.
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = Isolate::Current()->builtins()->KeyedLoadIC_Initialize();
   __ Call(ic, RelocInfo::CODE_TARGET);
   // The delta from the start of the map-compare instruction to the
   // test instruction.  We use masm_-> directly here instead of the __
@@ -8079,7 +8078,8 @@
   // 7-byte NOP with non-zero immediate (0f 1f 80 xxxxxxxx) which won't
   // be generated normally.
   masm_->testl(rax, Immediate(-delta_to_patch_site));
-  __ IncrementCounter(COUNTERS->keyed_load_inline_miss(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_inline_miss(), 1);
 
   if (!dst_.is(rax)) __ movq(dst_, rax);
 }
@@ -8112,7 +8112,8 @@
 
 
 void DeferredReferenceSetKeyedValue::Generate() {
-  __ IncrementCounter(COUNTERS->keyed_store_inline_miss(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_store_inline_miss(), 1);
   // Move value, receiver, and key to registers rax, rdx, and rcx, as
   // the IC stub expects.
   // Move value to rax, using xchg if the receiver or key is in rax.
@@ -8160,8 +8161,8 @@
 
   // Call the IC stub.
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
-                                    : Builtins::KeyedStoreIC_Initialize));
+      (strict_mode_ == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+                                    : Builtins::kKeyedStoreIC_Initialize));
   __ Call(ic, RelocInfo::CODE_TARGET);
   // The delta from the start of the map-compare instructions (initial movq)
   // to the test instruction.  We use masm_-> directly here instead of the
@@ -8247,7 +8248,8 @@
     int offset = kMaxInt;
     masm()->movq(result.reg(), FieldOperand(receiver.reg(), offset));
 
-    __ IncrementCounter(COUNTERS->named_load_inline(), 1);
+    Counters* counters = masm()->isolate()->counters();
+    __ IncrementCounter(counters->named_load_inline(), 1);
     deferred->BindExit();
   }
   ASSERT(frame()->height() == original_height - 1);
@@ -8454,7 +8456,8 @@
     result = elements;
     __ CompareRoot(result.reg(), Heap::kTheHoleValueRootIndex);
     deferred->Branch(equal);
-    __ IncrementCounter(COUNTERS->keyed_load_inline(), 1);
+    Counters* counters = masm()->isolate()->counters();
+    __ IncrementCounter(counters->keyed_load_inline(), 1);
 
     deferred->BindExit();
   } else {
@@ -8565,7 +8568,8 @@
                          index.scale,
                          FixedArray::kHeaderSize),
             result.reg());
-    __ IncrementCounter(COUNTERS->keyed_store_inline(), 1);
+    Counters* counters = masm()->isolate()->counters();
+    __ IncrementCounter(counters->keyed_store_inline(), 1);
 
     deferred->BindExit();
   } else {
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index 63067bd..c58d5ea 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -101,6 +101,11 @@
 };
 
 
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  // TODO(1276): Implement.
+}
+
+
 void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
   HandleScope scope;
   AssertNoAllocation no_allocation;
@@ -187,7 +192,7 @@
 
   // Add the deoptimizing code to the list.
   DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
-  DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
+  DeoptimizerData* data = code->GetIsolate()->deoptimizer_data();
   node->set_next(data->deoptimizing_code_list_);
   data->deoptimizing_code_list_ = node;
 
@@ -389,8 +394,8 @@
         optimized_code_->entry() + pc_offset);
     output_[0]->SetPc(pc);
   }
-  Code* continuation = Isolate::Current()->builtins()->builtin(
-      Builtins::NotifyOSR);
+  Code* continuation =
+      function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
   output_[0]->SetContinuation(
       reinterpret_cast<intptr_t>(continuation->entry()));
 
@@ -562,9 +567,8 @@
   // Set the continuation for the topmost frame.
   if (is_topmost) {
     Code* continuation = (bailout_type_ == EAGER)
-        ? Isolate::Current()->builtins()->builtin(Builtins::NotifyDeoptimized)
-        : Isolate::Current()->builtins()->builtin(
-              Builtins::NotifyLazyDeoptimized);
+        ? isolate_->builtins()->builtin(Builtins::kNotifyDeoptimized)
+        : isolate_->builtins()->builtin(Builtins::kNotifyLazyDeoptimized);
     output_frame->SetContinuation(
         reinterpret_cast<intptr_t>(continuation->entry()));
   }
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 2253596..90afd85 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -740,9 +740,9 @@
              prop->key()->AsLiteral()->handle()->IsSmi());
       __ Move(rcx, prop->key()->AsLiteral()->handle());
 
-      Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
-          ? Builtins::KeyedStoreIC_Initialize_Strict
-          : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
     }
   }
@@ -1121,8 +1121,7 @@
   // load IC call.
   __ movq(rax, GlobalObjectOperand());
   __ Move(rcx, slot->var()->name());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
       ? RelocInfo::CODE_TARGET
       : RelocInfo::CODE_TARGET_CONTEXT;
@@ -1205,8 +1204,8 @@
                   ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
                                                     slow));
           __ Move(rax, key_literal->handle());
-          Handle<Code> ic(isolate()->builtins()->builtin(
-              Builtins::KeyedLoadIC_Initialize));
+          Handle<Code> ic =
+              isolate()->builtins()->KeyedLoadIC_Initialize();
           EmitCallIC(ic, RelocInfo::CODE_TARGET);
           __ jmp(done);
         }
@@ -1229,8 +1228,7 @@
     // object on the stack.
     __ Move(rcx, var->name());
     __ movq(rax, GlobalObjectOperand());
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::LoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
     context()->Plug(rax);
 
@@ -1293,8 +1291,7 @@
     __ Move(rax, key_literal->handle());
 
     // Do a keyed property load.
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::KeyedLoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET);
     context()->Plug(rax);
   }
@@ -1405,8 +1402,7 @@
           __ Move(rcx, key->handle());
           __ movq(rdx, Operand(rsp, 0));
           if (property->emit_store()) {
-            Handle<Code> ic(isolate()->builtins()->builtin(
-                Builtins::StoreIC_Initialize));
+            Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
             EmitCallIC(ic, RelocInfo::CODE_TARGET);
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
           }
@@ -1650,16 +1646,14 @@
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   __ Move(rcx, key->handle());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 }
 
 
 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 }
 
@@ -1765,9 +1759,9 @@
       __ movq(rdx, rax);
       __ pop(rax);  // Restore value.
       __ Move(rcx, prop->key()->AsLiteral()->handle());
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                           : Builtins::StoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->StoreIC_Initialize_Strict()
+          : isolate()->builtins()->StoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       break;
     }
@@ -1788,9 +1782,9 @@
         __ pop(rdx);
       }
       __ pop(rax);  // Restore value.
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                           : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       break;
     }
@@ -1814,9 +1808,9 @@
     // rcx, and the global object on the stack.
     __ Move(rcx, var->name());
     __ movq(rdx, GlobalObjectOperand());
-    Handle<Code> ic(isolate()->builtins()->builtin(is_strict_mode()
-        ? Builtins::StoreIC_Initialize_Strict
-        : Builtins::StoreIC_Initialize));
+    Handle<Code> ic = is_strict_mode()
+        ? isolate()->builtins()->StoreIC_Initialize_Strict()
+        : isolate()->builtins()->StoreIC_Initialize();
     EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
 
   } else if (op == Token::INIT_CONST) {
@@ -1917,9 +1911,9 @@
   } else {
     __ pop(rdx);
   }
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                       : Builtins::StoreIC_Initialize));
+  Handle<Code> ic = is_strict_mode()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 
   // If the assignment ends an initialization block, revert to fast case.
@@ -1957,9 +1951,9 @@
   }
   // Record source code position before IC call.
   SetSourcePosition(expr->position());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                       : Builtins::KeyedStoreIC_Initialize));
+  Handle<Code> ic = is_strict_mode()
+      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+      : isolate()->builtins()->KeyedStoreIC_Initialize();
   EmitCallIC(ic, RelocInfo::CODE_TARGET);
 
   // If the assignment ends an initialization block, revert to fast case.
@@ -2238,8 +2232,7 @@
         // Record source code position for IC call.
         SetSourcePosition(prop->position());
 
-        Handle<Code> ic(isolate()->builtins()->builtin(
-            Builtins::KeyedLoadIC_Initialize));
+        Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
         EmitCallIC(ic, RelocInfo::CODE_TARGET);
         // Push result (function).
         __ push(rax);
@@ -2307,8 +2300,8 @@
   __ Set(rax, arg_count);
   __ movq(rdi, Operand(rsp, arg_count * kPointerSize));
 
-  Handle<Code> construct_builtin(isolate()->builtins()->builtin(
-      Builtins::JSConstructCall));
+  Handle<Code> construct_builtin =
+      isolate()->builtins()->JSConstructCall();
   __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL);
   context()->Plug(rax);
 }
@@ -3231,7 +3224,288 @@
 
 
 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
-  context()->Plug(Heap::kUndefinedValueRootIndex);
+  Label bailout, return_result, done, one_char_separator, long_separator,
+      non_trivial_array, not_size_one_array, loop,
+      loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry;
+  ASSERT(args->length() == 2);
+  // We will leave the separator on the stack until the end of the function.
+  VisitForStackValue(args->at(1));
+  // Load this to rax (= array)
+  VisitForAccumulatorValue(args->at(0));
+  // All aliases of the same register have disjoint lifetimes.
+  Register array = rax;
+  Register elements = no_reg;  // Will be rax.
+
+  Register index = rdx;
+
+  Register string_length = rcx;
+
+  Register string = rsi;
+
+  Register scratch = rbx;
+
+  Register array_length = rdi;
+  Register result_pos = no_reg;  // Will be rdi.
+
+  Operand separator_operand =    Operand(rsp, 2 * kPointerSize);
+  Operand result_operand =       Operand(rsp, 1 * kPointerSize);
+  Operand array_length_operand = Operand(rsp, 0 * kPointerSize);
+  // Separator operand is already pushed. Make room for the two
+  // other stack fields, and clear the direction flag in anticipation
+  // of calling CopyBytes.
+  __ subq(rsp, Immediate(2 * kPointerSize));
+  __ cld();
+  // Check that the array is a JSArray
+  __ JumpIfSmi(array, &bailout);
+  __ CmpObjectType(array, JS_ARRAY_TYPE, scratch);
+  __ j(not_equal, &bailout);
+
+  // Check that the array has fast elements.
+  __ testb(FieldOperand(scratch, Map::kBitField2Offset),
+           Immediate(1 << Map::kHasFastElements));
+  __ j(zero, &bailout);
+
+  // Array has fast elements, so its length must be a smi.
+  // If the array has length zero, return the empty string.
+  __ movq(array_length, FieldOperand(array, JSArray::kLengthOffset));
+  __ SmiCompare(array_length, Smi::FromInt(0));
+  __ j(not_zero, &non_trivial_array);
+  __ LoadRoot(rax, Heap::kEmptyStringRootIndex);
+  __ jmp(&return_result);
+
+  // Save the array length on the stack.
+  __ bind(&non_trivial_array);
+  __ SmiToInteger32(array_length, array_length);
+  __ movl(array_length_operand, array_length);
+
+  // Save the FixedArray containing array's elements.
+  // End of array's live range.
+  elements = array;
+  __ movq(elements, FieldOperand(array, JSArray::kElementsOffset));
+  array = no_reg;
+
+
+  // Check that all array elements are sequential ASCII strings, and
+  // accumulate the sum of their lengths, as a smi-encoded value.
+  __ Set(index, 0);
+  __ Set(string_length, 0);
+  // Loop condition: while (index < array_length).
+  // Live loop registers: index(int32), array_length(int32), string(String*),
+  //                      scratch, string_length(int32), elements(FixedArray*).
+  if (FLAG_debug_code) {
+    __ cmpq(index, array_length);
+    __ Assert(below, "No empty arrays here in EmitFastAsciiArrayJoin");
+  }
+  __ bind(&loop);
+  __ movq(string, FieldOperand(elements,
+                               index,
+                               times_pointer_size,
+                               FixedArray::kHeaderSize));
+  __ JumpIfSmi(string, &bailout);
+  __ movq(scratch, FieldOperand(string, HeapObject::kMapOffset));
+  __ movzxbl(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
+  __ andb(scratch, Immediate(
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
+  __ cmpb(scratch, Immediate(kStringTag | kAsciiStringTag | kSeqStringTag));
+  __ j(not_equal, &bailout);
+  __ AddSmiField(string_length,
+                 FieldOperand(string, SeqAsciiString::kLengthOffset));
+  __ j(overflow, &bailout);
+  __ incl(index);
+  __ cmpl(index, array_length);
+  __ j(less, &loop);
+
+  // Live registers:
+  // string_length: Sum of string lengths.
+  // elements: FixedArray of strings.
+  // index: Array length.
+  // array_length: Array length.
+
+  // If array_length is 1, return elements[0], a string.
+  __ cmpl(array_length, Immediate(1));
+  __ j(not_equal, &not_size_one_array);
+  __ movq(rax, FieldOperand(elements, FixedArray::kHeaderSize));
+  __ jmp(&return_result);
+
+  __ bind(&not_size_one_array);
+
+  // End of array_length live range.
+  result_pos = array_length;
+  array_length = no_reg;
+
+  // Live registers:
+  // string_length: Sum of string lengths.
+  // elements: FixedArray of strings.
+  // index: Array length.
+
+  // Check that the separator is a sequential ASCII string.
+  __ movq(string, separator_operand);
+  __ JumpIfSmi(string, &bailout);
+  __ movq(scratch, FieldOperand(string, HeapObject::kMapOffset));
+  __ movzxbl(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
+  __ andb(scratch, Immediate(
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
+  __ cmpb(scratch, Immediate(kStringTag | kAsciiStringTag | kSeqStringTag));
+  __ j(not_equal, &bailout);
+
+  // Live registers:
+  // string_length: Sum of string lengths.
+  // elements: FixedArray of strings.
+  // index: Array length.
+  // string: Separator string.
+
+  // Add (separator length times (array_length - 1)) to string_length.
+  __ SmiToInteger32(scratch,
+                    FieldOperand(string, SeqAsciiString::kLengthOffset));
+  __ decl(index);
+  __ imull(scratch, index);
+  __ j(overflow, &bailout);
+  __ addl(string_length, scratch);
+  __ j(overflow, &bailout);
+
+  // Live registers and stack values:
+  //   string_length: Total length of result string.
+  //   elements: FixedArray of strings.
+  __ AllocateAsciiString(result_pos, string_length, scratch,
+                         index, string, &bailout);
+  __ movq(result_operand, result_pos);
+  __ lea(result_pos, FieldOperand(result_pos, SeqAsciiString::kHeaderSize));
+
+  __ movq(string, separator_operand);
+  __ SmiCompare(FieldOperand(string, SeqAsciiString::kLengthOffset),
+                Smi::FromInt(1));
+  __ j(equal, &one_char_separator);
+  __ j(greater, &long_separator);
+
+
+  // Empty separator case:
+  __ Set(index, 0);
+  __ movl(scratch, array_length_operand);
+  __ jmp(&loop_1_condition);
+  // Loop condition: while (index < array_length).
+  __ bind(&loop_1);
+  // Each iteration of the loop concatenates one string to the result.
+  // Live values in registers:
+  //   index: which element of the elements array we are adding to the result.
+  //   result_pos: the position to which we are currently copying characters.
+  //   elements: the FixedArray of strings we are joining.
+  //   scratch: array length.
+
+  // Get string = array[index].
+  __ movq(string, FieldOperand(elements, index,
+                               times_pointer_size,
+                               FixedArray::kHeaderSize));
+  __ SmiToInteger32(string_length,
+                    FieldOperand(string, String::kLengthOffset));
+  __ lea(string,
+         FieldOperand(string, SeqAsciiString::kHeaderSize));
+  __ CopyBytes(result_pos, string, string_length);
+  __ incl(index);
+  __ bind(&loop_1_condition);
+  __ cmpl(index, scratch);
+  __ j(less, &loop_1);  // Loop while (index < array_length).
+  __ jmp(&done);
+
+  // Generic bailout code used from several places.
+  __ bind(&bailout);
+  __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
+  __ jmp(&return_result);
+
+
+  // One-character separator case
+  __ bind(&one_char_separator);
+  // Get the separator ascii character value.
+  // Register "string" holds the separator.
+  __ movzxbl(scratch, FieldOperand(string, SeqAsciiString::kHeaderSize));
+  __ Set(index, 0);
+  // Jump into the loop after the code that copies the separator, so the first
+  // element is not preceded by a separator
+  __ jmp(&loop_2_entry);
+  // Loop condition: while (index < length).
+  __ bind(&loop_2);
+  // Each iteration of the loop concatenates one string to the result.
+  // Live values in registers:
+  //   elements: The FixedArray of strings we are joining.
+  //   index: which element of the elements array we are adding to the result.
+  //   result_pos: the position to which we are currently copying characters.
+  //   scratch: Separator character.
+
+  // Copy the separator character to the result.
+  __ movb(Operand(result_pos, 0), scratch);
+  __ incq(result_pos);
+
+  __ bind(&loop_2_entry);
+  // Get string = array[index].
+  __ movq(string, FieldOperand(elements, index,
+                               times_pointer_size,
+                               FixedArray::kHeaderSize));
+  __ SmiToInteger32(string_length,
+                    FieldOperand(string, String::kLengthOffset));
+  __ lea(string,
+         FieldOperand(string, SeqAsciiString::kHeaderSize));
+  __ CopyBytes(result_pos, string, string_length);
+  __ incl(index);
+  __ cmpl(index, array_length_operand);
+  __ j(less, &loop_2);  // End while (index < length).
+  __ jmp(&done);
+
+
+  // Long separator case (separator is more than one character).
+  __ bind(&long_separator);
+
+  // Make elements point to end of elements array, and index
+  // count from -array_length to zero, so we don't need to maintain
+  // a loop limit.
+  __ movl(index, array_length_operand);
+  __ lea(elements, FieldOperand(elements, index, times_pointer_size,
+                                FixedArray::kHeaderSize));
+  __ neg(index);
+
+  // Replace separator string with pointer to its first character, and
+  // make scratch be its length.
+  __ movq(string, separator_operand);
+  __ SmiToInteger32(scratch,
+                    FieldOperand(string, String::kLengthOffset));
+  __ lea(string,
+         FieldOperand(string, SeqAsciiString::kHeaderSize));
+  __ movq(separator_operand, string);
+
+  // Jump into the loop after the code that copies the separator, so the first
+  // element is not preceded by a separator
+  __ jmp(&loop_3_entry);
+  // Loop condition: while (index < length).
+  __ bind(&loop_3);
+  // Each iteration of the loop concatenates one string to the result.
+  // Live values in registers:
+  //   index: which element of the elements array we are adding to the result.
+  //   result_pos: the position to which we are currently copying characters.
+  //   scratch: Separator length.
+  //   separator_operand (rsp[0x10]): Address of first char of separator.
+
+  // Copy the separator to the result.
+  __ movq(string, separator_operand);
+  __ movl(string_length, scratch);
+  __ CopyBytes(result_pos, string, string_length, 2);
+
+  __ bind(&loop_3_entry);
+  // Get string = array[index].
+  __ movq(string, Operand(elements, index, times_pointer_size, 0));
+  __ SmiToInteger32(string_length,
+                    FieldOperand(string, String::kLengthOffset));
+  __ lea(string,
+         FieldOperand(string, SeqAsciiString::kHeaderSize));
+  __ CopyBytes(result_pos, string, string_length);
+  __ incq(index);
+  __ j(not_equal, &loop_3);  // Loop while (index < 0).
+
+  __ bind(&done);
+  __ movq(rax, result_operand);
+
+  __ bind(&return_result);
+  // Drop temp values from the stack, and restore context register.
+  __ addq(rsp, Immediate(3 * kPointerSize));
+  __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
+  context()->Plug(rax);
 }
 
 
@@ -3575,9 +3849,9 @@
     case NAMED_PROPERTY: {
       __ Move(rcx, prop->key()->AsLiteral()->handle());
       __ pop(rdx);
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::StoreIC_Initialize_Strict
-                           : Builtins::StoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->StoreIC_Initialize_Strict()
+          : isolate()->builtins()->StoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
@@ -3592,9 +3866,9 @@
     case KEYED_PROPERTY: {
       __ pop(rcx);
       __ pop(rdx);
-      Handle<Code> ic(isolate()->builtins()->builtin(
-          is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict
-                           : Builtins::KeyedStoreIC_Initialize));
+      Handle<Code> ic = is_strict_mode()
+          ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+          : isolate()->builtins()->KeyedStoreIC_Initialize();
       EmitCallIC(ic, RelocInfo::CODE_TARGET);
       PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
       if (expr->is_postfix()) {
@@ -3619,8 +3893,7 @@
     Comment cmnt(masm_, "Global variable");
     __ Move(rcx, proxy->name());
     __ movq(rax, GlobalObjectOperand());
-    Handle<Code> ic(isolate()->builtins()->builtin(
-        Builtins::LoadIC_Initialize));
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
     EmitCallIC(ic, RelocInfo::CODE_TARGET);
@@ -3884,18 +4157,19 @@
 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
   ASSERT(mode == RelocInfo::CODE_TARGET ||
          mode == RelocInfo::CODE_TARGET_CONTEXT);
+  Counters* counters = isolate()->counters();
   switch (ic->kind()) {
     case Code::LOAD_IC:
-      __ IncrementCounter(COUNTERS->named_load_full(), 1);
+      __ IncrementCounter(counters->named_load_full(), 1);
       break;
     case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
+      __ IncrementCounter(counters->keyed_load_full(), 1);
       break;
     case Code::STORE_IC:
-      __ IncrementCounter(COUNTERS->named_store_full(), 1);
+      __ IncrementCounter(counters->named_store_full(), 1);
       break;
     case Code::KEYED_STORE_IC:
-      __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
+      __ IncrementCounter(counters->keyed_store_full(), 1);
     default:
       break;
   }
@@ -3927,18 +4201,19 @@
 
 
 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
+  Counters* counters = isolate()->counters();
   switch (ic->kind()) {
     case Code::LOAD_IC:
-      __ IncrementCounter(COUNTERS->named_load_full(), 1);
+      __ IncrementCounter(counters->named_load_full(), 1);
       break;
     case Code::KEYED_LOAD_IC:
-      __ IncrementCounter(COUNTERS->keyed_load_full(), 1);
+      __ IncrementCounter(counters->keyed_load_full(), 1);
       break;
     case Code::STORE_IC:
-      __ IncrementCounter(COUNTERS->named_store_full(), 1);
+      __ IncrementCounter(counters->named_store_full(), 1);
       break;
     case Code::KEYED_STORE_IC:
-      __ IncrementCounter(COUNTERS->keyed_store_full(), 1);
+      __ IncrementCounter(counters->keyed_store_full(), 1);
     default:
       break;
   }
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 7755493..9180465 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -579,7 +579,8 @@
                         rax,
                         NULL,
                         &slow);
-  __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
   __ ret(0);
 
   __ bind(&check_number_dictionary);
@@ -601,7 +602,7 @@
   // Slow case: Jump to runtime.
   // rdx: receiver
   // rax: key
-  __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
   GenerateRuntimeGetProperty(masm);
 
   __ bind(&check_string);
@@ -652,7 +653,7 @@
   __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
   __ addq(rcx, rdi);
   __ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0));
-  __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
   __ ret(0);
 
   // Load property array property.
@@ -660,7 +661,7 @@
   __ movq(rax, FieldOperand(rdx, JSObject::kPropertiesOffset));
   __ movq(rax, FieldOperand(rax, rdi, times_pointer_size,
                             FixedArray::kHeaderSize));
-  __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
   __ ret(0);
 
   // Do a quick inline probe of the receiver's dictionary, if it
@@ -675,7 +676,7 @@
   GenerateGlobalInstanceTypeCheck(masm, rcx, &slow);
 
   GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax);
-  __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1);
+  __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
   __ ret(0);
 
   __ bind(&index_string);
@@ -990,10 +991,11 @@
   // rsp[(argc + 1) * 8]      : argument 0 = receiver
   // -----------------------------------
 
+  Counters* counters = masm->isolate()->counters();
   if (id == IC::kCallIC_Miss) {
-    __ IncrementCounter(COUNTERS->call_miss(), 1);
+    __ IncrementCounter(counters->call_miss(), 1);
   } else {
-    __ IncrementCounter(COUNTERS->keyed_call_miss(), 1);
+    __ IncrementCounter(counters->keyed_call_miss(), 1);
   }
 
   // Get the receiver of the function from the stack; 1 ~ return address.
@@ -1119,7 +1121,8 @@
 
   GenerateFastArrayLoad(
       masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1);
 
   __ bind(&do_call);
   // receiver in rdx is not used after this point.
@@ -1137,13 +1140,13 @@
   __ SmiToInteger32(rbx, rcx);
   // ebx: untagged index
   GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
   __ jmp(&do_call);
 
   __ bind(&slow_load);
   // This branch is taken when calling KeyedCallIC_Miss is neither required
   // nor beneficial.
-  __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
   __ EnterInternalFrame();
   __ push(rcx);  // save the key
   __ push(rdx);  // pass the receiver
@@ -1170,11 +1173,11 @@
   __ j(not_equal, &lookup_monomorphic_cache);
 
   GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
   __ jmp(&do_call);
 
   __ bind(&lookup_monomorphic_cache);
-  __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
   GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC);
   // Fall through on miss.
 
@@ -1185,7 +1188,7 @@
   // - the value loaded is not a function,
   // - there is hope that the runtime will create a monomorphic call stub
   //   that will get fetched next time.
-  __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1);
+  __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
   GenerateMiss(masm, argc);
 
   __ bind(&index_string);
@@ -1279,7 +1282,8 @@
   //  -- rsp[0] : return address
   // -----------------------------------
 
-  __ IncrementCounter(COUNTERS->load_miss(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->load_miss(), 1);
 
   __ pop(rbx);
   __ push(rax);  // receiver
@@ -1424,7 +1428,8 @@
   //  -- rsp[0]  : return address
   // -----------------------------------
 
-  __ IncrementCounter(COUNTERS->keyed_load_miss(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_miss(), 1);
 
   __ pop(rbx);
   __ push(rdx);  // receiver
@@ -1569,11 +1574,12 @@
   GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
 
   GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
-  __ IncrementCounter(COUNTERS->store_normal_hit(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->store_normal_hit(), 1);
   __ ret(0);
 
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->store_normal_miss(), 1);
+  __ IncrementCounter(counters->store_normal_miss(), 1);
   GenerateMiss(masm);
 }
 
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 5af2795..a3609fd 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -43,12 +43,10 @@
  public:
   SafepointGenerator(LCodeGen* codegen,
                      LPointerMap* pointers,
-                     int deoptimization_index,
-                     bool ensure_reloc_space = false)
+                     int deoptimization_index)
       : codegen_(codegen),
         pointers_(pointers),
-        deoptimization_index_(deoptimization_index),
-        ensure_reloc_space_(ensure_reloc_space) { }
+        deoptimization_index_(deoptimization_index) { }
   virtual ~SafepointGenerator() { }
 
   virtual void BeforeCall(int call_size) {
@@ -67,9 +65,7 @@
   virtual void AfterCall() {
     // Ensure that we have enough space in the reloc info to patch
     // this with calls when doing deoptimization.
-    if (ensure_reloc_space_) {
-      codegen_->masm()->RecordComment(RelocInfo::kFillerCommentString, true);
-    }
+    codegen_->masm()->RecordComment(RelocInfo::kFillerCommentString, true);
     codegen_->RecordSafepoint(pointers_, deoptimization_index_);
   }
 
@@ -79,7 +75,6 @@
   LCodeGen* codegen_;
   LPointerMap* pointers_;
   int deoptimization_index_;
-  bool ensure_reloc_space_;
 };
 
 
@@ -102,6 +97,7 @@
   code->set_stack_slots(StackSlotCount());
   code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
   PopulateDeoptimizationData(code);
+  Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
 }
 
 
@@ -2096,12 +2092,76 @@
 }
 
 
+void LCodeGen::EmitLoadField(Register result,
+                             Register object,
+                             Handle<Map> type,
+                             Handle<String> name) {
+  LookupResult lookup;
+  type->LookupInDescriptors(NULL, *name, &lookup);
+  ASSERT(lookup.IsProperty() && lookup.type() == FIELD);
+  int index = lookup.GetLocalFieldIndexFromMap(*type);
+  int offset = index * kPointerSize;
+  if (index < 0) {
+    // Negative property indices are in-object properties, indexed
+    // from the end of the fixed part of the object.
+    __ movq(result, FieldOperand(object, offset + type->instance_size()));
+  } else {
+    // Non-negative property indices are in the properties array.
+    __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
+    __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
+  }
+}
+
+
+void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
+  Register object = ToRegister(instr->object());
+  Register result = ToRegister(instr->result());
+
+  int map_count = instr->hydrogen()->types()->length();
+  Handle<String> name = instr->hydrogen()->name();
+
+  if (map_count == 0) {
+    ASSERT(instr->hydrogen()->need_generic());
+    __ Move(rcx, instr->hydrogen()->name());
+    Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+    CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  } else {
+    NearLabel done;
+    for (int i = 0; i < map_count - 1; ++i) {
+      Handle<Map> map = instr->hydrogen()->types()->at(i);
+      NearLabel next;
+      __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+      __ j(not_equal, &next);
+      EmitLoadField(result, object, map, name);
+      __ jmp(&done);
+      __ bind(&next);
+    }
+    Handle<Map> map = instr->hydrogen()->types()->last();
+    __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map);
+    if (instr->hydrogen()->need_generic()) {
+      NearLabel generic;
+      __ j(not_equal, &generic);
+      EmitLoadField(result, object, map, name);
+      __ jmp(&done);
+      __ bind(&generic);
+      __ Move(rcx, instr->hydrogen()->name());
+      Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+      CallCode(ic, RelocInfo::CODE_TARGET, instr);
+    } else {
+      DeoptimizeIf(not_equal, instr->environment());
+      EmitLoadField(result, object, map, name);
+    }
+    __ bind(&done);
+  }
+}
+
+
 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
   ASSERT(ToRegister(instr->object()).is(rax));
   ASSERT(ToRegister(instr->result()).is(rax));
 
   __ Move(rcx, instr->name());
-  Handle<Code> ic(isolate()->builtins()->builtin(Builtins::LoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2157,11 +2217,16 @@
                    Heap::kFixedArrayMapRootIndex);
     __ j(equal, &done);
     __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
-                   Heap::kExternalPixelArrayMapRootIndex);
-    __ j(equal, &done);
-    __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
                    Heap::kFixedCOWArrayMapRootIndex);
-    __ Check(equal, "Check for fast elements failed.");
+    __ j(equal, &done);
+    Register temp((result.is(rax)) ? rbx : rax);
+    __ push(temp);
+    __ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
+    __ movzxbq(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
+    __ subq(temp, Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
+    __ cmpq(temp, Immediate(kExternalArrayTypeCount));
+    __ pop(temp);
+    __ Check(below, "Check for fast elements failed.");
     __ bind(&done);
   }
 }
@@ -2212,14 +2277,47 @@
 }
 
 
-void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
-  Register external_elements = ToRegister(instr->external_pointer());
+void LCodeGen::DoLoadKeyedSpecializedArrayElement(
+    LLoadKeyedSpecializedArrayElement* instr) {
+  Register external_pointer = ToRegister(instr->external_pointer());
   Register key = ToRegister(instr->key());
-  Register result = ToRegister(instr->result());
-  ASSERT(result.is(external_elements));
-
-  // Load the result.
-  __ movzxbq(result, Operand(external_elements, key, times_1, 0));
+  ExternalArrayType array_type = instr->array_type();
+  if (array_type == kExternalFloatArray) {
+    XMMRegister result(ToDoubleRegister(instr->result()));
+    __ movss(result, Operand(external_pointer, key, times_4, 0));
+    __ cvtss2sd(result, result);
+  } else {
+    Register result(ToRegister(instr->result()));
+    switch (array_type) {
+      case kExternalByteArray:
+        __ movsxbq(result, Operand(external_pointer, key, times_1, 0));
+        break;
+      case kExternalUnsignedByteArray:
+      case kExternalPixelArray:
+        __ movzxbq(result, Operand(external_pointer, key, times_1, 0));
+        break;
+      case kExternalShortArray:
+        __ movsxwq(result, Operand(external_pointer, key, times_2, 0));
+        break;
+      case kExternalUnsignedShortArray:
+        __ movzxwq(result, Operand(external_pointer, key, times_2, 0));
+        break;
+      case kExternalIntArray:
+        __ movsxlq(result, Operand(external_pointer, key, times_4, 0));
+        break;
+      case kExternalUnsignedIntArray:
+        __ movl(result, Operand(external_pointer, key, times_4, 0));
+        __ testl(result, result);
+        // TODO(danno): we could be more clever here, perhaps having a special
+        // version of the stub that detects if the overflow case actually
+        // happens, and generate code that returns a double rather than int.
+        DeoptimizeIf(negative, instr->environment());
+        break;
+      case kExternalFloatArray:
+        UNREACHABLE();
+        break;
+    }
+  }
 }
 
 
@@ -2227,8 +2325,7 @@
   ASSERT(ToRegister(instr->object()).is(rdx));
   ASSERT(ToRegister(instr->key()).is(rax));
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2343,8 +2440,7 @@
   RegisterEnvironmentForDeoptimization(env);
   SafepointGenerator safepoint_generator(this,
                                          pointers,
-                                         env->deoptimization_index(),
-                                         true);
+                                         env->deoptimization_index());
   v8::internal::ParameterCount actual(rax);
   __ InvokeFunction(function, actual, CALL_FUNCTION, &safepoint_generator);
 }
@@ -2782,8 +2878,7 @@
   ASSERT(ToRegister(instr->InputAt(0)).is(rdi));
   ASSERT(ToRegister(instr->result()).is(rax));
 
-  Handle<Code> builtin(isolate()->builtins()->builtin(
-      Builtins::JSConstructCall));
+  Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
   __ Set(rax, instr->arity());
   CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
 }
@@ -2829,28 +2924,53 @@
   ASSERT(ToRegister(instr->value()).is(rax));
 
   __ Move(rcx, instr->hydrogen()->name());
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      info_->is_strict() ? Builtins::StoreIC_Initialize_Strict
-                         : Builtins::StoreIC_Initialize));
+  Handle<Code> ic = info_->is_strict()
+      ? isolate()->builtins()->StoreIC_Initialize_Strict()
+      : isolate()->builtins()->StoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
 
-void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) {
+void LCodeGen::DoStoreKeyedSpecializedArrayElement(
+    LStoreKeyedSpecializedArrayElement* instr) {
   Register external_pointer = ToRegister(instr->external_pointer());
   Register key = ToRegister(instr->key());
-  Register value = ToRegister(instr->value());
-
-  {  // Clamp the value to [0..255].
-    NearLabel done;
-    __ testl(value, Immediate(0xFFFFFF00));
-    __ j(zero, &done);
-    __ setcc(negative, value);  // 1 if negative, 0 if positive.
-    __ decb(value);  // 0 if negative, 255 if positive.
-    __ bind(&done);
+  ExternalArrayType array_type = instr->array_type();
+  if (array_type == kExternalFloatArray) {
+    XMMRegister value(ToDoubleRegister(instr->value()));
+    __ cvtsd2ss(value, value);
+    __ movss(Operand(external_pointer, key, times_4, 0), value);
+  } else {
+    Register value(ToRegister(instr->value()));
+    switch (array_type) {
+      case kExternalPixelArray:
+        {  // Clamp the value to [0..255].
+          NearLabel done;
+          __ testl(value, Immediate(0xFFFFFF00));
+          __ j(zero, &done);
+          __ setcc(negative, value);  // 1 if negative, 0 if positive.
+          __ decb(value);  // 0 if negative, 255 if positive.
+          __ bind(&done);
+          __ movb(Operand(external_pointer, key, times_1, 0), value);
+        }
+        break;
+      case kExternalByteArray:
+      case kExternalUnsignedByteArray:
+        __ movb(Operand(external_pointer, key, times_1, 0), value);
+        break;
+      case kExternalShortArray:
+      case kExternalUnsignedShortArray:
+        __ movw(Operand(external_pointer, key, times_2, 0), value);
+        break;
+      case kExternalIntArray:
+      case kExternalUnsignedIntArray:
+        __ movl(Operand(external_pointer, key, times_4, 0), value);
+        break;
+      case kExternalFloatArray:
+        UNREACHABLE();
+        break;
+    }
   }
-
-  __ movb(Operand(external_pointer, key, times_1, 0), value);
 }
 
 
@@ -2900,9 +3020,9 @@
   ASSERT(ToRegister(instr->key()).is(rcx));
   ASSERT(ToRegister(instr->value()).is(rax));
 
-  Handle<Code> ic(isolate()->builtins()->builtin(
-      info_->is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict
-                         : Builtins::KeyedStoreIC_Initialize));
+  Handle<Code> ic = info_->is_strict()
+      ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
+      : isolate()->builtins()->KeyedStoreIC_Initialize();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3791,8 +3911,7 @@
   // builtin)
   SafepointGenerator safepoint_generator(this,
                                          pointers,
-                                         env->deoptimization_index(),
-                                         true);
+                                         env->deoptimization_index());
   __ Push(Smi::FromInt(strict_mode_flag()));
   __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, &safepoint_generator);
 }
diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h
index fcd0a70..f44fdb9 100644
--- a/src/x64/lithium-codegen-x64.h
+++ b/src/x64/lithium-codegen-x64.h
@@ -241,6 +241,11 @@
   // Caller should branch on equal condition.
   void EmitIsConstructCall(Register temp);
 
+  void EmitLoadField(Register result,
+                     Register object,
+                     Handle<Map> type,
+                     Handle<String> name);
+
   // Emits code for pushing a constant operand.
   void EmitPushConstantOperand(LOperand* operand);
 
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 09b7b63..c47cd72 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1763,6 +1763,21 @@
 }
 
 
+LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
+    HLoadNamedFieldPolymorphic* instr) {
+  ASSERT(instr->representation().IsTagged());
+  if (instr->need_generic()) {
+    LOperand* obj = UseFixed(instr->object(), rax);
+    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    return MarkAsCall(DefineFixed(result, rax), instr);
+  } else {
+    LOperand* obj = UseRegisterAtStart(instr->object());
+    LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj);
+    return AssignEnvironment(DefineAsRegister(result));
+  }
+}
+
+
 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
   LOperand* object = UseFixed(instr->object(), rax);
   LLoadNamedGeneric* result = new LLoadNamedGeneric(object);
@@ -1801,16 +1816,22 @@
 }
 
 
-LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
-    HLoadPixelArrayElement* instr) {
-  ASSERT(instr->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
+    HLoadKeyedSpecializedArrayElement* instr) {
+  ExternalArrayType array_type = instr->array_type();
+  Representation representation(instr->representation());
+  ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+         (representation.IsDouble() && array_type == kExternalFloatArray));
   ASSERT(instr->key()->representation().IsInteger32());
-  LOperand* external_pointer =
-      UseRegisterAtStart(instr->external_pointer());
-  LOperand* key = UseRegisterAtStart(instr->key());
-  LLoadPixelArrayElement* result =
-      new LLoadPixelArrayElement(external_pointer, key);
-  return DefineSameAsFirst(result);
+  LOperand* external_pointer = UseRegister(instr->external_pointer());
+  LOperand* key = UseRegister(instr->key());
+  LLoadKeyedSpecializedArrayElement* result =
+      new LLoadKeyedSpecializedArrayElement(external_pointer, key);
+  LInstruction* load_instr = DefineAsRegister(result);
+  // An unsigned int array load might overflow and cause a deopt, make sure it
+  // has an environment.
+  return (array_type == kExternalUnsignedIntArray) ?
+      AssignEnvironment(load_instr) : load_instr;
 }
 
 
@@ -1842,17 +1863,26 @@
 }
 
 
-LInstruction* LChunkBuilder::DoStorePixelArrayElement(
-    HStorePixelArrayElement* instr) {
-  ASSERT(instr->value()->representation().IsInteger32());
+LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
+    HStoreKeyedSpecializedArrayElement* instr) {
+  Representation representation(instr->value()->representation());
+  ExternalArrayType array_type = instr->array_type();
+  ASSERT((representation.IsInteger32() && array_type != kExternalFloatArray) ||
+         (representation.IsDouble() && array_type == kExternalFloatArray));
   ASSERT(instr->external_pointer()->representation().IsExternal());
   ASSERT(instr->key()->representation().IsInteger32());
 
   LOperand* external_pointer = UseRegister(instr->external_pointer());
-  LOperand* val = UseTempRegister(instr->value());
+  bool val_is_temp_register = array_type == kExternalPixelArray ||
+      array_type == kExternalFloatArray;
+  LOperand* val = val_is_temp_register
+      ? UseTempRegister(instr->value())
+      : UseRegister(instr->key());
   LOperand* key = UseRegister(instr->key());
 
-  return new LStorePixelArrayElement(external_pointer, key, val);
+  return new LStoreKeyedSpecializedArrayElement(external_pointer,
+                                                key,
+                                                val);
 }
 
 
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index f5c3ddd..e94debf 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -121,10 +121,11 @@
   V(LoadGlobal)                                 \
   V(LoadKeyedFastElement)                       \
   V(LoadKeyedGeneric)                           \
+  V(LoadKeyedSpecializedArrayElement)           \
   V(LoadNamedField)                             \
+  V(LoadNamedFieldPolymorphic)                  \
   V(LoadNamedGeneric)                           \
   V(LoadFunctionPrototype)                      \
-  V(LoadPixelArrayElement)                      \
   V(ModI)                                       \
   V(MulI)                                       \
   V(NumberTagD)                                 \
@@ -146,9 +147,9 @@
   V(StoreGlobal)                                \
   V(StoreKeyedFastElement)                      \
   V(StoreKeyedGeneric)                          \
+  V(StoreKeyedSpecializedArrayElement)          \
   V(StoreNamedField)                            \
   V(StoreNamedGeneric)                          \
-  V(StorePixelArrayElement)                     \
   V(StringCharCodeAt)                           \
   V(StringCharFromCode)                         \
   V(StringLength)                               \
@@ -1134,6 +1135,19 @@
 };
 
 
+class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LLoadNamedFieldPolymorphic(LOperand* object) {
+    inputs_[0] = object;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic")
+  DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic)
+
+  LOperand* object() { return inputs_[0]; }
+};
+
+
 class LLoadNamedGeneric: public LTemplateInstruction<1, 1, 0> {
  public:
   explicit LLoadNamedGeneric(LOperand* object) {
@@ -1197,19 +1211,23 @@
 };
 
 
-class LLoadPixelArrayElement: public LTemplateInstruction<1, 2, 0> {
+class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
  public:
-  LLoadPixelArrayElement(LOperand* external_pointer, LOperand* key) {
+  LLoadKeyedSpecializedArrayElement(LOperand* external_pointer,
+                                    LOperand* key) {
     inputs_[0] = external_pointer;
     inputs_[1] = key;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
-                               "load-pixel-array-element")
-  DECLARE_HYDROGEN_ACCESSOR(LoadPixelArrayElement)
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement,
+                               "load-keyed-specialized-array-element")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedSpecializedArrayElement)
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
+  ExternalArrayType array_type() const {
+    return hydrogen()->array_type();
+  }
 };
 
 
@@ -1587,23 +1605,26 @@
 };
 
 
-class LStorePixelArrayElement: public LTemplateInstruction<0, 3, 0> {
+class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
  public:
-  LStorePixelArrayElement(LOperand* external_pointer,
-                          LOperand* key,
-                          LOperand* val) {
+  LStoreKeyedSpecializedArrayElement(LOperand* external_pointer,
+                                     LOperand* key,
+                                     LOperand* val) {
     inputs_[0] = external_pointer;
     inputs_[1] = key;
     inputs_[2] = val;
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
-                               "store-pixel-array-element")
-  DECLARE_HYDROGEN_ACCESSOR(StorePixelArrayElement)
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
+                               "store-keyed-specialized-array-element")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedSpecializedArrayElement)
 
   LOperand* external_pointer() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
   LOperand* value() { return inputs_[2]; }
+  ExternalArrayType array_type() const {
+    return hydrogen()->array_type();
+  }
 };
 
 
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index b73f5d1..654814c 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -45,13 +45,13 @@
       generating_stub_(false),
       allow_stub_calls_(true),
       root_array_available_(true),
-      code_object_(HEAP->undefined_value()) {
+      code_object_(isolate()->heap()->undefined_value()) {
 }
 
 
-static intptr_t RootRegisterDelta(ExternalReference other) {
+static intptr_t RootRegisterDelta(ExternalReference other, Isolate* isolate) {
   Address roots_register_value = kRootRegisterBias +
-      reinterpret_cast<Address>(Isolate::Current()->heap()->roots_address());
+      reinterpret_cast<Address>(isolate->heap()->roots_address());
   intptr_t delta = other.address() - roots_register_value;
   return delta;
 }
@@ -60,10 +60,10 @@
 Operand MacroAssembler::ExternalOperand(ExternalReference target,
                                         Register scratch) {
   if (root_array_available_ && !Serializer::enabled()) {
-    intptr_t delta = RootRegisterDelta(target);
+    intptr_t delta = RootRegisterDelta(target, isolate());
     if (is_int32(delta)) {
       Serializer::TooLateToEnableNow();
-      return Operand(kRootRegister, delta);
+      return Operand(kRootRegister, static_cast<int32_t>(delta));
     }
   }
   movq(scratch, target);
@@ -73,7 +73,7 @@
 
 void MacroAssembler::Load(Register destination, ExternalReference source) {
   if (root_array_available_ && !Serializer::enabled()) {
-    intptr_t delta = RootRegisterDelta(source);
+    intptr_t delta = RootRegisterDelta(source, isolate());
     if (is_int32(delta)) {
       Serializer::TooLateToEnableNow();
       movq(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
@@ -92,7 +92,7 @@
 
 void MacroAssembler::Store(ExternalReference destination, Register source) {
   if (root_array_available_ && !Serializer::enabled()) {
-    intptr_t delta = RootRegisterDelta(destination);
+    intptr_t delta = RootRegisterDelta(destination, isolate());
     if (is_int32(delta)) {
       Serializer::TooLateToEnableNow();
       movq(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
@@ -112,7 +112,7 @@
 void MacroAssembler::LoadAddress(Register destination,
                                  ExternalReference source) {
   if (root_array_available_ && !Serializer::enabled()) {
-    intptr_t delta = RootRegisterDelta(source);
+    intptr_t delta = RootRegisterDelta(source, isolate());
     if (is_int32(delta)) {
       Serializer::TooLateToEnableNow();
       lea(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
@@ -129,7 +129,7 @@
     // This calculation depends on the internals of LoadAddress.
     // It's correctness is ensured by the asserts in the Call
     // instruction below.
-    intptr_t delta = RootRegisterDelta(source);
+    intptr_t delta = RootRegisterDelta(source, isolate());
     if (is_int32(delta)) {
       Serializer::TooLateToEnableNow();
       // Operand is lea(scratch, Operand(kRootRegister, delta));
@@ -909,9 +909,9 @@
                                                 Register src,
                                                 int constant) {
   if (dst.is(src)) {
-    addq(dst, Immediate(constant));
+    addl(dst, Immediate(constant));
   } else {
-    lea(dst, Operand(src, constant));
+    leal(dst, Operand(src, constant));
   }
   shl(dst, Immediate(kSmiShift));
 }
@@ -1245,12 +1245,10 @@
   // No overflow checking. Use only when it's known that
   // overflowing is impossible.
   ASSERT(!dst.is(src2));
-  if (dst.is(src1)) {
-    addq(dst, src2);
-  } else {
+  if (!dst.is(src1)) {
     movq(dst, src1);
-    addq(dst, src2);
   }
+  addq(dst, src2);
   Assert(no_overflow, "Smi addition overflow");
 }
 
@@ -1259,12 +1257,10 @@
   // No overflow checking. Use only when it's known that
   // overflowing is impossible (e.g., subtracting two positive smis).
   ASSERT(!dst.is(src2));
-  if (dst.is(src1)) {
-    subq(dst, src2);
-  } else {
+  if (!dst.is(src1)) {
     movq(dst, src1);
-    subq(dst, src2);
   }
+  subq(dst, src2);
   Assert(no_overflow, "Smi subtraction overflow");
 }
 
@@ -1274,12 +1270,10 @@
                             const Operand& src2) {
   // No overflow checking. Use only when it's known that
   // overflowing is impossible (e.g., subtracting two positive smis).
-  if (dst.is(src1)) {
-    subq(dst, src2);
-  } else {
+  if (!dst.is(src1)) {
     movq(dst, src1);
-    subq(dst, src2);
   }
+  subq(dst, src2);
   Assert(no_overflow, "Smi subtraction overflow");
 }
 
@@ -1466,6 +1460,13 @@
 }
 
 
+void MacroAssembler::AddSmiField(Register dst, const Operand& src) {
+  ASSERT_EQ(0, kSmiShift % kBitsPerByte);
+  addl(dst, Operand(src, kSmiShift / kBitsPerByte));
+}
+
+
+
 void MacroAssembler::Move(Register dst, Register src) {
   if (!dst.is(src)) {
     movq(dst, src);
@@ -2701,6 +2702,70 @@
 }
 
 
+// Copy memory, byte-by-byte, from source to destination.  Not optimized for
+// long or aligned copies.  The contents of scratch and length are destroyed.
+// Destination is incremented by length, source, length and scratch are
+// clobbered.
+// A simpler loop is faster on small copies, but slower on large ones.
+// The cld() instruction must have been emitted, to set the direction flag(),
+// before calling this function.
+void MacroAssembler::CopyBytes(Register destination,
+                               Register source,
+                               Register length,
+                               int min_length,
+                               Register scratch) {
+  ASSERT(min_length >= 0);
+  if (FLAG_debug_code) {
+    cmpl(length, Immediate(min_length));
+    Assert(greater_equal, "Invalid min_length");
+  }
+  Label loop, done, short_string, short_loop;
+
+  const int kLongStringLimit = 20;
+  if (min_length <= kLongStringLimit) {
+    cmpl(length, Immediate(kLongStringLimit));
+    j(less_equal, &short_string);
+  }
+
+  ASSERT(source.is(rsi));
+  ASSERT(destination.is(rdi));
+  ASSERT(length.is(rcx));
+
+  // Because source is 8-byte aligned in our uses of this function,
+  // we keep source aligned for the rep movs operation by copying the odd bytes
+  // at the end of the ranges.
+  movq(scratch, length);
+  shrl(length, Immediate(3));
+  repmovsq();
+  // Move remaining bytes of length.
+  andl(scratch, Immediate(0x7));
+  movq(length, Operand(source, scratch, times_1, -8));
+  movq(Operand(destination, scratch, times_1, -8), length);
+  addq(destination, scratch);
+
+  if (min_length <= kLongStringLimit) {
+    jmp(&done);
+
+    bind(&short_string);
+    if (min_length == 0) {
+      testl(length, length);
+      j(zero, &done);
+    }
+    lea(scratch, Operand(destination, length, times_1, 0));
+
+    bind(&short_loop);
+    movb(length, Operand(source, 0));
+    movb(Operand(destination, 0), length);
+    incq(source);
+    incq(destination);
+    cmpq(destination, scratch);
+    j(not_equal, &short_loop);
+
+    bind(&done);
+  }
+}
+
+
 void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
   if (context_chain_length > 0) {
     // Move up the chain of contexts to the context containing the slot.
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index eb1f42d..1ee0fe0 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -470,6 +470,11 @@
               Register src1,
               Register src2,
               LabelType* on_not_smi_result);
+  template <typename LabelType>
+  void SmiAdd(Register dst,
+              Register src1,
+              const Operand& src2,
+              LabelType* on_not_smi_result);
 
   void SmiAdd(Register dst,
               Register src1,
@@ -590,6 +595,10 @@
   // Converts a positive smi to a negative index.
   SmiIndex SmiToNegativeIndex(Register dst, Register src, int shift);
 
+  // Add the value of a smi in memory to an int32 register.
+  // Sets flags as a normal add.
+  void AddSmiField(Register dst, const Operand& src);
+
   // Basic Smi operations.
   void Move(Register dst, Smi* source) {
     LoadSmiConstant(dst, source);
@@ -1022,6 +1031,18 @@
 
   Handle<Object> CodeObject() { return code_object_; }
 
+  // Copy length bytes from source to destination.
+  // Uses scratch register internally (if you have a low-eight register
+  // free, do use it, otherwise kScratchRegister will be used).
+  // The min_length is a minimum limit on the value that length will have.
+  // The algorithm has some special cases that might be omitted if the string
+  // is known to always be long.
+  void CopyBytes(Register destination,
+                 Register source,
+                 Register length,
+                 int min_length = 0,
+                 Register scratch = kScratchRegister);
+
 
   // ---------------------------------------------------------------------------
   // StatsCounter support
@@ -1273,6 +1294,26 @@
 
 
 template <typename LabelType>
+void MacroAssembler::SmiAdd(Register dst,
+                            Register src1,
+                            const Operand& src2,
+                            LabelType* on_not_smi_result) {
+  ASSERT_NOT_NULL(on_not_smi_result);
+  if (dst.is(src1)) {
+    movq(kScratchRegister, src1);
+    addq(kScratchRegister, src2);
+    j(overflow, on_not_smi_result);
+    movq(dst, kScratchRegister);
+  } else {
+    ASSERT(!src2.AddressUsesRegister(dst));
+    movq(dst, src1);
+    addq(dst, src2);
+    j(overflow, on_not_smi_result);
+  }
+}
+
+
+template <typename LabelType>
 void MacroAssembler::SmiSub(Register dst,
                             Register src1,
                             Register src2,
@@ -1910,9 +1951,7 @@
   }
 
   if (!definitely_matches) {
-    Handle<Code> adaptor =
-        Handle<Code>(Isolate::Current()->builtins()->builtin(
-            Builtins::ArgumentsAdaptorTrampoline));
+    Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
     if (!code_constant.is_null()) {
       movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT);
       addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index ac2a305..403a1dc 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -89,8 +89,9 @@
                                              Register r0,
                                              Register r1) {
   ASSERT(name->IsSymbol());
-  __ IncrementCounter(COUNTERS->negative_lookups(), 1);
-  __ IncrementCounter(COUNTERS->negative_lookups_miss(), 1);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->negative_lookups(), 1);
+  __ IncrementCounter(counters->negative_lookups_miss(), 1);
 
   Label done;
   __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset));
@@ -173,7 +174,7 @@
   }
 
   __ bind(&done);
-  __ DecrementCounter(COUNTERS->negative_lookups_miss(), 1);
+  __ DecrementCounter(counters->negative_lookups_miss(), 1);
 }
 
 
@@ -184,7 +185,7 @@
                               Register scratch,
                               Register extra,
                               Register extra2) {
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = masm->isolate();
   Label miss;
   USE(extra);   // The register extra is not used on the X64 platform.
   USE(extra2);  // The register extra2 is not used on the X64 platform.
@@ -255,14 +256,15 @@
 
 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
     MacroAssembler* masm, int index, Register prototype, Label* miss) {
+  Isolate* isolate = masm->isolate();
   // Check we're still in the same context.
-  __ Move(prototype, Isolate::Current()->global());
+  __ Move(prototype, isolate->global());
   __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)),
           prototype);
   __ j(not_equal, miss);
   // Get the global function with the given index.
-  JSFunction* function = JSFunction::cast(
-      Isolate::Current()->global_context()->get(index));
+  JSFunction* function =
+      JSFunction::cast(isolate->global_context()->get(index));
   // Load its initial map. The global functions all have initial maps.
   __ Move(prototype, Handle<Map>(function->initial_map()));
   // Load the prototype from the initial map.
@@ -601,10 +603,11 @@
                              (depth2 != kInvalidProtoDepth);
     }
 
-    __ IncrementCounter(COUNTERS->call_const_interceptor(), 1);
+    Counters* counters = masm->isolate()->counters();
+    __ IncrementCounter(counters->call_const_interceptor(), 1);
 
     if (can_do_fast_api_call) {
-      __ IncrementCounter(COUNTERS->call_const_interceptor_fast_api(), 1);
+      __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1);
       ReserveSpaceForFastApiCall(masm, scratch1);
     }
 
@@ -734,9 +737,9 @@
   ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
   Code* code = NULL;
   if (kind == Code::LOAD_IC) {
-    code = Isolate::Current()->builtins()->builtin(Builtins::LoadIC_Miss);
+    code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
   } else {
-    code = Isolate::Current()->builtins()->builtin(Builtins::KeyedLoadIC_Miss);
+    code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
   }
 
   Handle<Code> ic(code);
@@ -1322,7 +1325,7 @@
 
 
 MaybeObject* CallStubCompiler::GenerateMissBranch() {
-  MaybeObject* maybe_obj = Isolate::Current()->stub_cache()->ComputeCallMiss(
+  MaybeObject* maybe_obj = masm()->isolate()->stub_cache()->ComputeCallMiss(
       arguments().immediate(), kind_);
   Object* obj;
   if (!maybe_obj->ToObject(&obj)) return maybe_obj;
@@ -2006,8 +2009,9 @@
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &miss_before_stack_reserved);
 
-  __ IncrementCounter(COUNTERS->call_const(), 1);
-  __ IncrementCounter(COUNTERS->call_const_fast_api(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->call_const(), 1);
+  __ IncrementCounter(counters->call_const_fast_api(), 1);
 
   // Allocate space for v8::Arguments implicit values. Must be initialized
   // before calling any runtime function.
@@ -2077,10 +2081,11 @@
   // unless we're doing a receiver map check.
   ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
 
+  Counters* counters = masm()->isolate()->counters();
   SharedFunctionInfo* function_info = function->shared();
   switch (check) {
     case RECEIVER_MAP_CHECK:
-      __ IncrementCounter(COUNTERS->call_const(), 1);
+      __ IncrementCounter(counters->call_const(), 1);
 
       // Check that the maps haven't changed.
       CheckPrototypes(JSObject::cast(object), rdx, holder,
@@ -2282,7 +2287,8 @@
   __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
 
   // Jump to the cached code (tail call).
-  __ IncrementCounter(COUNTERS->call_global_inline(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->call_global_inline(), 1);
   ASSERT(function->is_compiled());
   ParameterCount expected(function->shared()->formal_parameter_count());
   if (V8::UseCrankshaft()) {
@@ -2298,7 +2304,7 @@
   }
   // Handle call cache miss.
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->call_global_inline_miss(), 1);
+  __ IncrementCounter(counters->call_global_inline_miss(), 1);
   MaybeObject* maybe_result = GenerateMissBranch();
   if (maybe_result->IsFailure()) return maybe_result;
 
@@ -2329,8 +2335,7 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2381,8 +2386,7 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2432,8 +2436,7 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2470,14 +2473,14 @@
   __ movq(FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset), rax);
 
   // Return the value (register rax).
-  __ IncrementCounter(COUNTERS->named_store_global_inline(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->named_store_global_inline(), 1);
   __ ret(0);
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->named_store_global_inline_miss(), 1);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::StoreIC_Miss));
+  __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
+  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2497,7 +2500,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_store_field(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_store_field(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rcx, Handle<String>(name));
@@ -2513,9 +2517,8 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_store_field(), 1);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedStoreIC_Miss));
+  __ DecrementCounter(counters->keyed_store_field(), 1);
+  Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
   __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2572,8 +2575,7 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedStoreIC_Miss));
+  Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
   __ jmp(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
@@ -2761,12 +2763,13 @@
     __ Check(not_equal, "DontDelete cells can't contain the hole");
   }
 
-  __ IncrementCounter(COUNTERS->named_load_global_stub(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->named_load_global_stub(), 1);
   __ movq(rax, rbx);
   __ ret(0);
 
   __ bind(&miss);
-  __ IncrementCounter(COUNTERS->named_load_global_stub_miss(), 1);
+  __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
   GenerateLoadMiss(masm(), Code::LOAD_IC);
 
   // Return the generated code.
@@ -2785,7 +2788,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_field(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_field(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rax, Handle<String>(name));
@@ -2794,7 +2798,7 @@
   GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss);
 
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_field(), 1);
+  __ DecrementCounter(counters->keyed_load_field(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -2814,7 +2818,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_callback(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_callback(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rax, Handle<String>(name));
@@ -2829,7 +2834,7 @@
 
   __ bind(&miss);
 
-  __ DecrementCounter(COUNTERS->keyed_load_callback(), 1);
+  __ DecrementCounter(counters->keyed_load_callback(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -2848,7 +2853,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_constant_function(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rax, Handle<String>(name));
@@ -2857,7 +2863,7 @@
   GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi,
                        value, name, &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_constant_function(), 1);
+  __ DecrementCounter(counters->keyed_load_constant_function(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -2875,7 +2881,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_interceptor(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rax, Handle<String>(name));
@@ -2894,7 +2901,7 @@
                           name,
                           &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_interceptor(), 1);
+  __ DecrementCounter(counters->keyed_load_interceptor(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -2910,7 +2917,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_array_length(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_array_length(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rax, Handle<String>(name));
@@ -2918,7 +2926,7 @@
 
   GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_array_length(), 1);
+  __ DecrementCounter(counters->keyed_load_array_length(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -2934,7 +2942,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_string_length(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_string_length(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rax, Handle<String>(name));
@@ -2942,7 +2951,7 @@
 
   GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss, true);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_string_length(), 1);
+  __ DecrementCounter(counters->keyed_load_string_length(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -2958,7 +2967,8 @@
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
 
   // Check that the name has not changed.
   __ Cmp(rax, Handle<String>(name));
@@ -2966,7 +2976,7 @@
 
   GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss);
   __ bind(&miss);
-  __ DecrementCounter(COUNTERS->keyed_load_function_prototype(), 1);
+  __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
   GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
 
   // Return the generated code.
@@ -3135,15 +3145,16 @@
   __ pop(rcx);
   __ lea(rsp, Operand(rsp, rbx, times_pointer_size, 1 * kPointerSize));
   __ push(rcx);
-  __ IncrementCounter(COUNTERS->constructed_objects(), 1);
-  __ IncrementCounter(COUNTERS->constructed_objects_stub(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->constructed_objects(), 1);
+  __ IncrementCounter(counters->constructed_objects_stub(), 1);
   __ ret(0);
 
   // Jump to the generic stub in case the specialized code cannot handle the
   // construction.
   __ bind(&generic_stub_call);
-  Code* code = Isolate::Current()->builtins()->builtin(
-      Builtins::JSConstructStubGeneric);
+  Code* code =
+      masm()->isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric);
   Handle<Code> generic_construct_stub(code);
   __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
 
@@ -3258,7 +3269,8 @@
 
   // Slow case: Jump to runtime.
   __ bind(&slow);
-  __ IncrementCounter(COUNTERS->keyed_load_external_array_slow(), 1);
+  Counters* counters = masm()->isolate()->counters();
+  __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
 
   // ----------- S t a t e -------------
   //  -- rax    : key
diff --git a/src/x64/virtual-frame-x64.cc b/src/x64/virtual-frame-x64.cc
index 6bd7965..10c327a 100644
--- a/src/x64/virtual-frame-x64.cc
+++ b/src/x64/virtual-frame-x64.cc
@@ -1116,7 +1116,7 @@
   // Name and receiver are on the top of the frame.  Both are dropped.
   // The IC expects name in rcx and receiver in rax.
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::LoadIC_Initialize));
+      Builtins::kLoadIC_Initialize));
   Result name = Pop();
   Result receiver = Pop();
   PrepareForCall(0, 0);
@@ -1134,7 +1134,7 @@
   MoveResultsToRegisters(&key, &receiver, rax, rdx);
 
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::KeyedLoadIC_Initialize));
+      Builtins::kKeyedLoadIC_Initialize));
   return RawCallCodeObject(ic, mode);
 }
 
@@ -1145,8 +1145,8 @@
   // Value and (if not contextual) receiver are on top of the frame.
   // The IC expects name in rcx, value in rax, and receiver in rdx.
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      (strict_mode == kStrictMode) ? Builtins::StoreIC_Initialize_Strict
-                                   : Builtins::StoreIC_Initialize));
+      (strict_mode == kStrictMode) ? Builtins::kStoreIC_Initialize_Strict
+                                   : Builtins::kStoreIC_Initialize));
   Result value = Pop();
   RelocInfo::Mode mode;
   if (is_contextual) {
@@ -1211,8 +1211,8 @@
   }
 
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      (strict_mode == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
-                                   : Builtins::KeyedStoreIC_Initialize));
+      (strict_mode == kStrictMode) ? Builtins::kKeyedStoreIC_Initialize_Strict
+                                   : Builtins::kKeyedStoreIC_Initialize));
   return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
 }
 
@@ -1260,7 +1260,7 @@
   // IC expects arg count in rax, function in rdi, and the arguments
   // and receiver on the stack.
   Handle<Code> ic(Isolate::Current()->builtins()->builtin(
-      Builtins::JSConstructCall));
+      Builtins::kJSConstructCall));
   // Duplicate the function before preparing the frame.
   PushElementAt(arg_count);
   Result function = Pop();