Version 3.17.11

Added a version of the v8::HandleScope constructor with an v8::Isolate parameter and made AdjustAmountOfExternalAllocatedMemory an instance method of v8::Isolate. (issue 2487)

Fixed two register allocator bugs (off-by-one error/failure propagation). (issue 2576)

Fixed huge heap snapshot when a heavily shared context has many variables. (Chromium issue 145687)

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@13956 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index 4ec3936..47928a6 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -666,11 +666,21 @@
 
 
 HandleScope::HandleScope() {
-  i::Isolate* isolate = i::Isolate::Current();
-  API_ENTRY_CHECK(isolate, "HandleScope::HandleScope");
+  Initialize(reinterpret_cast<Isolate*>(i::Isolate::Current()));
+}
+
+
+HandleScope::HandleScope(Isolate* isolate) {
+  Initialize(isolate);
+}
+
+
+void HandleScope::Initialize(Isolate* isolate) {
+  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  API_ENTRY_CHECK(internal_isolate, "HandleScope::HandleScope");
   v8::ImplementationUtilities::HandleScopeData* current =
-      isolate->handle_scope_data();
-  isolate_ = isolate;
+      internal_isolate->handle_scope_data();
+  isolate_ = internal_isolate;
   prev_next_ = current->next;
   prev_limit_ = current->limit;
   is_closed_ = false;
@@ -686,7 +696,6 @@
 
 
 void HandleScope::Leave() {
-  ASSERT(isolate_ == i::Isolate::Current());
   v8::ImplementationUtilities::HandleScopeData* current =
       isolate_->handle_scope_data();
   current->level--;
@@ -1884,7 +1893,7 @@
 v8::TryCatch::~TryCatch() {
   ASSERT(isolate_ == i::Isolate::Current());
   if (rethrow_) {
-    v8::HandleScope scope;
+    v8::HandleScope scope(reinterpret_cast<Isolate*>(isolate_));
     v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(Exception());
     isolate_->UnregisterTryCatchHandler(this);
     v8::ThrowException(exc);
@@ -1976,7 +1985,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
   Local<String> result = Utils::ToLocal(raw_result);
@@ -1990,7 +1999,7 @@
     return Local<String>();
   }
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   // Return this.script.name.
@@ -2009,7 +2018,7 @@
     return Local<Value>();
   }
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   // Return this.script.data.
@@ -2027,7 +2036,7 @@
     return Local<v8::StackTrace>();
   }
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
   i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
@@ -2147,7 +2156,7 @@
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result = CallV8HeapFunction("GetSourceLine",
                                                    Utils::OpenHandle(this),
@@ -2177,7 +2186,7 @@
     return Local<StackFrame>();
   }
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSArray> self = Utils::OpenHandle(this);
   i::Object* raw_object = self->GetElementNoExceptionThrown(index);
   i::Handle<i::JSObject> obj(i::JSObject::cast(raw_object));
@@ -2254,7 +2263,7 @@
     return Local<String>();
   }
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> name = GetProperty(self, "scriptName");
   if (!name->IsString()) {
@@ -2270,7 +2279,7 @@
     return Local<String>();
   }
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
   if (!name->IsString()) {
@@ -2286,7 +2295,7 @@
     return Local<String>();
   }
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   i::Handle<i::Object> name = GetProperty(self, "functionName");
   if (!name->IsString()) {
@@ -3280,7 +3289,7 @@
   ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
              return false);
   ENTER_V8(isolate);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
   return i::JSObject::DeleteElement(self, index)->IsTrue();
 }
@@ -3858,7 +3867,7 @@
   ENTER_V8(isolate);
   i::Logger::TimerEventScope timer_scope(
       isolate, i::Logger::TimerEventScope::v8_execute);
-  HandleScope scope;
+  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
   STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
   i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
@@ -4011,31 +4020,30 @@
 
   class Visitor {
    public:
-    explicit Visitor()
+    inline explicit Visitor()
       : utf8_length_(0),
         state_(kInitialState) {}
 
-    template<typename Char>
-    inline void Visit(const Char* chars, int length) {
+    void VisitOneByteString(const uint8_t* chars, int length) {
+      int utf8_length = 0;
+      // Add in length 1 for each non-ASCII character.
+      for (int i = 0; i < length; i++) {
+        utf8_length += *chars++ >> 7;
+      }
+      // Add in length 1 for each character.
+      utf8_length_ = utf8_length + length;
+      state_ = kInitialState;
+    }
+
+    void VisitTwoByteString(const uint16_t* chars, int length) {
       int utf8_length = 0;
       int last_character = unibrow::Utf16::kNoPreviousCharacter;
       for (int i = 0; i < length; i++) {
         uint16_t c = chars[i];
         utf8_length += unibrow::Utf8::Length(c, last_character);
-        if (sizeof(Char) > 1) {
-          last_character = c;
-        }
+        last_character = c;
       }
       utf8_length_ = utf8_length;
-    }
-
-    void VisitOneByteString(const uint8_t* chars, int length) {
-      Visit(chars, length);
-      state_ = kInitialState;
-    }
-
-    void VisitTwoByteString(const uint16_t* chars, int length) {
-      Visit(chars, length);
       uint8_t state = 0;
       if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
         state |= kStartsWithTrailingSurrogate;
@@ -4132,32 +4140,30 @@
       if (right_as_cons == NULL) {
         total_length += leaf_length;
         MergeLeafRight(&total_length, &state, right_leaf_state);
-        // Terminal node.
-        if (left_as_cons == NULL) {
+        if (left_as_cons != NULL) {
+          // 1 Leaf node. Descend in place.
+          current = left_as_cons;
+          continue;
+        } else {
+          // Terminal node.
           MergeTerminal(&total_length, state, state_out);
           return total_length;
         }
-      } else if (left_as_cons != NULL) {
-        // Both strings are ConsStrings.
-        // Recurse on smallest.
-        if (left->length() < right->length()) {
-          total_length += Calculate(left_as_cons, &left_leaf_state);
-          MergeLeafLeft(&total_length, &state, left_leaf_state);
-          current = right_as_cons;
-          continue;
-        } else {
-          total_length += Calculate(right_as_cons, &right_leaf_state);
-          MergeLeafRight(&total_length, &state, right_leaf_state);
-          current = left_as_cons;
-          continue;
-        }
-      }
-      // 1 leaf node. Do in place descent.
-      if (left_as_cons != NULL) {
-        current = left_as_cons;
-      } else {
-        ASSERT(right_as_cons != NULL);
+      } else if (left_as_cons == NULL) {
+        // 1 Leaf node. Descend in place.
         current = right_as_cons;
+        continue;
+      }
+      // Both strings are ConsStrings.
+      // Recurse on smallest.
+      if (left->length() < right->length()) {
+        total_length += Calculate(left_as_cons, &left_leaf_state);
+        MergeLeafLeft(&total_length, &state, left_leaf_state);
+        current = right_as_cons;
+      } else {
+        total_length += Calculate(right_as_cons, &right_leaf_state);
+        MergeLeafRight(&total_length, &state, right_leaf_state);
+        current = left_as_cons;
       }
     }
     UNREACHABLE();
@@ -4267,7 +4273,7 @@
       if (sizeof(Char) == 1) {
         for (; i < fast_length; i++) {
           buffer +=
-              Utf8::Encode(buffer, *chars++, Utf16::kNoPreviousCharacter);
+              Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
           ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_);
         }
       } else {
@@ -5783,14 +5789,21 @@
 }
 
 
+intptr_t Isolate::AdjustAmountOfExternalAllocatedMemory(
+    intptr_t change_in_bytes) {
+  i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
+  return heap->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
+}
+
+
 intptr_t V8::AdjustAmountOfExternalAllocatedMemory(intptr_t change_in_bytes) {
   i::Isolate* isolate = i::Isolate::UncheckedCurrent();
   if (isolate == NULL || !isolate->IsInitialized() ||
       IsDeadCheck(isolate, "v8::V8::AdjustAmountOfExternalAllocatedMemory()")) {
     return 0;
   }
-  return isolate->heap()->AdjustAmountOfExternalAllocatedMemory(
-      change_in_bytes);
+  Isolate* isolate_ext = reinterpret_cast<Isolate*>(isolate);
+  return isolate_ext->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
 }
 
 
@@ -6314,7 +6327,7 @@
   if (!isolate->IsInitialized()) return Local<Value>();
   ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
   ENTER_V8(isolate);
-  v8::HandleScope scope;
+  v8::HandleScope scope(reinterpret_cast<Isolate*>(isolate));
   i::Debug* isolate_debug = isolate->debug();
   isolate_debug->Load();
   i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h
index 85a523d..123013b 100644
--- a/src/arm/assembler-arm-inl.h
+++ b/src/arm/assembler-arm-inl.h
@@ -107,13 +107,13 @@
 
 
 Address RelocInfo::target_address() {
-  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
+  ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
   return Assembler::target_address_at(pc_);
 }
 
 
 Address RelocInfo::target_address_address() {
-  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
+  ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
                               || rmode_ == EMBEDDED_OBJECT
                               || rmode_ == EXTERNAL_REFERENCE);
   return reinterpret_cast<Address>(Assembler::target_pointer_address_at(pc_));
@@ -126,7 +126,7 @@
 
 
 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
-  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
+  ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
   Assembler::set_target_address_at(pc_, target);
   if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) {
     Object* target_code = Code::GetCodeFromTargetAddress(target);
@@ -321,7 +321,7 @@
              Isolate::Current()->debug()->has_break_points()) {
     visitor->VisitDebugTarget(this);
 #endif
-  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
+  } else if (RelocInfo::IsRuntimeEntry(mode)) {
     visitor->VisitRuntimeEntry(this);
   }
 }
@@ -348,7 +348,7 @@
               IsPatchedDebugBreakSlotSequence()))) {
     StaticVisitor::VisitDebugTarget(heap, this);
 #endif
-  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
+  } else if (RelocInfo::IsRuntimeEntry(mode)) {
     StaticVisitor::VisitRuntimeEntry(this);
   }
 }
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 142787b..2946b35 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -124,12 +124,7 @@
   if (initial_capacity > 0) {
     size += FixedArray::SizeFor(initial_capacity);
   }
-  __ AllocateInNewSpace(size,
-                        result,
-                        scratch2,
-                        scratch3,
-                        gc_required,
-                        TAG_OBJECT);
+  __ Allocate(size, result, scratch2, scratch3, gc_required, TAG_OBJECT);
 
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
@@ -653,12 +648,12 @@
   // -----------------------------------
 
   Label gc_required;
-  __ AllocateInNewSpace(JSValue::kSize,
-                        r0,  // Result.
-                        r3,  // Scratch.
-                        r4,  // Scratch.
-                        &gc_required,
-                        TAG_OBJECT);
+  __ Allocate(JSValue::kSize,
+              r0,  // Result.
+              r3,  // Scratch.
+              r4,  // Scratch.
+              &gc_required,
+              TAG_OBJECT);
 
   // Initialising the String Object.
   Register map = r3;
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index f2f6408..b1ffaea 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -166,12 +166,7 @@
   __ pop(r3);
 
   // Attempt to allocate new JSFunction in new space.
-  __ AllocateInNewSpace(JSFunction::kSize,
-                        r0,
-                        r1,
-                        r2,
-                        &gc,
-                        TAG_OBJECT);
+  __ Allocate(JSFunction::kSize, r0, r1, r2, &gc, TAG_OBJECT);
 
   __ IncrementCounter(counters->fast_new_closure_total(), 1, r6, r7);
 
@@ -298,12 +293,7 @@
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
 
   // Attempt to allocate the context in new space.
-  __ AllocateInNewSpace(FixedArray::SizeFor(length),
-                        r0,
-                        r1,
-                        r2,
-                        &gc,
-                        TAG_OBJECT);
+  __ Allocate(FixedArray::SizeFor(length), r0, r1, r2, &gc, TAG_OBJECT);
 
   // Load the function from the stack.
   __ ldr(r3, MemOperand(sp, 0));
@@ -348,8 +338,7 @@
   // Try to allocate the context in new space.
   Label gc;
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
-  __ AllocateInNewSpace(FixedArray::SizeFor(length),
-                        r0, r1, r2, &gc, TAG_OBJECT);
+  __ Allocate(FixedArray::SizeFor(length), r0, r1, r2, &gc, TAG_OBJECT);
 
   // Load the function from the stack.
   __ ldr(r3, MemOperand(sp, 0));
@@ -435,7 +424,7 @@
   if (mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS) {
     flags = static_cast<AllocationFlags>(DOUBLE_ALIGNMENT | flags);
   }
-  __ AllocateInNewSpace(size, r0, r1, r2, fail, flags);
+  __ Allocate(size, r0, r1, r2, fail, flags);
 
   if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     __ mov(r2, Operand(Handle<Map>(masm->isolate()->heap()->
@@ -4513,7 +4502,7 @@
 
   StubCompiler::GenerateLoadArrayLength(masm, receiver, r3, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -4542,7 +4531,7 @@
 
   StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r3, r4, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -4573,7 +4562,7 @@
                                          support_wrapper_);
 
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -4643,7 +4632,7 @@
 
   __ bind(&miss);
 
-  StubCompiler::GenerateStoreMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index eb1f988..1df1649 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1547,7 +1547,7 @@
   __ bind(&materialized);
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index e10068f..7272f54 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -290,6 +290,13 @@
 }
 
 
+void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  base_object()->PrintTo(stream);
+  stream->Add(" + %d", offset());
+}
+
+
 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
   stream->Add("#%d / ", arity());
 }
@@ -668,8 +675,12 @@
 LUnallocated* LChunkBuilder::TempRegister() {
   LUnallocated* operand =
       new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
-  operand->set_virtual_register(allocator_->GetVirtualRegister());
-  if (!allocator_->AllocationOk()) Abort("Not enough virtual registers.");
+  int vreg = allocator_->GetVirtualRegister();
+  if (!allocator_->AllocationOk()) {
+    Abort("Out of virtual registers while trying to allocate temp register.");
+    return NULL;
+  }
+  operand->set_virtual_register(vreg);
   return operand;
 }
 
@@ -928,7 +939,7 @@
 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
   HValue* value = instr->value();
   if (value->EmitAtUses()) {
-    HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
+    HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
     return new(zone()) LGoto(successor->block_id());
@@ -1017,6 +1028,15 @@
 }
 
 
+LInstruction* LChunkBuilder::DoInnerAllocatedObject(
+    HInnerAllocatedObject* inner_object) {
+  LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
+  LInnerAllocatedObject* result =
+    new(zone()) LInnerAllocatedObject(base_object);
+  return DefineAsRegister(result);
+}
+
+
 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
   return instr->HasNoUses()
       ? NULL
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index ca8b493..f49e8ce 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -191,7 +191,8 @@
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
   V(WrapReceiver)                               \
-  V(Drop)
+  V(Drop)                                       \
+  V(InnerAllocatedObject)
 
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
@@ -1655,6 +1656,22 @@
 };
 
 
+class LInnerAllocatedObject: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LInnerAllocatedObject(LOperand* base_object) {
+    inputs_[0] = base_object;
+  }
+
+  LOperand* base_object() { return inputs_[0]; }
+  int offset() { return hydrogen()->offset(); }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
+  DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+};
+
+
 class LThisFunction: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 6e2fc17..e8f96e4 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -4341,6 +4341,13 @@
 }
 
 
+void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
+  Register result = ToRegister(instr->result());
+  Register base = ToRegister(instr->base_object());
+  __ add(result, base, Operand(instr->offset()));
+}
+
+
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Register object = ToRegister(instr->object());
   Register value = ToRegister(instr->value());
@@ -5581,12 +5588,8 @@
   // the constructor's prototype changes, but instance size and property
   // counts remain unchanged (if slack tracking finished).
   ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress());
-  __ AllocateInNewSpace(instance_size,
-                        result,
-                        scratch,
-                        scratch2,
-                        deferred->entry(),
-                        TAG_OBJECT);
+  __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(),
+              TAG_OBJECT);
 
   __ bind(deferred->exit());
   if (FLAG_debug_code) {
@@ -5661,12 +5664,10 @@
   }
   if (instr->size()->IsConstantOperand()) {
     int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
-    __ AllocateInNewSpace(size,
-                          result,
-                          scratch,
-                          scratch2,
-                          deferred->entry(),
-                          flags);
+    if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
+      flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
+    }
+    __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
     __ AllocateInNewSpace(size,
@@ -5899,7 +5900,7 @@
   // Allocate all objects that are part of the literal in one big
   // allocation. This avoids multiple limit checks.
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
@@ -5981,7 +5982,7 @@
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
 
-  __ AllocateInNewSpace(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 1542447..e0e77cf 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -1564,12 +1564,12 @@
 }
 
 
-void MacroAssembler::AllocateInNewSpace(int object_size,
-                                        Register result,
-                                        Register scratch1,
-                                        Register scratch2,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
+void MacroAssembler::Allocate(int object_size,
+                              Register result,
+                              Register scratch1,
+                              Register scratch2,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -1597,21 +1597,22 @@
   // The values must be adjacent in memory to allow the use of LDM.
   // Also, assert that the registers are numbered such that the values
   // are loaded in the correct order.
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
+
   intptr_t top   =
-      reinterpret_cast<intptr_t>(new_space_allocation_top.address());
+      reinterpret_cast<intptr_t>(allocation_top.address());
   intptr_t limit =
-      reinterpret_cast<intptr_t>(new_space_allocation_limit.address());
+      reinterpret_cast<intptr_t>(allocation_limit.address());
   ASSERT((limit - top) == kPointerSize);
   ASSERT(result.code() < ip.code());
 
   // Set up allocation top address and object size registers.
   Register topaddr = scratch1;
   Register obj_size_reg = scratch2;
-  mov(topaddr, Operand(new_space_allocation_top));
+  mov(topaddr, Operand(allocation_top));
   Operand obj_size_operand = Operand(object_size);
   if (!obj_size_operand.is_single_instruction(this)) {
     // We are about to steal IP, so we need to load this value first
@@ -1639,6 +1640,7 @@
   if ((flags & DOUBLE_ALIGNMENT) != 0) {
     // Align the next allocation. Storing the filler map without checking top is
     // always safe because the limit of the heap is always aligned.
+    ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
     ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
     and_(scratch2, result, Operand(kDoubleAlignmentMask), SetCC);
     Label aligned;
@@ -1675,6 +1677,7 @@
                                         Register scratch2,
                                         Label* gc_required,
                                         AllocationFlags flags) {
+  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -1858,12 +1861,8 @@
                                                Register scratch1,
                                                Register scratch2,
                                                Label* gc_required) {
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   InitializeNewString(result,
                       length,
@@ -1878,12 +1877,8 @@
                                              Register scratch1,
                                              Register scratch2,
                                              Label* gc_required) {
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   InitializeNewString(result,
                       length,
@@ -1898,12 +1893,8 @@
                                                  Register scratch1,
                                                  Register scratch2,
                                                  Label* gc_required) {
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   InitializeNewString(result,
                       length,
@@ -1918,12 +1909,8 @@
                                                Register scratch1,
                                                Register scratch2,
                                                Label* gc_required) {
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   InitializeNewString(result,
                       length,
@@ -2238,7 +2225,8 @@
 
 
 void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
-  ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe());
+  ASSERT(allow_stub_calls_ ||
+         stub->CompilingCallsToThisStubIsGCSafe(isolate()));
   Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, cond);
 }
 
@@ -2348,7 +2336,7 @@
 
 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
   if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
-  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe();
+  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe(isolate());
 }
 
 
@@ -2544,7 +2532,15 @@
          !scratch.is(input_low));
   ASSERT(!double_input.is(double_scratch));
 
-  Label overflow, out_of_range, negate, done;
+  Label out_of_range, negate, done;
+
+  vcvt_s32_f64(double_scratch.low(), double_input);
+  vmov(result, double_scratch.low());
+
+  // If result is not saturated (0x7fffffff or 0x80000000), we are done.
+  sub(scratch, result, Operand(1));
+  cmp(scratch, Operand(0x7ffffffe));
+  b(lt, &done);
 
   vmov(input_low, input_high, double_input);
   Ubfx(scratch, input_high,
@@ -2552,20 +2548,9 @@
   // Load scratch with exponent - 1. This is faster than loading
   // with exponent because Bias + 1 = 1024 which is an *ARM* immediate value.
   sub(scratch, scratch, Operand(HeapNumber::kExponentBias + 1));
-  // Compare exponent with 31 (compare exponent - 1 with 30).
-  cmp(scratch, Operand(30));
-  b(ge, &overflow);
-  // Exponent is less than 31 so vcvt will never saturate.
-  // So, just return the result.
-  vcvt_s32_f64(double_scratch.low(), double_input);
-  vmov(result, double_scratch.low());
-  b(&done);
-
-  bind(&overflow);
   // If exponent is greater than or equal to 84, the 32 less significant
   // bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits),
   // the result is 0.
-  // This test also catch Nan and infinities which also return 0.
   // Compare exponent with 84 (compare exponent - 1 with 83).
   cmp(scratch, Operand(83));
   b(ge, &out_of_range);
@@ -3231,13 +3216,8 @@
                                         TaggingMode tagging_mode) {
   // Allocate an object in the heap for the heap number and tag it as a heap
   // object.
-  AllocateInNewSpace(HeapNumber::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     tagging_mode == TAG_RESULT ? TAG_OBJECT :
-                                                  NO_ALLOCATION_FLAGS);
+  Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required,
+           tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS);
 
   // Store heap number map in the allocated object.
   AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index 05ede68..5cbe995 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -665,19 +665,20 @@
   // ---------------------------------------------------------------------------
   // Allocation support
 
-  // Allocate an object in new space. The object_size is specified
-  // either in bytes or in words if the allocation flag SIZE_IN_WORDS
-  // is passed. If the new space is exhausted control continues at the
-  // gc_required label. The allocated object is returned in result. If
-  // the flag tag_allocated_object is true the result is tagged as as
-  // a heap object. All registers are clobbered also when control
-  // continues at the gc_required label.
-  void AllocateInNewSpace(int object_size,
-                          Register result,
-                          Register scratch1,
-                          Register scratch2,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  // Allocate an object in new space or old pointer space. The object_size is
+  // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS
+  // is passed. If the space is exhausted control continues at the gc_required
+  // label. The allocated object is returned in result. If the flag
+  // tag_allocated_object is true the result is tagged as as a heap object.
+  // All registers are clobbered also when control continues at the gc_required
+  // label.
+  void Allocate(int object_size,
+                Register result,
+                Register scratch1,
+                Register scratch2,
+                Label* gc_required,
+                AllocationFlags flags);
+
   void AllocateInNewSpace(Register object_size,
                           Register result,
                           Register scratch1,
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index 7e6c344..0cb80c0 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -337,9 +337,6 @@
     __ b(ne, &fail);
     __ sub(r3, r3, Operand('a'));
     __ cmp(r3, Operand('z' - 'a'));  // Is r3 a lowercase letter?
-#ifndef ENABLE_LATIN_1
-    __ b(hi, &fail);
-#else
     __ b(ls, &loop_check);  // In range 'a'-'z'.
     // Latin-1: Check for values in range [224,254] but not 247.
     __ sub(r3, r3, Operand(224 - 'a'));
@@ -347,7 +344,6 @@
     __ b(hi, &fail);  // Weren't Latin-1 letters.
     __ cmp(r3, Operand(247 - 224));  // Check for 247.
     __ b(eq, &fail);
-#endif
 
     __ bind(&loop_check);
     __ cmp(r0, r1);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index ac9b5ec..e3d27f1 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -320,19 +320,6 @@
 }
 
 
-// Load a fast property out of a holder object (src). In-object properties
-// are loaded directly otherwise the property is loaded from the properties
-// fixed array.
-void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
-                                            Register dst,
-                                            Register src,
-                                            Handle<JSObject> holder,
-                                            PropertyIndex index) {
-  DoGenerateFastPropertyLoad(
-      masm, dst, src, index.is_inobject(holder), index.translate(holder));
-}
-
-
 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
                                               Register dst,
                                               Register src,
@@ -446,9 +433,11 @@
                                       Handle<Name> name,
                                       Register receiver_reg,
                                       Register name_reg,
+                                      Register value_reg,
                                       Register scratch1,
                                       Register scratch2,
-                                      Label* miss_label) {
+                                      Label* miss_label,
+                                      Label* miss_restore_name) {
   // r0 : value
   Label exit;
 
@@ -485,17 +474,8 @@
         holder = JSObject::cast(holder->GetPrototype());
       } while (holder->GetPrototype()->IsJSObject());
     }
-    // We need an extra register, push
-    __ push(name_reg);
-    Label miss_pop, done_check;
     CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, &miss_pop);
-    __ jmp(&done_check);
-    __ bind(&miss_pop);
-    __ pop(name_reg);
-    __ jmp(miss_label);
-    __ bind(&done_check);
-    __ pop(name_reg);
+                    scratch1, scratch2, name, miss_restore_name);
   }
 
   // Stub never generated for non-global objects that require access
@@ -542,14 +522,14 @@
   if (index < 0) {
     // Set the property straight into the object.
     int offset = object->map()->instance_size() + (index * kPointerSize);
-    __ str(r0, FieldMemOperand(receiver_reg, offset));
+    __ str(value_reg, FieldMemOperand(receiver_reg, offset));
 
     // Skip updating write barrier if storing a smi.
-    __ JumpIfSmi(r0, &exit);
+    __ JumpIfSmi(value_reg, &exit);
 
     // Update the write barrier for the array address.
     // Pass the now unused name_reg as a scratch register.
-    __ mov(name_reg, r0);
+    __ mov(name_reg, value_reg);
     __ RecordWriteField(receiver_reg,
                         offset,
                         name_reg,
@@ -562,14 +542,14 @@
     // Get the properties array
     __ ldr(scratch1,
            FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    __ str(r0, FieldMemOperand(scratch1, offset));
+    __ str(value_reg, FieldMemOperand(scratch1, offset));
 
     // Skip updating write barrier if storing a smi.
-    __ JumpIfSmi(r0, &exit);
+    __ JumpIfSmi(value_reg, &exit);
 
     // Update the write barrier for the array address.
     // Ok to clobber receiver_reg and name_reg, since we return.
-    __ mov(name_reg, r0);
+    __ mov(name_reg, value_reg);
     __ RecordWriteField(scratch1,
                         offset,
                         name_reg,
@@ -579,26 +559,19 @@
   }
 
   // Return the value (register r0).
+  ASSERT(value_reg.is(r0));
   __ bind(&exit);
   __ Ret();
 }
 
 
-void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
-  Handle<Code> code = (kind == Code::LOAD_IC)
-      ? masm->isolate()->builtins()->LoadIC_Miss()
-      : masm->isolate()->builtins()->KeyedLoadIC_Miss();
-  __ Jump(code, RelocInfo::CODE_TARGET);
-}
-
-
-void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
-  Handle<Code> code = (kind == Code::STORE_IC)
-      ? masm->isolate()->builtins()->StoreIC_Miss()
-      : masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(code, RelocInfo::CODE_TARGET);
+void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
+                                                Label* label,
+                                                Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ bind(label);
+    __ mov(this->name(), Operand(name));
+  }
 }
 
 
@@ -1063,15 +1036,15 @@
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-void StubCompiler::GenerateTailCall(Handle<Code> code) {
+void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
   __ Jump(code, RelocInfo::CODE_TARGET);
 }
 
 
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
                                        Register object_reg,
                                        Handle<JSObject> holder,
@@ -1190,7 +1163,7 @@
   if (!miss->is_unused()) {
     __ b(success);
     __ bind(miss);
-    GenerateLoadMiss(masm(), kind());
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
   }
 }
 
@@ -2599,58 +2572,23 @@
 }
 
 
-Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                  int index,
-                                                  Handle<Map> transition,
-                                                  Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : receiver
-  //  -- r2    : name
-  //  -- lr    : return address
-  // -----------------------------------
-  Label miss;
-
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     r1, r2, r3, r4,
-                     &miss);
-  __ bind(&miss);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreCallback(
     Handle<Name> name,
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<JSObject> holder,
     Handle<ExecutableAccessorInfo> callback) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : receiver
-  //  -- r2    : name
-  //  -- lr    : return address
-  // -----------------------------------
   Label miss;
   // Check that the maps haven't changed.
-  __ JumpIfSmi(r1, &miss);
-  CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss);
+  __ JumpIfSmi(receiver(), &miss);
+  CheckPrototypes(object, receiver(), holder,
+                  scratch1(), scratch2(), scratch3(), name, &miss);
 
   // Stub never generated for non-global objects that require access checks.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
 
-  __ push(r1);  // receiver
+  __ push(receiver());  // receiver
   __ mov(ip, Operand(callback));  // callback info
-  __ Push(ip, r2, r0);
+  __ Push(ip, this->name(), value());
 
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
@@ -2660,11 +2598,10 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
+  return GetICCode(kind(), Code::CALLBACKS, name);
 }
 
 
@@ -2713,62 +2650,28 @@
 #define __ ACCESS_MASM(masm())
 
 
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
-    Handle<Name> name,
-    Handle<JSObject> receiver,
-    Handle<JSObject> holder,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : receiver
-  //  -- r2    : name
-  //  -- lr    : return address
-  // -----------------------------------
-  Label miss;
-
-  // Check that the maps haven't changed.
-  __ JumpIfSmi(r1, &miss);
-  CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss);
-
-  GenerateStoreViaSetter(masm(), setter);
-
-  __ bind(&miss);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : receiver
-  //  -- r2    : name
-  //  -- lr    : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the object hasn't changed.
-  __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss,
+  __ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss,
               DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform global security token check if needed.
-  if (receiver->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(r1, r3, &miss);
+  if (object->IsJSGlobalProxy()) {
+    __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
   }
 
   // Stub is never generated for non-global objects that require access
   // checks.
-  ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
+  ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
 
-  __ Push(r1, r2, r0);  // Receiver, name, value.
+  __ Push(receiver(), this->name(), value());
 
-  __ mov(r0, Operand(Smi::FromInt(strict_mode_)));
-  __ push(r0);  // strict mode
+  __ mov(scratch1(), Operand(Smi::FromInt(strict_mode())));
+  __ push(scratch1());  // strict mode
 
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
@@ -2778,11 +2681,10 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::INTERCEPTOR, name);
+  return GetICCode(kind(), Code::INTERCEPTOR, name);
 }
 
 
@@ -2790,45 +2692,42 @@
     Handle<GlobalObject> object,
     Handle<JSGlobalPropertyCell> cell,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : receiver
-  //  -- r2    : name
-  //  -- lr    : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the global has not changed.
-  __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
-  __ cmp(r3, Operand(Handle<Map>(object->map())));
+  __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  __ cmp(scratch1(), Operand(Handle<Map>(object->map())));
   __ b(ne, &miss);
 
   // Check that the value in the cell is not the hole. If it is, this
   // cell could have been deleted and reintroducing the global needs
   // to update the property details in the property dictionary of the
   // global object. We bail out to the runtime system to do that.
-  __ mov(r4, Operand(cell));
-  __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
-  __ ldr(r6, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset));
-  __ cmp(r5, r6);
+  __ mov(scratch1(), Operand(cell));
+  __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex);
+  __ ldr(scratch3(),
+         FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
+  __ cmp(scratch3(), scratch2());
   __ b(eq, &miss);
 
   // Store the value in the cell.
-  __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset));
+  __ str(value(),
+         FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset));
   // Cells are always rescanned, so no write barrier here.
 
   Counters* counters = masm()->isolate()->counters();
-  __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3);
+  __ IncrementCounter(
+      counters->named_store_global_inline(), 1, scratch1(), scratch2());
   __ Ret();
 
   // Handle store cache miss.
   __ bind(&miss);
-  __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  __ IncrementCounter(
+      counters->named_store_global_inline_miss(), 1, scratch1(), scratch2());
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, name);
+  return GetICCode(kind(), Code::NORMAL, name);
 }
 
 
@@ -2866,6 +2765,20 @@
 }
 
 
+Register* StoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { r1, r2, r0, r3, r4, r5 };
+  return registers;
+}
+
+
+Register* KeyedStoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { r2, r1, r0, r3, r4, r5 };
+  return registers;
+}
+
+
 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
                                               Register name_reg,
                                               Label* miss) {
@@ -2874,6 +2787,14 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
+                                               Register name_reg,
+                                               Label* miss) {
+  __ cmp(name_reg, Operand(name));
+  __ b(ne, miss);
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
@@ -2948,34 +2869,6 @@
 }
 
 
-Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- lr    : return address
-  //  -- r0    : key
-  //  -- r1    : receiver
-  // -----------------------------------
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  if (receiver_map->has_fast_elements() ||
-      receiver_map->has_external_array_elements()) {
-    Handle<Code> stub = KeyedLoadFastElementStub(
-        receiver_map->instance_type() == JS_ARRAY_TYPE,
-        elements_kind).GetCode(isolate());
-    __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK);
-  } else {
-    Handle<Code> stub =
-        KeyedLoadDictionaryElementStub().GetCode(isolate());
-    __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK);
-  }
-
-  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
-}
-
-
 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
     MapHandleList* receiver_maps,
     CodeHandleList* handlers,
@@ -3000,7 +2893,7 @@
   }
 
   __ bind(&miss);
-  GenerateLoadMiss(masm(), kind());
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
   InlineCacheState state =
@@ -3009,109 +2902,35 @@
 }
 
 
-Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                       int index,
-                                                       Handle<Map> transition,
-                                                       Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : name
-  //  -- r2    : receiver
-  //  -- lr    : return address
-  // -----------------------------------
-  Label miss;
-
-  Counters* counters = masm()->isolate()->counters();
-  __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4);
-
-  // Check that the name has not changed.
-  __ cmp(r1, Operand(name));
-  __ b(ne, &miss);
-
-  // r3 is used as scratch register. r1 and r2 keep their values if a jump to
-  // the miss label is generated.
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     r2, r1, r3, r4,
-                     &miss);
-  __ bind(&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.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
-Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : key
-  //  -- r2    : receiver
-  //  -- lr    : return address
-  //  -- r3    : scratch
-  // -----------------------------------
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
-  Handle<Code> stub =
-      KeyedStoreElementStub(is_js_array,
-                            elements_kind,
-                            store_mode_).GetCode(isolate());
-
-  __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK);
-
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string());
-}
-
-
 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
     MapHandleList* receiver_maps,
     CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
-  // ----------- S t a t e -------------
-  //  -- r0    : value
-  //  -- r1    : key
-  //  -- r2    : receiver
-  //  -- lr    : return address
-  //  -- r3    : scratch
-  // -----------------------------------
   Label miss;
-  __ JumpIfSmi(r2, &miss);
+  __ JumpIfSmi(receiver(), &miss);
 
   int receiver_count = receiver_maps->length();
-  __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
+  __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_count; ++i) {
     __ mov(ip, Operand(receiver_maps->at(i)));
-    __ cmp(r3, ip);
+    __ cmp(scratch1(), ip);
     if (transitioned_maps->at(i).is_null()) {
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq);
     } else {
       Label next_map;
       __ b(ne, &next_map);
-      __ mov(r3, Operand(transitioned_maps->at(i)));
+      __ mov(transition_map(), Operand(transitioned_maps->at(i)));
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
       __ bind(&next_map);
     }
   }
 
   __ bind(&miss);
-  Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
+  return GetICCode(
+      kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3292,9 +3111,7 @@
   //  -- r0     : key
   //  -- r1     : receiver
   // -----------------------------------
-  Handle<Code> slow_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_Slow();
-  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
 
   // Miss case, call the runtime.
   __ bind(&miss_force_generic);
@@ -3304,10 +3121,7 @@
   //  -- r0     : key
   //  -- r1     : receiver
   // -----------------------------------
-
-  Handle<Code> miss_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
 }
 
 
@@ -3699,9 +3513,7 @@
   //  -- r0     : key
   //  -- r1     : receiver
   // -----------------------------------
-  Handle<Code> slow_ic =
-      masm->isolate()->builtins()->KeyedStoreIC_Slow();
-  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
 
   // Miss case, call the runtime.
   __ bind(&miss_force_generic);
@@ -3711,10 +3523,7 @@
   //  -- r0     : key
   //  -- r1     : receiver
   // -----------------------------------
-
-  Handle<Code> miss_ic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 }
 
 
@@ -3807,13 +3616,10 @@
   __ Ret();
 
   __ bind(&miss_force_generic);
-  Handle<Code> ic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Grow the array by a single element if possible.
@@ -3833,8 +3639,7 @@
     __ b(ne, &check_capacity);
 
     int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, elements_reg, scratch, scratch2, &slow,
-                          TAG_OBJECT);
+    __ Allocate(size, elements_reg, scratch, scratch2, &slow, TAG_OBJECT);
 
     __ LoadRoot(scratch, Heap::kFixedArrayMapRootIndex);
     __ str(scratch, FieldMemOperand(elements_reg, JSObject::kMapOffset));
@@ -3878,8 +3683,7 @@
     __ jmp(&finish_store);
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ Jump(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }
 
@@ -3953,13 +3757,10 @@
 
   // Handle store cache miss, replacing the ic with the generic stub.
   __ bind(&miss_force_generic);
-  Handle<Code> ic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Grow the array by a single element if possible.
@@ -3987,8 +3788,7 @@
     __ b(ne, &check_capacity);
 
     int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, elements_reg, scratch1, scratch2, &slow,
-                          TAG_OBJECT);
+    __ Allocate(size, elements_reg, scratch1, scratch2, &slow, TAG_OBJECT);
 
     // Initialize the new FixedDoubleArray.
     __ LoadRoot(scratch1, Heap::kFixedDoubleArrayMapRootIndex);
@@ -4044,8 +3844,7 @@
     __ jmp(&finish_store);
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ Jump(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }
 
diff --git a/src/assembler.cc b/src/assembler.cc
index 8d8208d..fc96662 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -811,7 +811,7 @@
     }
   } else if (IsPosition(rmode_)) {
     PrintF(out, "  (%" V8_PTR_PREFIX "d)", data());
-  } else if (rmode_ == RelocInfo::RUNTIME_ENTRY &&
+  } else if (IsRuntimeEntry(rmode_) &&
              Isolate::Current()->deoptimizer_data() != NULL) {
     // Depotimization bailouts are stored as runtime entries.
     int id = Deoptimizer::GetDeoptimizationId(
@@ -1188,6 +1188,20 @@
 }
 
 
+ExternalReference ExternalReference::old_pointer_space_allocation_top_address(
+    Isolate* isolate) {
+  return ExternalReference(
+      isolate->heap()->OldPointerSpaceAllocationTopAddress());
+}
+
+
+ExternalReference ExternalReference::old_pointer_space_allocation_limit_address(
+    Isolate* isolate) {
+  return ExternalReference(
+      isolate->heap()->OldPointerSpaceAllocationLimitAddress());
+}
+
+
 ExternalReference ExternalReference::handle_scope_level_address(
     Isolate* isolate) {
   return ExternalReference(HandleScope::current_level_address(isolate));
diff --git a/src/assembler.h b/src/assembler.h
index f5ae611..4a67ce3 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -373,7 +373,7 @@
 
   // Read/modify the code target in the branch/call instruction
   // this relocation applies to;
-  // can only be called if IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY
+  // can only be called if IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)
   INLINE(Address target_address());
   INLINE(void set_target_address(Address target,
                                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER));
@@ -749,6 +749,10 @@
   // Used for fast allocation in generated code.
   static ExternalReference new_space_allocation_top_address(Isolate* isolate);
   static ExternalReference new_space_allocation_limit_address(Isolate* isolate);
+  static ExternalReference old_pointer_space_allocation_top_address(
+      Isolate* isolate);
+  static ExternalReference old_pointer_space_allocation_limit_address(
+      Isolate* isolate);
 
   static ExternalReference double_fp_operation(Token::Value operation,
                                                Isolate* isolate);
diff --git a/src/ast.cc b/src/ast.cc
index 02c815c..712bfd1 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1007,11 +1007,6 @@
     add_flag(kDontInline); \
     add_flag(kDontSelfOptimize); \
   }
-#define DONT_INLINE_NODE(NodeType) \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count(); \
-    add_flag(kDontInline); \
-  }
 #define DONT_SELFOPTIMIZE_NODE(NodeType) \
   void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
     increase_node_count(); \
@@ -1038,8 +1033,10 @@
 REGULAR_NODE(SwitchStatement)
 REGULAR_NODE(Conditional)
 REGULAR_NODE(Literal)
+REGULAR_NODE(ArrayLiteral)
 REGULAR_NODE(ObjectLiteral)
 REGULAR_NODE(RegExpLiteral)
+REGULAR_NODE(FunctionLiteral)
 REGULAR_NODE(Assignment)
 REGULAR_NODE(Throw)
 REGULAR_NODE(Property)
@@ -1070,9 +1067,6 @@
 DONT_OPTIMIZE_NODE(DebuggerStatement)
 DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral)
 
-DONT_INLINE_NODE(ArrayLiteral)  // TODO(1322): Allow materialized literals.
-DONT_INLINE_NODE(FunctionLiteral)
-
 DONT_SELFOPTIMIZE_NODE(DoWhileStatement)
 DONT_SELFOPTIMIZE_NODE(WhileStatement)
 DONT_SELFOPTIMIZE_NODE(ForStatement)
@@ -1099,7 +1093,6 @@
 
 #undef REGULAR_NODE
 #undef DONT_OPTIMIZE_NODE
-#undef DONT_INLINE_NODE
 #undef DONT_SELFOPTIMIZE_NODE
 #undef DONT_CACHE_NODE
 
diff --git a/src/builtins.cc b/src/builtins.cc
index aa69203..f8d562b 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -203,12 +203,6 @@
     holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray);
   }
 
-  ASSERT(function->has_initial_map());
-  ElementsKind kind = function->initial_map()->elements_kind();
-  if (holey) {
-    kind = GetHoleyElementsKind(kind);
-  }
-
   MaybeObject* maybe_array;
   if (*type_info != isolate->heap()->undefined_value()) {
     JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
@@ -224,14 +218,20 @@
       AllocationSiteMode mode = AllocationSiteInfo::GetMode(to_kind);
       if (mode == TRACK_ALLOCATION_SITE) {
         maybe_array = isolate->heap()->AllocateEmptyJSArrayWithAllocationSite(
-            kind, type_info);
+            to_kind, type_info);
       } else {
-        maybe_array = isolate->heap()->AllocateEmptyJSArray(kind);
+        maybe_array = isolate->heap()->AllocateEmptyJSArray(to_kind);
       }
       if (!maybe_array->To(&array)) return maybe_array;
     }
   }
 
+  ASSERT(function->has_initial_map());
+  ElementsKind kind = function->initial_map()->elements_kind();
+  if (holey) {
+    kind = GetHoleyElementsKind(kind);
+  }
+
   if (array == NULL) {
     maybe_array = isolate->heap()->AllocateEmptyJSArray(kind);
     if (!maybe_array->To(&array)) return maybe_array;
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index bb8bfe3..ae198bc 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -39,7 +39,7 @@
   Isolate* isolate =  graph->isolate();
   AssertNoAllocation no_gc;
   NoHandleAllocation no_handles(isolate);
-  NoHandleDereference no_deref(isolate);
+  HandleDereferenceGuard no_deref(isolate, HandleDereferenceGuard::DISALLOW);
 
   ASSERT(graph != NULL);
   SmartArrayPointer<char> bailout_reason;
@@ -189,11 +189,16 @@
 
   HValue* size_in_bytes =
       AddInstruction(new(zone) HConstant(size, Representation::Integer32()));
+  HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
+  if (FLAG_pretenure_literals) {
+    flags = static_cast<HAllocate::Flags>(
+       flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
+  }
   HInstruction* object =
       AddInstruction(new(zone) HAllocate(context(),
                                          size_in_bytes,
                                          HType::JSObject(),
-                                         HAllocate::CAN_ALLOCATE_IN_NEW_SPACE));
+                                         flags));
 
   for (int i = 0; i < size; i += kPointerSize) {
     HInstruction* value =
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 151a51c..e91b241 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -149,10 +149,10 @@
 
   virtual ~CodeStub() {}
 
-  bool CompilingCallsToThisStubIsGCSafe() {
+  bool CompilingCallsToThisStubIsGCSafe(Isolate* isolate) {
     bool is_pregenerated = IsPregenerated();
     Code* code = NULL;
-    CHECK(!is_pregenerated || FindCodeInCache(&code, Isolate::Current()));
+    CHECK(!is_pregenerated || FindCodeInCache(&code, isolate));
     return is_pregenerated;
   }
 
diff --git a/src/compiler.cc b/src/compiler.cc
index 8f4be0c..e51fb42 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -396,7 +396,7 @@
 OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() {
   AssertNoAllocation no_gc;
   NoHandleAllocation no_handles(isolate());
-  NoHandleDereference no_deref(isolate());
+  HandleDereferenceGuard no_deref(isolate(), HandleDereferenceGuard::DISALLOW);
 
   ASSERT(last_status() == SUCCEEDED);
   Timer t(this, &time_taken_to_optimize_);
@@ -943,7 +943,9 @@
             new(info->zone()) OptimizingCompiler(*info);
         OptimizingCompiler::Status status = compiler->CreateGraph();
         if (status == OptimizingCompiler::SUCCEEDED) {
-          closure->MarkInRecompileQueue();
+          // Do a scavenge to put off the next scavenge as far as possible.
+          // This may ease the issue that GVN blocks the next scavenge.
+          isolate->heap()->CollectGarbage(NEW_SPACE, "parallel recompile");
           shared->code()->set_profiler_ticks(0);
           info.Detach();
           isolate->optimizing_compiler_thread()->QueueForOptimization(compiler);
@@ -975,7 +977,19 @@
 
 void Compiler::InstallOptimizedCode(OptimizingCompiler* optimizing_compiler) {
   SmartPointer<CompilationInfo> info(optimizing_compiler->info());
-  ASSERT(info->closure()->IsMarkedForInstallingRecompiledCode());
+  // The function may have already been optimized by OSR.  Simply continue.
+  // Except when OSR already disabled optimization for some reason.
+  if (info->shared_info()->optimization_disabled()) {
+    info->SetCode(Handle<Code>(info->shared_info()->code()));
+    InstallFullCode(*info);
+    if (FLAG_trace_parallel_recompilation) {
+      PrintF("  ** aborting optimization for ");
+      info->closure()->PrintName();
+      PrintF(" as it has been disabled.\n");
+    }
+    ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
+    return;
+  }
 
   Isolate* isolate = info->isolate();
   VMState state(isolate, PARALLEL_COMPILER);
@@ -1015,6 +1029,7 @@
   // Optimized code is finally replacing unoptimized code.  Reset the latter's
   // profiler ticks to prevent too soon re-opt after a deopt.
   info->shared_info()->code()->set_profiler_ticks(0);
+  ASSERT(!info->closure()->IsMarkedForInstallingRecompiledCode());
 }
 
 
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index f044328..a20de43 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -54,7 +54,9 @@
                       Handle<Object> exec_state,
                       Handle<Object> event_data,
                       Handle<Value> data) {
-  HandleScope scope;
+  // TODO(svenpanne) There should be a way to retrieve this in the callback.
+  Isolate* isolate = Isolate::GetCurrent();
+  HandleScope scope(isolate);
 
   // Check for handled event.
   if (event != Break && event != Exception && event != AfterCompile) {
@@ -69,7 +71,7 @@
       Function::Cast(*event_data->Get(to_json_fun_name));
   Local<Value> event_json = to_json_fun->Call(event_data, 0, NULL);
   if (try_catch.HasCaught()) {
-    Shell::ReportException(&try_catch);
+    Shell::ReportException(isolate, &try_catch);
     return;
   }
 
@@ -77,7 +79,7 @@
   Handle<Object> details =
       Shell::DebugMessageDetails(Handle<String>::Cast(event_json));
   if (try_catch.HasCaught()) {
-    Shell::ReportException(&try_catch);
+    Shell::ReportException(isolate, &try_catch);
     return;
   }
   String::Utf8Value str(details->Get(String::New("text")));
@@ -93,7 +95,7 @@
   Local<Object> cmd_processor =
       Object::Cast(*fun->Call(exec_state, 0, NULL));
   if (try_catch.HasCaught()) {
-    Shell::ReportException(&try_catch);
+    Shell::ReportException(isolate, &try_catch);
     return;
   }
 
@@ -114,7 +116,7 @@
     Handle<Value> request =
         Shell::DebugCommandToJSONRequest(String::New(command));
     if (try_catch.HasCaught()) {
-      Shell::ReportException(&try_catch);
+      Shell::ReportException(isolate, &try_catch);
       continue;
     }
 
@@ -138,7 +140,7 @@
     args[0] = request;
     Handle<Value> response_val = fun->Call(cmd_processor, kArgc, args);
     if (try_catch.HasCaught()) {
-      Shell::ReportException(&try_catch);
+      Shell::ReportException(isolate, &try_catch);
       continue;
     }
     Handle<String> response = Handle<String>::Cast(response_val);
@@ -146,7 +148,7 @@
     // Convert the debugger response into text details and the running state.
     Handle<Object> response_details = Shell::DebugMessageDetails(response);
     if (try_catch.HasCaught()) {
-      Shell::ReportException(&try_catch);
+      Shell::ReportException(isolate, &try_catch);
       continue;
     }
     String::Utf8Value text_str(response_details->Get(String::New("text")));
@@ -159,8 +161,8 @@
 }
 
 
-void RunRemoteDebugger(int port) {
-  RemoteDebugger debugger(port);
+void RunRemoteDebugger(Isolate* isolate, int port) {
+  RemoteDebugger debugger(isolate, port);
   debugger.Run();
 }
 
@@ -273,15 +275,15 @@
 
 
 void RemoteDebugger::HandleMessageReceived(char* message) {
-  Locker lock(v8::Isolate::GetCurrent());
-  HandleScope scope;
+  Locker lock(isolate_);
+  HandleScope scope(isolate_);
 
   // Print the event details.
   TryCatch try_catch;
   Handle<Object> details =
       Shell::DebugMessageDetails(Handle<String>::Cast(String::New(message)));
   if (try_catch.HasCaught()) {
-    Shell::ReportException(&try_catch);
+    Shell::ReportException(isolate_, &try_catch);
     PrintPrompt();
     return;
   }
@@ -302,15 +304,15 @@
 
 
 void RemoteDebugger::HandleKeyboardCommand(char* command) {
-  Locker lock(v8::Isolate::GetCurrent());
-  HandleScope scope;
+  Locker lock(isolate_);
+  HandleScope scope(isolate_);
 
   // Convert the debugger command to a JSON debugger request.
   TryCatch try_catch;
   Handle<Value> request =
       Shell::DebugCommandToJSONRequest(String::New(command));
   if (try_catch.HasCaught()) {
-    Shell::ReportException(&try_catch);
+    Shell::ReportException(isolate_, &try_catch);
     PrintPrompt();
     return;
   }
diff --git a/src/d8-debug.h b/src/d8-debug.h
index aeff3c1..a6cea2a 100644
--- a/src/d8-debug.h
+++ b/src/d8-debug.h
@@ -43,7 +43,7 @@
 
 // Start the remove debugger connecting to a V8 debugger agent on the specified
 // port.
-void RunRemoteDebugger(int port);
+void RunRemoteDebugger(Isolate* isolate, int port);
 
 // Forward declerations.
 class RemoteDebuggerEvent;
@@ -53,8 +53,9 @@
 // Remote debugging class.
 class RemoteDebugger {
  public:
-  explicit RemoteDebugger(int port)
-      : port_(port),
+  explicit RemoteDebugger(Isolate* isolate, int port)
+      : isolate_(isolate),
+        port_(port),
         event_access_(i::OS::CreateMutex()),
         event_available_(i::OS::CreateSemaphore(0)),
         head_(NULL), tail_(NULL) {}
@@ -79,6 +80,7 @@
   // Get connection to agent in debugged V8.
   i::Socket* conn() { return conn_; }
 
+  Isolate* isolate_;
   int port_;  // Port used to connect to debugger V8.
   i::Socket* conn_;  // Connection to debugger agent in debugged V8.
 
diff --git a/src/d8-posix.cc b/src/d8-posix.cc
index 8a278e4..1be782a 100644
--- a/src/d8-posix.cc
+++ b/src/d8-posix.cc
@@ -449,7 +449,7 @@
 
 // Implementation of the system() function (see d8.h for details).
 Handle<Value> Shell::System(const Arguments& args) {
-  HandleScope scope;
+  HandleScope scope(args.GetIsolate());
   int read_timeout = -1;
   int total_timeout = -1;
   if (!GetTimeouts(args, &read_timeout, &total_timeout)) return v8::Undefined();
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index cc7a3a6..5226364 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -154,7 +154,7 @@
     HandleScope scope;
     Local<String> full_text = String::New(rl_line_buffer, rl_point);
     Handle<Array> completions =
-      Shell::GetCompletions(String::New(text), full_text);
+        Shell::GetCompletions(isolate, String::New(text), full_text);
     current_completions = Persistent<Array>::New(isolate, completions);
     current_index = 0;
   }
diff --git a/src/d8.cc b/src/d8.cc
index 24c89e9..eaebd90 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -93,7 +93,7 @@
 class Symbols {
  public:
   explicit Symbols(Isolate* isolate) : isolate_(isolate) {
-    HandleScope scope;
+    HandleScope scope(isolate);
 #define INIT_SYMBOL(name, value) \
     name##_ = Persistent<String>::New(isolate, String::NewSymbol(value));
     FOR_EACH_SYMBOL(INIT_SYMBOL)
@@ -181,7 +181,8 @@
 
 
 // Executes a string within the current v8 context.
-bool Shell::ExecuteString(Handle<String> source,
+bool Shell::ExecuteString(Isolate* isolate,
+                          Handle<String> source,
                           Handle<Value> name,
                           bool print_result,
                           bool report_exceptions) {
@@ -190,7 +191,7 @@
 #else
   bool FLAG_debugger = false;
 #endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
-  HandleScope handle_scope;
+  HandleScope handle_scope(isolate);
   TryCatch try_catch;
   options.script_executed = true;
   if (FLAG_debugger) {
@@ -201,7 +202,7 @@
   if (script.IsEmpty()) {
     // Print errors that happened during compilation.
     if (report_exceptions && !FLAG_debugger)
-      ReportException(&try_catch);
+      ReportException(isolate, &try_catch);
     return false;
   } else {
     Handle<Value> result = script->Run();
@@ -209,7 +210,7 @@
       ASSERT(try_catch.HasCaught());
       // Print errors that happened during execution.
       if (report_exceptions && !FLAG_debugger)
-        ReportException(&try_catch);
+        ReportException(isolate, &try_catch);
       return false;
     } else {
       ASSERT(!try_catch.HasCaught());
@@ -237,7 +238,7 @@
 
 Handle<Value> Shell::Write(const Arguments& args) {
   for (int i = 0; i < args.Length(); i++) {
-    HandleScope handle_scope;
+    HandleScope handle_scope(args.GetIsolate());
     if (i != 0) {
       printf(" ");
     }
@@ -315,7 +316,7 @@
 
 Handle<Value> Shell::Load(const Arguments& args) {
   for (int i = 0; i < args.Length(); i++) {
-    HandleScope handle_scope;
+    HandleScope handle_scope(args.GetIsolate());
     String::Utf8Value file(args[i]);
     if (*file == NULL) {
       return Throw("Error loading file");
@@ -324,7 +325,11 @@
     if (source.IsEmpty()) {
       return Throw("Error loading file");
     }
-    if (!ExecuteString(source, String::New(*file), false, true)) {
+    if (!ExecuteString(args.GetIsolate(),
+                       source,
+                       String::New(*file),
+                       false,
+                       true)) {
       return Throw("Error executing file");
     }
   }
@@ -389,7 +394,7 @@
       Persistent<Object>::New(isolate, buffer);
   persistent_array.MakeWeak(isolate, data, ExternalArrayWeakCallback);
   persistent_array.MarkIndependent(isolate);
-  V8::AdjustAmountOfExternalAllocatedMemory(length);
+  isolate->AdjustAmountOfExternalAllocatedMemory(length);
 
   buffer->SetIndexedPropertiesToExternalArrayData(
       data, v8::kExternalByteArray, length);
@@ -827,10 +832,10 @@
 void Shell::ExternalArrayWeakCallback(v8::Isolate* isolate,
                                       Persistent<Value> object,
                                       void* data) {
-  HandleScope scope;
+  HandleScope scope(isolate);
   int32_t length =
       object->ToObject()->Get(Symbols::byteLength(isolate))->Uint32Value();
-  V8::AdjustAmountOfExternalAllocatedMemory(-length);
+  isolate->AdjustAmountOfExternalAllocatedMemory(-length);
   delete[] static_cast<uint8_t*>(data);
   object.Dispose(isolate);
 }
@@ -903,8 +908,8 @@
 }
 
 
-void Shell::ReportException(v8::TryCatch* try_catch) {
-  HandleScope handle_scope;
+void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
+  HandleScope handle_scope(isolate);
 #if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
   bool enter_context = !Context::InContext();
   if (enter_context) utility_context_->Enter();
@@ -950,8 +955,10 @@
 
 
 #ifndef V8_SHARED
-Handle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) {
-  HandleScope handle_scope;
+Handle<Array> Shell::GetCompletions(Isolate* isolate,
+                                    Handle<String> text,
+                                    Handle<String> full) {
+  HandleScope handle_scope(isolate);
   Context::Scope context_scope(utility_context_);
   Handle<Object> global = utility_context_->Global();
   Handle<Value> fun = global->Get(String::New("GetCompletions"));
@@ -1094,7 +1101,7 @@
 
 void Shell::InstallUtilityScript(Isolate* isolate) {
   Locker lock(isolate);
-  HandleScope scope;
+  HandleScope scope(isolate);
   // If we use the utility context, we have to set the security tokens so that
   // utility, evaluation and debug context can all access each other.
   utility_context_->SetSecurityToken(Undefined(isolate));
@@ -1272,7 +1279,7 @@
   if (options.test_shell) return;
 #ifndef V8_SHARED
   Locker lock(isolate);
-  HandleScope scope;
+  HandleScope scope(isolate);
   Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
   utility_context_ = Context::New(NULL, global_template);
 
@@ -1446,7 +1453,7 @@
       Persistent<Object>::New(isolate, buffer);
   persistent_buffer.MakeWeak(isolate, data, ExternalArrayWeakCallback);
   persistent_buffer.MarkIndependent(isolate);
-  V8::AdjustAmountOfExternalAllocatedMemory(length);
+  isolate->AdjustAmountOfExternalAllocatedMemory(length);
 
   buffer->SetIndexedPropertiesToExternalArrayData(
       data, kExternalUnsignedByteArray, length);
@@ -1493,16 +1500,16 @@
 void Shell::RunShell(Isolate* isolate) {
   Locker locker(isolate);
   Context::Scope context_scope(evaluation_context_);
-  HandleScope outer_scope;
+  HandleScope outer_scope(isolate);
   Handle<String> name = String::New("(d8)");
   LineEditor* console = LineEditor::Get();
   printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
   console->Open(isolate);
   while (true) {
-    HandleScope inner_scope;
+    HandleScope inner_scope(isolate);
     Handle<String> input = console->Prompt(Shell::kPrompt);
     if (input.IsEmpty()) break;
-    ExecuteString(input, name, true, true);
+    ExecuteString(isolate, input, name, true, true);
   }
   printf("\n");
 }
@@ -1541,13 +1548,13 @@
 
     // Prepare the context for this thread.
     Locker locker(isolate_);
-    HandleScope outer_scope;
+    HandleScope outer_scope(isolate_);
     Persistent<Context> thread_context =
         Shell::CreateEvaluationContext(isolate_);
     Context::Scope context_scope(thread_context);
 
     while ((ptr != NULL) && (*ptr != '\0')) {
-      HandleScope inner_scope;
+      HandleScope inner_scope(isolate_);
       char* filename = ptr;
       ptr = ReadWord(ptr);
 
@@ -1562,7 +1569,7 @@
         Shell::Exit(1);
       }
 
-      Shell::ExecuteString(str, String::New(filename), false, false);
+      Shell::ExecuteString(isolate_, str, String::New(filename), false, false);
     }
 
     thread_context.Dispose(thread_context->GetIsolate());
@@ -1589,10 +1596,10 @@
     const char* arg = argv_[i];
     if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
       // Execute argument given to -e option directly.
-      HandleScope handle_scope;
+      HandleScope handle_scope(isolate);
       Handle<String> file_name = String::New("unnamed");
       Handle<String> source = String::New(argv_[i + 1]);
-      if (!Shell::ExecuteString(source, file_name, false, true)) {
+      if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
         Shell::Exit(1);
       }
       ++i;
@@ -1600,14 +1607,14 @@
       // Ignore other options. They have been parsed already.
     } else {
       // Use all other arguments as names of files to load and run.
-      HandleScope handle_scope;
+      HandleScope handle_scope(isolate);
       Handle<String> file_name = String::New(arg);
       Handle<String> source = ReadFile(isolate, arg);
       if (source.IsEmpty()) {
         printf("Error reading '%s'\n", arg);
         Shell::Exit(1);
       }
-      if (!Shell::ExecuteString(source, file_name, false, true)) {
+      if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
         Shell::Exit(1);
       }
     }
@@ -1642,7 +1649,7 @@
     {
       Isolate::Scope iscope(isolate);
       Locker lock(isolate);
-      HandleScope scope;
+      HandleScope scope(isolate);
       Symbols symbols(isolate);
       Persistent<Context> context = Shell::CreateEvaluationContext(isolate);
       {
@@ -1840,7 +1847,7 @@
 #endif  // V8_SHARED
   {  // NOLINT
     Locker lock(isolate);
-    HandleScope scope;
+    HandleScope scope(isolate);
     Persistent<Context> context = CreateEvaluationContext(isolate);
     if (options.last_run) {
       // Keep using the same context in the interactive shell.
@@ -1936,7 +1943,7 @@
     // Run remote debugger if requested, but never on --test
     if (i::FLAG_remote_debugger && !options.test_shell) {
       InstallUtilityScript(isolate);
-      RunRemoteDebugger(i::FLAG_debugger_port);
+      RunRemoteDebugger(isolate, i::FLAG_debugger_port);
       return 0;
     }
 #endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
diff --git a/src/d8.h b/src/d8.h
index 04c5454..621ac74 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -265,12 +265,13 @@
 #endif  // V8_SHARED
 
  public:
-  static bool ExecuteString(Handle<String> source,
+  static bool ExecuteString(Isolate* isolate,
+                            Handle<String> source,
                             Handle<Value> name,
                             bool print_result,
                             bool report_exceptions);
   static const char* ToCString(const v8::String::Utf8Value& value);
-  static void ReportException(TryCatch* try_catch);
+  static void ReportException(Isolate* isolate, TryCatch* try_catch);
   static Handle<String> ReadFile(Isolate* isolate, const char* name);
   static Persistent<Context> CreateEvaluationContext(Isolate* isolate);
   static int RunMain(Isolate* isolate, int argc, char* argv[]);
@@ -279,7 +280,8 @@
   static void OnExit();
 
 #ifndef V8_SHARED
-  static Handle<Array> GetCompletions(Handle<String> text,
+  static Handle<Array> GetCompletions(Isolate* isolate,
+                                      Handle<String> text,
                                       Handle<String> full);
   static int* LookupCounter(const char* name);
   static void* CreateHistogram(const char* name,
diff --git a/src/debug.cc b/src/debug.cc
index 2821578..1fd3e40 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -3567,7 +3567,8 @@
 
 
 v8::Handle<v8::String> MessageImpl::GetJSON() const {
-  v8::HandleScope scope;
+  v8::HandleScope scope(
+      reinterpret_cast<v8::Isolate*>(event_data_->GetIsolate()));
 
   if (IsEvent()) {
     // Call toJSONProtocol on the debug event object.
diff --git a/src/disassembler.cc b/src/disassembler.cc
index 5d18d68..3830759 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -282,7 +282,7 @@
         if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
           out.AddFormatted(" (id = %d)", static_cast<int>(relocinfo.data()));
         }
-      } else if (rmode == RelocInfo::RUNTIME_ENTRY &&
+      } else if (RelocInfo::IsRuntimeEntry(rmode) &&
                  isolate->deoptimizer_data() != NULL) {
         // A runtime entry reloinfo might be a deoptimization bailout.
         Address addr = relocinfo.target_address();
diff --git a/src/execution.h b/src/execution.h
index c350805..b104180 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -189,8 +189,6 @@
   void Interrupt();
   bool IsTerminateExecution();
   void TerminateExecution();
-  bool IsCodeReadyEvent();
-  void RequestCodeReadyEvent();
 #ifdef ENABLE_DEBUGGER_SUPPORT
   bool IsDebugBreak();
   void DebugBreak();
diff --git a/src/factory.cc b/src/factory.cc
index 9135d54..fece9a0 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -703,9 +703,11 @@
 }
 
 
-Handle<Object> Factory::NewError(const char* maker, const char* type,
-    Vector< Handle<Object> > args) {
-  v8::HandleScope scope;  // Instantiate a closeable HandleScope for EscapeFrom.
+Handle<Object> Factory::NewError(const char* maker,
+                                 const char* type,
+                                 Vector< Handle<Object> > args) {
+  // Instantiate a closeable HandleScope for EscapeFrom.
+  v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate()));
   Handle<FixedArray> array = NewFixedArray(args.length());
   for (int i = 0; i < args.length(); i++) {
     array->set(i, *args[i]);
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 3a2426b..c4b560b 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -166,6 +166,7 @@
 DEFINE_bool(clever_optimizations,
             true,
             "Optimize object size, Array shift, DOM strings and string +")
+DEFINE_bool(pretenure_literals, false, "allocate literals in old space")
 
 // Flags for data representation optimizations
 DEFINE_bool(unbox_double_arrays, true, "automatically unbox arrays of doubles")
diff --git a/src/flags.cc b/src/flags.cc
index bca0eff..ff725ad 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -542,6 +542,7 @@
 void FlagList::EnforceFlagImplications() {
 #define FLAG_MODE_DEFINE_IMPLICATIONS
 #include "flag-definitions.h"
+#undef FLAG_MODE_DEFINE_IMPLICATIONS
 }
 
 } }  // namespace v8::internal
diff --git a/src/handles-inl.h b/src/handles-inl.h
index c1daae2..fd60a35 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -52,10 +52,26 @@
 
 
 template <typename T>
+inline bool Handle<T>::is_identical_to(const Handle<T> other) const {
+  ASSERT(location_ == NULL ||
+         reinterpret_cast<Address>(*location_) != kZapValue);
+#ifdef DEBUG
+  if (FLAG_enable_slow_asserts) {
+    Isolate* isolate = Isolate::Current();
+    CHECK(isolate->AllowHandleDereference() ||
+          Heap::RelocationLock::IsLocked(isolate->heap()) ||
+          !isolate->optimizing_compiler_thread()->IsOptimizerThread());
+  }
+#endif  // DEBUG
+  return *location_ == *other.location_;
+}
+
+
+template <typename T>
 inline T* Handle<T>::operator*() const {
   ASSERT(location_ != NULL);
   ASSERT(reinterpret_cast<Address>(*location_) != kHandleZapValue);
-  SLOW_ASSERT(ISOLATE->allow_handle_deref());
+  SLOW_ASSERT(Isolate::Current()->AllowHandleDereference());
   return *BitCast<T**>(location_);
 }
 
@@ -63,7 +79,7 @@
 inline T** Handle<T>::location() const {
   ASSERT(location_ == NULL ||
          reinterpret_cast<Address>(*location_) != kZapValue);
-  SLOW_ASSERT(ISOLATE->allow_handle_deref());
+  SLOW_ASSERT(Isolate::Current()->AllowHandleDereference());
   return location_;
 }
 
@@ -164,39 +180,19 @@
 }
 
 
-NoHandleDereference::NoHandleDereference(Isolate* isolate)
+HandleDereferenceGuard::HandleDereferenceGuard(Isolate* isolate, State state)
     : isolate_(isolate) {
-  // The guard is set on a per-isolate basis, so it affects all threads.
-  // That's why we can only use it when running without parallel recompilation.
-  if (FLAG_parallel_recompilation) return;
-  old_state_ = isolate->allow_handle_deref();
-  isolate_->set_allow_handle_deref(false);
+  old_state_ = isolate_->AllowHandleDereference();
+  isolate_->SetAllowHandleDereference(state == ALLOW);
 }
 
 
-NoHandleDereference::~NoHandleDereference() {
-  if (FLAG_parallel_recompilation) return;
-  isolate_->set_allow_handle_deref(old_state_);
+HandleDereferenceGuard::~HandleDereferenceGuard() {
+  isolate_->SetAllowHandleDereference(old_state_);
 }
 
-
-AllowHandleDereference::AllowHandleDereference(Isolate* isolate)
-    : isolate_(isolate) {
-  // The guard is set on a per-isolate basis, so it affects all threads.
-  // That's why we can only use it when running without parallel recompilation.
-  if (FLAG_parallel_recompilation) return;
-  old_state_ = isolate->allow_handle_deref();
-  isolate_->set_allow_handle_deref(true);
-}
-
-
-AllowHandleDereference::~AllowHandleDereference() {
-  if (FLAG_parallel_recompilation) return;
-  isolate_->set_allow_handle_deref(old_state_);
-}
 #endif
 
-
 } }  // namespace v8::internal
 
 #endif  // V8_HANDLES_INL_H_
diff --git a/src/handles.h b/src/handles.h
index b0b271c..3e408b7 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -64,9 +64,7 @@
   INLINE(T* operator ->() const) { return operator*(); }
 
   // Check if this handle refers to the exact same object as the other handle.
-  bool is_identical_to(const Handle<T> other) const {
-    return *location_ == *other.location_;
-  }
+  INLINE(bool is_identical_to(const Handle<T> other) const);
 
   // Provides the C++ dereference operator.
   INLINE(T* operator*() const);
@@ -341,29 +339,15 @@
 };
 
 
-class NoHandleDereference BASE_EMBEDDED {
+class HandleDereferenceGuard BASE_EMBEDDED {
  public:
+  enum State { ALLOW, DISALLOW };
 #ifndef DEBUG
-  explicit NoHandleDereference(Isolate* isolate) {}
-  ~NoHandleDereference() {}
+  HandleDereferenceGuard(Isolate* isolate, State state) { }
+  ~HandleDereferenceGuard() { }
 #else
-  explicit inline NoHandleDereference(Isolate* isolate);
-  inline ~NoHandleDereference();
- private:
-  Isolate* isolate_;
-  bool old_state_;
-#endif
-};
-
-
-class AllowHandleDereference BASE_EMBEDDED {
- public:
-#ifndef DEBUG
-  explicit AllowHandleDereference(Isolate* isolate) {}
-  ~AllowHandleDereference() {}
-#else
-  explicit inline AllowHandleDereference(Isolate* isolate);
-  inline ~AllowHandleDereference();
+  inline HandleDereferenceGuard(Isolate* isolate,  State state);
+  inline ~HandleDereferenceGuard();
  private:
   Isolate* isolate_;
   bool old_state_;
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 3644876..9ed65d8 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -653,24 +653,12 @@
     // TODO(yangguo): check that the object is indeed an external string.
     ASSERT(heap_->InNewSpace(obj));
     ASSERT(obj != HEAP->the_hole_value());
-#ifndef ENABLE_LATIN_1
-    if (obj->IsExternalAsciiString()) {
-      ExternalAsciiString* string = ExternalAsciiString::cast(obj);
-      ASSERT(String::IsAscii(string->GetChars(), string->length()));
-    }
-#endif
   }
   for (int i = 0; i < old_space_strings_.length(); ++i) {
     Object* obj = Object::cast(old_space_strings_[i]);
     // TODO(yangguo): check that the object is indeed an external string.
     ASSERT(!heap_->InNewSpace(obj));
     ASSERT(obj != HEAP->the_hole_value());
-#ifndef ENABLE_LATIN_1
-    if (obj->IsExternalAsciiString()) {
-      ExternalAsciiString* string = ExternalAsciiString::cast(obj);
-      ASSERT(String::IsAscii(string->GetChars(), string->length()));
-    }
-#endif
   }
 #endif
 }
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 5f46678..cdd5a07 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -174,6 +174,7 @@
     case kHeapNumber: return "/number/";
     case kNative: return "/native/";
     case kSynthetic: return "/synthetic/";
+    case kContext: return "/context/";
     default: return "???";
   }
 }
@@ -826,7 +827,7 @@
   } else if (object->IsNativeContext()) {
     return AddEntry(object, HeapEntry::kHidden, "system / NativeContext");
   } else if (object->IsContext()) {
-    return AddEntry(object, HeapEntry::kHidden, "system / Context");
+    return AddEntry(object, HeapEntry::kContext, "system / Context");
   } else if (object->IsFixedArray() ||
              object->IsFixedDoubleArray() ||
              object->IsByteArray() ||
@@ -1097,6 +1098,27 @@
 
 
 void V8HeapExplorer::ExtractContextReferences(int entry, Context* context) {
+  if (context == context->declaration_context()) {
+    ScopeInfo* scope_info = context->closure()->shared()->scope_info();
+    // Add context allocated locals.
+    int context_locals = scope_info->ContextLocalCount();
+    for (int i = 0; i < context_locals; ++i) {
+      String* local_name = scope_info->ContextLocalName(i);
+      int idx = Context::MIN_CONTEXT_SLOTS + i;
+      SetContextReference(context, entry, local_name, context->get(idx),
+                          Context::OffsetOfElementAt(idx));
+    }
+    if (scope_info->HasFunctionName()) {
+      String* name = scope_info->FunctionName();
+      VariableMode mode;
+      int idx = scope_info->FunctionContextSlotIndex(name, &mode);
+      if (idx >= 0) {
+        SetContextReference(context, entry, name, context->get(idx),
+                            Context::OffsetOfElementAt(idx));
+      }
+    }
+  }
+
 #define EXTRACT_CONTEXT_FIELD(index, type, name) \
   SetInternalReference(context, entry, #name, context->get(Context::index), \
       FixedArray::OffsetOfElementAt(Context::index));
@@ -1286,26 +1308,6 @@
       SetNativeBindReference(js_obj, entry, reference_name,
                              bindings->get(i));
     }
-  } else {
-    Context* context = func->context()->declaration_context();
-    ScopeInfo* scope_info = context->closure()->shared()->scope_info();
-    // Add context allocated locals.
-    int context_locals = scope_info->ContextLocalCount();
-    for (int i = 0; i < context_locals; ++i) {
-      String* local_name = scope_info->ContextLocalName(i);
-      int idx = Context::MIN_CONTEXT_SLOTS + i;
-      SetClosureReference(js_obj, entry, local_name, context->get(idx));
-    }
-
-    // Add function variable.
-    if (scope_info->HasFunctionName()) {
-      String* name = scope_info->FunctionName();
-      VariableMode mode;
-      int idx = scope_info->FunctionContextSlotIndex(name, &mode);
-      if (idx >= 0) {
-        SetClosureReference(js_obj, entry, name, context->get(idx));
-      }
-    }
   }
 }
 
@@ -1580,16 +1582,18 @@
 }
 
 
-void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
+void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
                                          int parent_entry,
                                          String* reference_name,
-                                         Object* child_obj) {
+                                         Object* child_obj,
+                                         int field_offset) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
     filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
                                parent_entry,
                                collection_->names()->GetName(reference_name),
                                child_entry);
+    IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
   }
 }
 
@@ -2576,7 +2580,8 @@
             JSON_S("regexp") ","
             JSON_S("number") ","
             JSON_S("native") ","
-            JSON_S("synthetic")) ","
+            JSON_S("synthetic") ","
+            JSON_S("context")) ","
         JSON_S("string") ","
         JSON_S("number") ","
         JSON_S("number") ","
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index fe15715..c952381 100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -98,7 +98,8 @@
     kRegExp = v8::HeapGraphNode::kRegExp,
     kHeapNumber = v8::HeapGraphNode::kHeapNumber,
     kNative = v8::HeapGraphNode::kNative,
-    kSynthetic = v8::HeapGraphNode::kSynthetic
+    kSynthetic = v8::HeapGraphNode::kSynthetic,
+    kContext = v8::HeapGraphNode::kContext
   };
   static const int kNoEntry;
 
@@ -479,10 +480,11 @@
   void ExtractElementReferences(JSObject* js_obj, int entry);
   void ExtractInternalReferences(JSObject* js_obj, int entry);
   bool IsEssentialObject(Object* object);
-  void SetClosureReference(HeapObject* parent_obj,
+  void SetContextReference(HeapObject* parent_obj,
                            int parent,
                            String* reference_name,
-                           Object* child);
+                           Object* child,
+                           int field_offset);
   void SetNativeBindReference(HeapObject* parent_obj,
                               int parent,
                               const char* reference_name,
diff --git a/src/heap.cc b/src/heap.cc
index fe1783d..9ee64e3 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3596,10 +3596,6 @@
     return Failure::OutOfMemoryException(0x5);
   }
 
-#ifndef ENABLE_LATIN_1
-  ASSERT(String::IsAscii(resource->data(), static_cast<int>(length)));
-#endif  // ENABLE_LATIN_1
-
   Map* map = external_ascii_string_map();
   Object* result;
   { MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
@@ -5078,17 +5074,6 @@
   String::cast(result)->set_hash_field(String::kEmptyHashField);
   ASSERT_EQ(size, HeapObject::cast(result)->Size());
 
-#ifndef ENABLE_LATIN_1
-#ifdef VERIFY_HEAP
-  if (FLAG_verify_heap) {
-    // Initialize string's content to ensure ASCII-ness (character range 0-127)
-    // as required when verifying the heap.
-    uint8_t* dest = SeqOneByteString::cast(result)->GetChars();
-    memset(dest, 0x0F, length * kCharSize);
-  }
-#endif
-#endif
-
   return result;
 }
 
@@ -6597,6 +6582,9 @@
   store_buffer()->SetUp();
 
   if (FLAG_parallel_recompilation) relocation_mutex_ = OS::CreateMutex();
+#ifdef DEBUG
+  relocation_mutex_locked_ = false;
+#endif  // DEBUG
 
   return true;
 }
diff --git a/src/heap.h b/src/heap.h
index 456e9d8..d26c384 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -590,6 +590,13 @@
     return new_space_.allocation_limit_address();
   }
 
+  Address* OldPointerSpaceAllocationTopAddress() {
+    return old_pointer_space_->allocation_top_address();
+  }
+  Address* OldPointerSpaceAllocationLimitAddress() {
+    return old_pointer_space_->allocation_limit_address();
+  }
+
   // Uncommit unused semi space.
   bool UncommitFromSpace() { return new_space_.UncommitFromSpace(); }
 
@@ -1822,14 +1829,27 @@
     explicit RelocationLock(Heap* heap) : heap_(heap) {
       if (FLAG_parallel_recompilation) {
         heap_->relocation_mutex_->Lock();
+#ifdef DEBUG
+        heap_->relocation_mutex_locked_ = true;
+#endif  // DEBUG
       }
     }
+
     ~RelocationLock() {
       if (FLAG_parallel_recompilation) {
+#ifdef DEBUG
+        heap_->relocation_mutex_locked_ = false;
+#endif  // DEBUG
         heap_->relocation_mutex_->Unlock();
       }
     }
 
+#ifdef DEBUG
+    static bool IsLocked(Heap* heap) {
+      return heap->relocation_mutex_locked_;
+    }
+#endif  // DEBUG
+
    private:
     Heap* heap_;
   };
@@ -2304,6 +2324,9 @@
   MemoryChunk* chunks_queued_for_free_;
 
   Mutex* relocation_mutex_;
+#ifdef DEBUG
+  bool relocation_mutex_locked_;
+#endif  // DEBUG;
 
   friend class Factory;
   friend class GCTracer;
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 8399f0b..20e41bc 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -348,11 +348,7 @@
 }
 
 
-HType HType::TypeFromValue(Isolate* isolate, Handle<Object> value) {
-  // Handle dereferencing is safe here: an object's type as checked below
-  // never changes.
-  AllowHandleDereference allow_handle_deref(isolate);
-
+HType HType::TypeFromValue(Handle<Object> value) {
   HType result = HType::Tagged();
   if (value->IsSmi()) {
     result = HType::Smi();
@@ -1309,10 +1305,7 @@
   }
 
   if (check_ == IS_INTERNALIZED_STRING && value()->IsConstant()) {
-    // Dereferencing is safe here:
-    // an internalized string cannot become non-internalized.
-    AllowHandleDereference allow_handle_deref(isolate());
-    if (HConstant::cast(value())->handle()->IsInternalizedString()) return NULL;
+    if (HConstant::cast(value())->HasInternalizedStringValue()) return NULL;
   }
   return this;
 }
@@ -1814,17 +1807,20 @@
 
 
 HConstant::HConstant(Handle<Object> handle, Representation r)
-    : handle_(handle),
-      has_int32_value_(false),
-      has_double_value_(false) {
-  // Dereferencing here is safe: the value of a number object does not change.
-  AllowHandleDereference allow_handle_deref(Isolate::Current());
+  : handle_(handle),
+    has_int32_value_(false),
+    has_double_value_(false),
+    is_internalized_string_(false),
+    boolean_value_(handle->BooleanValue()) {
   if (handle_->IsNumber()) {
     double n = handle_->Number();
     has_int32_value_ = IsInteger32(n);
     int32_value_ = DoubleToInt32(n);
     double_value_ = n;
     has_double_value_ = true;
+  } else {
+    type_from_value_ = HType::TypeFromValue(handle_);
+    is_internalized_string_ = handle_->IsInternalizedString();
   }
   if (r.IsNone()) {
     if (has_int32_value_) {
@@ -1839,18 +1835,44 @@
 }
 
 
-HConstant::HConstant(int32_t integer_value, Representation r)
+HConstant::HConstant(Handle<Object> handle,
+                     Representation r,
+                     HType type,
+                     bool is_internalize_string,
+                     bool boolean_value)
+    : handle_(handle),
+      has_int32_value_(false),
+      has_double_value_(false),
+      is_internalized_string_(is_internalize_string),
+      boolean_value_(boolean_value),
+      type_from_value_(type) {
+  ASSERT(!handle.is_null());
+  ASSERT(!type.IsUninitialized());
+  ASSERT(!type.IsTaggedNumber());
+  Initialize(r);
+}
+
+
+HConstant::HConstant(int32_t integer_value,
+                     Representation r,
+                     Handle<Object> optional_handle)
     : has_int32_value_(true),
       has_double_value_(true),
+      is_internalized_string_(false),
+      boolean_value_(integer_value != 0),
       int32_value_(integer_value),
       double_value_(FastI2D(integer_value)) {
   Initialize(r);
 }
 
 
-HConstant::HConstant(double double_value, Representation r)
+HConstant::HConstant(double double_value,
+                     Representation r,
+                     Handle<Object> optional_handle)
     : has_int32_value_(IsInteger32(double_value)),
       has_double_value_(true),
+      is_internalized_string_(false),
+      boolean_value_(double_value != 0 && !isnan(double_value)),
       int32_value_(DoubleToInt32(double_value)),
       double_value_(double_value) {
   Initialize(r);
@@ -1869,53 +1891,27 @@
 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
   if (r.IsInteger32() && !has_int32_value_) return NULL;
   if (r.IsDouble() && !has_double_value_) return NULL;
-  if (handle_.is_null()) {
-    ASSERT(has_int32_value_ || has_double_value_);
-    if (has_int32_value_) return new(zone) HConstant(int32_value_, r);
-    return new(zone) HConstant(double_value_, r);
-  }
-  return new(zone) HConstant(handle_, r);
+  if (has_int32_value_) return new(zone) HConstant(int32_value_, r, handle_);
+  if (has_double_value_) return new(zone) HConstant(double_value_, r, handle_);
+  ASSERT(!handle_.is_null());
+  return new(zone) HConstant(
+      handle_, r, type_from_value_, is_internalized_string_, boolean_value_);
 }
 
 
 HConstant* HConstant::CopyToTruncatedInt32(Zone* zone) const {
   if (has_int32_value_) {
-    if (handle_.is_null()) {
-      return new(zone) HConstant(int32_value_, Representation::Integer32());
-    } else {
-      // Re-use the existing Handle if possible.
-      return new(zone) HConstant(handle_, Representation::Integer32());
-    }
-  } else if (has_double_value_) {
-    return new(zone) HConstant(DoubleToInt32(double_value_),
-                               Representation::Integer32());
-  } else {
-    return NULL;
+    return new(zone) HConstant(
+        int32_value_, Representation::Integer32(), handle_);
   }
+  if (has_double_value_) {
+    return new(zone) HConstant(
+        DoubleToInt32(double_value_), Representation::Integer32(), handle_);
+  }
+  return NULL;
 }
 
 
-bool HConstant::ToBoolean() {
-  // Converts the constant's boolean value according to
-  // ECMAScript section 9.2 ToBoolean conversion.
-  if (HasInteger32Value()) return Integer32Value() != 0;
-  if (HasDoubleValue()) {
-    double v = DoubleValue();
-    return v != 0 && !isnan(v);
-  }
-  // Dereferencing is safe: singletons do not change and strings are
-  // immutable.
-  AllowHandleDereference allow_handle_deref(isolate());
-  if (handle_->IsTrue()) return true;
-  if (handle_->IsFalse()) return false;
-  if (handle_->IsUndefined()) return false;
-  if (handle_->IsNull()) return false;
-  if (handle_->IsString() && String::cast(*handle_)->length() == 0) {
-    return false;
-  }
-  return true;
-}
-
 void HConstant::PrintDataTo(StringStream* stream) {
   if (has_int32_value_) {
     stream->Add("%d ", int32_value_);
@@ -2514,6 +2510,12 @@
 }
 
 
+void HInnerAllocatedObject::PrintDataTo(StringStream* stream) {
+  base_object()->PrintNameTo(stream);
+  stream->Add(" offset %d", offset());
+}
+
+
 void HStoreGlobalCell::PrintDataTo(StringStream* stream) {
   stream->Add("[%p] = ", *cell());
   value()->PrintNameTo(stream);
@@ -2594,7 +2596,8 @@
     return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber();
   }
   if (has_double_value_) return HType::HeapNumber();
-  return HType::TypeFromValue(isolate(), handle_);
+  ASSERT(!type_from_value_.IsUninitialized());
+  return type_from_value_;
 }
 
 
@@ -2666,6 +2669,7 @@
 
 void HAllocate::PrintDataTo(StringStream* stream) {
   size()->PrintNameTo(stream);
+  if (!GuaranteedInNewSpace()) stream->Add(" (pretenure)");
 }
 
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index b60a23b..29e8c29 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -122,6 +122,7 @@
   V(HasInstanceTypeAndBranch)                  \
   V(InductionVariableAnnotation)               \
   V(In)                                        \
+  V(InnerAllocatedObject)                      \
   V(InstanceOf)                                \
   V(InstanceOfKnownGlobal)                     \
   V(InstanceSize)                              \
@@ -385,7 +386,7 @@
     return HType(static_cast<Type>(type_ & other.type_));
   }
 
-  bool Equals(const HType& other) {
+  bool Equals(const HType& other) const {
     return type_ == other.type_;
   }
 
@@ -393,66 +394,66 @@
     return Combine(other).Equals(other);
   }
 
-  bool IsTagged() {
+  bool IsTagged() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kTagged) == kTagged);
   }
 
-  bool IsTaggedPrimitive() {
+  bool IsTaggedPrimitive() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
   }
 
-  bool IsTaggedNumber() {
+  bool IsTaggedNumber() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kTaggedNumber) == kTaggedNumber);
   }
 
-  bool IsSmi() {
+  bool IsSmi() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kSmi) == kSmi);
   }
 
-  bool IsHeapNumber() {
+  bool IsHeapNumber() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kHeapNumber) == kHeapNumber);
   }
 
-  bool IsString() {
+  bool IsString() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kString) == kString);
   }
 
-  bool IsBoolean() {
+  bool IsBoolean() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kBoolean) == kBoolean);
   }
 
-  bool IsNonPrimitive() {
+  bool IsNonPrimitive() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kNonPrimitive) == kNonPrimitive);
   }
 
-  bool IsJSArray() {
+  bool IsJSArray() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kJSArray) == kJSArray);
   }
 
-  bool IsJSObject() {
+  bool IsJSObject() const {
     ASSERT(type_ != kUninitialized);
     return ((type_ & kJSObject) == kJSObject);
   }
 
-  bool IsUninitialized() {
+  bool IsUninitialized() const {
     return type_ == kUninitialized;
   }
 
-  bool IsHeapObject() {
+  bool IsHeapObject() const {
     ASSERT(type_ != kUninitialized);
     return IsHeapNumber() || IsString() || IsNonPrimitive();
   }
 
-  static HType TypeFromValue(Isolate* isolate, Handle<Object> value);
+  static HType TypeFromValue(Handle<Object> value);
 
   const char* ToString();
 
@@ -2791,7 +2792,10 @@
   virtual intptr_t Hashcode() {
     ASSERT_ALLOCATION_DISABLED;
     // Dereferencing to use the object's raw address for hashing is safe.
-    AllowHandleDereference allow_handle_deref(isolate());
+    HandleDereferenceGuard allow_handle_deref(isolate(),
+                                              HandleDereferenceGuard::ALLOW);
+    SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) ||
+                !isolate()->optimizing_compiler_thread()->IsOptimizerThread());
     intptr_t hash = 0;
     for (int i = 0; i < prototypes_.length(); i++) {
       hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]);
@@ -3069,8 +3073,17 @@
 class HConstant: public HTemplateInstruction<0> {
  public:
   HConstant(Handle<Object> handle, Representation r);
-  HConstant(int32_t value, Representation r);
-  HConstant(double value, Representation r);
+  HConstant(int32_t value,
+            Representation r,
+            Handle<Object> optional_handle = Handle<Object>::null());
+  HConstant(double value,
+            Representation r,
+            Handle<Object> optional_handle = Handle<Object>::null());
+  HConstant(Handle<Object> handle,
+            Representation r,
+            HType type,
+            bool is_internalized_string,
+            bool boolean_value);
 
   Handle<Object> handle() {
     if (handle_.is_null()) {
@@ -3098,8 +3111,9 @@
     Heap* heap = isolate()->heap();
     // We should have handled minus_zero_value and nan_value in the
     // has_double_value_ clause above.
-    // Dereferencing is safe to compare against singletons.
-    AllowHandleDereference allow_handle_deref(isolate());
+    // Dereferencing is safe to compare against immovable singletons.
+    HandleDereferenceGuard allow_handle_deref(isolate(),
+                                              HandleDereferenceGuard::ALLOW);
     ASSERT(*handle_ != heap->minus_zero_value());
     ASSERT(*handle_ != heap->nan_value());
     return *handle_ == heap->undefined_value() ||
@@ -3148,14 +3162,17 @@
   bool HasStringValue() const {
     if (has_double_value_ || has_int32_value_) return false;
     ASSERT(!handle_.is_null());
-    return handle_->IsString();
+    return type_from_value_.IsString();
   }
   Handle<String> StringValue() const {
     ASSERT(HasStringValue());
     return Handle<String>::cast(handle_);
   }
+  bool HasInternalizedStringValue() const {
+    return HasStringValue() && is_internalized_string_;
+  }
 
-  bool ToBoolean();
+  bool BooleanValue() const { return boolean_value_; }
 
   bool IsUint32() {
     return HasInteger32Value() && (Integer32Value() >= 0);
@@ -3172,7 +3189,10 @@
     } else {
       ASSERT(!handle_.is_null());
       // Dereferencing to use the object's raw address for hashing is safe.
-      AllowHandleDereference allow_handle_deref(isolate());
+      HandleDereferenceGuard allow_handle_deref(isolate(),
+                                                HandleDereferenceGuard::ALLOW);
+      SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) ||
+                 !isolate()->optimizing_compiler_thread()->IsOptimizerThread());
       hash = reinterpret_cast<intptr_t>(*handle_);
     }
 
@@ -3222,8 +3242,11 @@
   // not the converse.
   bool has_int32_value_ : 1;
   bool has_double_value_ : 1;
+  bool is_internalized_string_ : 1;  // TODO(yangguo): make this part of HType.
+  bool boolean_value_ : 1;
   int32_t int32_value_;
   double double_value_;
+  HType type_from_value_;
 };
 
 
@@ -4525,7 +4548,10 @@
   virtual intptr_t Hashcode() {
     ASSERT_ALLOCATION_DISABLED;
     // Dereferencing to use the object's raw address for hashing is safe.
-    AllowHandleDereference allow_handle_deref(isolate());
+    HandleDereferenceGuard allow_handle_deref(isolate(),
+                                              HandleDereferenceGuard::ALLOW);
+    SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) ||
+               !isolate()->optimizing_compiler_thread()->IsOptimizerThread());
     return reinterpret_cast<intptr_t>(*cell_);
   }
 
@@ -4629,7 +4655,6 @@
       : type_(type),
         flags_(flags) {
     ASSERT((flags & CAN_ALLOCATE_IN_OLD_DATA_SPACE) == 0);  // unimplemented
-    ASSERT((flags & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) == 0);  // unimplemented
     SetOperandAt(0, context);
     SetOperandAt(1, size);
     set_representation(Representation::Tagged());
@@ -4684,6 +4709,31 @@
 };
 
 
+class HInnerAllocatedObject: public HTemplateInstruction<1> {
+ public:
+  HInnerAllocatedObject(HValue* value, int offset)
+      : offset_(offset) {
+    ASSERT(value->IsAllocate());
+    SetOperandAt(0, value);
+    set_representation(Representation::Tagged());
+  }
+
+  HValue* base_object() { return OperandAt(0); }
+  int offset() { return offset_; }
+
+  virtual Representation RequiredInputRepresentation(int index) {
+    return Representation::Tagged();
+  }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
+
+ private:
+  int offset_;
+};
+
+
 inline bool StoringValueNeedsWriteBarrier(HValue* value) {
   return !value->type().IsBoolean()
       && !value->type().IsSmi()
@@ -4693,6 +4743,11 @@
 
 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
                                             HValue* new_space_dominator) {
+  if (object->IsInnerAllocatedObject()) {
+    return ReceiverObjectNeedsWriteBarrier(
+        HInnerAllocatedObject::cast(object)->base_object(),
+        new_space_dominator);
+  }
   if (object != new_space_dominator) return true;
   if (object->IsFastLiteral()) return false;
   if (object->IsAllocateObject()) return false;
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 8499b99..9f63c17 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -505,7 +505,9 @@
 
 void HGraph::Verify(bool do_full_verify) const {
   // Allow dereferencing for debug mode verification.
-  AllowHandleDereference allow_handle_deref(isolate());
+  Heap::RelocationLock(isolate()->heap());
+  HandleDereferenceGuard allow_handle_deref(isolate(),
+                                            HandleDereferenceGuard::ALLOW);
   for (int i = 0; i < blocks_.length(); i++) {
     HBasicBlock* block = blocks_.at(i);
 
@@ -585,18 +587,6 @@
 #endif
 
 
-HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer,
-                               Handle<Object> value) {
-  if (!pointer->is_set()) {
-    HConstant* constant = new(zone()) HConstant(value,
-                                                Representation::Tagged());
-    constant->InsertAfter(GetConstantUndefined());
-    pointer->set(constant);
-  }
-  return pointer->get();
-}
-
-
 HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer,
                                     int32_t value) {
   if (!pointer->is_set()) {
@@ -624,19 +614,27 @@
 }
 
 
-HConstant* HGraph::GetConstantTrue() {
-  return GetConstant(&constant_true_, isolate()->factory()->true_value());
+#define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value)                  \
+HConstant* HGraph::GetConstant##Name() {                                       \
+  if (!constant_##name##_.is_set()) {                                          \
+    HConstant* constant = new(zone()) HConstant(                               \
+        isolate()->factory()->name##_value(),                                  \
+        Representation::Tagged(),                                              \
+        htype,                                                                 \
+        false,                                                                 \
+        boolean_value);                                                        \
+    constant->InsertAfter(GetConstantUndefined());                             \
+    constant_##name##_.set(constant);                                          \
+  }                                                                            \
+  return constant_##name##_.get();                                             \
 }
 
 
-HConstant* HGraph::GetConstantFalse() {
-  return GetConstant(&constant_false_, isolate()->factory()->false_value());
-}
+DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true)
+DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false)
+DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
 
-
-HConstant* HGraph::GetConstantHole() {
-  return GetConstant(&constant_hole_, isolate()->factory()->the_hole_value());
-}
+#undef DEFINE_GET_CONSTANT
 
 
 HGraphBuilder::CheckBuilder::CheckBuilder(HGraphBuilder* builder, BailoutId id)
@@ -1075,6 +1073,11 @@
   total_size->ClearFlag(HValue::kCanOverflow);
 
   HAllocate::Flags flags = HAllocate::CAN_ALLOCATE_IN_NEW_SPACE;
+  // TODO(hpayer): add support for old data space
+  if (FLAG_pretenure_literals && !IsFastDoubleElementsKind(kind)) {
+    flags = static_cast<HAllocate::Flags>(
+        flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
+  }
   if (IsFastDoubleElementsKind(kind)) {
     flags = static_cast<HAllocate::Flags>(
         flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
@@ -3711,7 +3714,7 @@
   }
   if (value->IsConstant()) {
     HConstant* constant_value = HConstant::cast(value);
-    if (constant_value->ToBoolean()) {
+    if (constant_value->BooleanValue()) {
       builder->current_block()->Goto(if_true(), builder->function_state());
     } else {
       builder->current_block()->Goto(if_false(), builder->function_state());
@@ -3878,6 +3881,8 @@
 void HGraph::GlobalValueNumbering() {
   // Perform common subexpression elimination and loop-invariant code motion.
   if (FLAG_use_gvn) {
+    // We use objects' raw addresses for identification, so they must not move.
+    Heap::RelocationLock relocation_lock(isolate()->heap());
     HPhase phase("H_Global value numbering", this);
     HGlobalValueNumberer gvn(this, info());
     bool removed_side_effects = gvn.Analyze();
@@ -9241,8 +9246,8 @@
 
     if (left_value->IsConstant()) {
       HConstant* left_constant = HConstant::cast(left_value);
-      if ((is_logical_and && left_constant->ToBoolean()) ||
-          (!is_logical_and && !left_constant->ToBoolean())) {
+      if ((is_logical_and && left_constant->BooleanValue()) ||
+          (!is_logical_and && !left_constant->BooleanValue())) {
         Drop(1);  // left_value.
         CHECK_BAILOUT(VisitForValue(expr->right()));
       }
@@ -10578,13 +10583,17 @@
 
 
 void HTracer::TraceLithium(const char* name, LChunk* chunk) {
-  AllowHandleDereference allow_handle_deref(chunk->isolate());
+  ASSERT(!FLAG_parallel_recompilation);
+  HandleDereferenceGuard allow_handle_deref(chunk->isolate(),
+                                            HandleDereferenceGuard::ALLOW);
   Trace(name, chunk->graph(), chunk);
 }
 
 
 void HTracer::TraceHydrogen(const char* name, HGraph* graph) {
-  AllowHandleDereference allow_handle_deref(graph->isolate());
+  ASSERT(!FLAG_parallel_recompilation);
+  HandleDereferenceGuard allow_handle_deref(graph->isolate(),
+                                            HandleDereferenceGuard::ALLOW);
   Trace(name, graph, NULL);
 }
 
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 47fd69d..a35d9a6 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -386,8 +386,6 @@
   }
 
  private:
-  HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
-                         Handle<Object> value);
   HConstant* GetConstantInt32(SetOncePointer<HConstant>* pointer,
                               int32_t integer_value);
 
@@ -422,7 +420,7 @@
   SetOncePointer<HConstant> constant_minus1_;
   SetOncePointer<HConstant> constant_true_;
   SetOncePointer<HConstant> constant_false_;
-  SetOncePointer<HConstant> constant_hole_;
+  SetOncePointer<HConstant> constant_the_hole_;
   SetOncePointer<HArgumentsObject> arguments_object_;
 
   SetOncePointer<HBasicBlock> osr_loop_entry_;
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 51e16fd..afb1c03 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -1033,12 +1033,7 @@
   if (initial_capacity > 0) {
     size += FixedArray::SizeFor(initial_capacity);
   }
-  __ AllocateInNewSpace(size,
-                        result,
-                        scratch2,
-                        scratch3,
-                        gc_required,
-                        TAG_OBJECT);
+  __ Allocate(size, result, scratch2, scratch3, gc_required, TAG_OBJECT);
 
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
@@ -1618,12 +1613,12 @@
 
   // Allocate a JSValue and put the tagged pointer into eax.
   Label gc_required;
-  __ AllocateInNewSpace(JSValue::kSize,
-                        eax,  // Result.
-                        ecx,  // New allocation top (we ignore it).
-                        no_reg,
-                        &gc_required,
-                        TAG_OBJECT);
+  __ Allocate(JSValue::kSize,
+              eax,  // Result.
+              ecx,  // New allocation top (we ignore it).
+              no_reg,
+              &gc_required,
+              TAG_OBJECT);
 
   // Set the map.
   __ LoadGlobalFunctionInitialMap(edi, ecx);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 1b27540..88207c4 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -145,7 +145,7 @@
   Counters* counters = masm->isolate()->counters();
 
   Label gc;
-  __ AllocateInNewSpace(JSFunction::kSize, eax, ebx, ecx, &gc, TAG_OBJECT);
+  __ Allocate(JSFunction::kSize, eax, ebx, ecx, &gc, TAG_OBJECT);
 
   __ IncrementCounter(counters->fast_new_closure_total(), 1);
 
@@ -273,8 +273,8 @@
   // Try to allocate the context in new space.
   Label gc;
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
-  __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize,
-                        eax, ebx, ecx, &gc, TAG_OBJECT);
+  __ Allocate((length * kPointerSize) + FixedArray::kHeaderSize,
+              eax, ebx, ecx, &gc, TAG_OBJECT);
 
   // Get the function from the stack.
   __ mov(ecx, Operand(esp, 1 * kPointerSize));
@@ -321,8 +321,7 @@
   // Try to allocate the context in new space.
   Label gc;
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
-  __ AllocateInNewSpace(FixedArray::SizeFor(length),
-                        eax, ebx, ecx, &gc, TAG_OBJECT);
+  __ Allocate(FixedArray::SizeFor(length), eax, ebx, ecx, &gc, TAG_OBJECT);
 
   // Get the function or sentinel from the stack.
   __ mov(ecx, Operand(esp, 1 * kPointerSize));
@@ -414,7 +413,7 @@
   if (mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS) {
     flags = static_cast<AllocationFlags>(DOUBLE_ALIGNMENT | flags);
   }
-  __ AllocateInNewSpace(size, eax, ebx, edx, fail, flags);
+  __ Allocate(size, eax, ebx, edx, fail, flags);
 
   if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     __ mov(FieldOperand(eax, allocation_info_start),
@@ -3301,7 +3300,7 @@
 
   StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -3320,7 +3319,7 @@
 
   StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -3340,7 +3339,7 @@
   StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss,
                                          support_wrapper_);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -3404,7 +3403,7 @@
 
   __ bind(&miss);
 
-  StubCompiler::GenerateStoreMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -6739,12 +6738,8 @@
   // Compare lengths -  strings up to min-length are equal.
   __ bind(&compare_lengths);
   __ test(length_delta, length_delta);
-#ifndef ENABLE_LATIN_1
-  __ j(not_zero, &result_not_equal, Label::kNear);
-#else
   Label length_not_equal;
   __ j(not_zero, &length_not_equal, Label::kNear);
-#endif
 
   // Result is EQUAL.
   STATIC_ASSERT(EQUAL == 0);
@@ -6753,19 +6748,13 @@
   __ ret(0);
 
   Label result_greater;
-#ifdef ENABLE_LATIN_1
   Label result_less;
   __ bind(&length_not_equal);
   __ j(greater, &result_greater, Label::kNear);
   __ jmp(&result_less, Label::kNear);
-#endif
   __ bind(&result_not_equal);
-#ifndef ENABLE_LATIN_1
-  __ j(greater, &result_greater, Label::kNear);
-#else
   __ j(above, &result_greater, Label::kNear);
   __ bind(&result_less);
-#endif
 
   // Result is LESS.
   __ Set(eax, Immediate(Smi::FromInt(LESS)));
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 25c5e65..ebc3a2b 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1489,7 +1489,7 @@
   __ bind(&materialized);
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 4ae6603..0cd5f1f 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4195,6 +4195,13 @@
 }
 
 
+void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
+  Register result = ToRegister(instr->result());
+  Register base = ToRegister(instr->base_object());
+  __ lea(result, Operand(base, instr->offset()));
+}
+
+
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Register object = ToRegister(instr->object());
   Register value = ToRegister(instr->value());
@@ -5461,12 +5468,8 @@
   // the constructor's prototype changes, but instance size and property
   // counts remain unchanged (if slack tracking finished).
   ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress());
-  __ AllocateInNewSpace(instance_size,
-                        result,
-                        no_reg,
-                        scratch,
-                        deferred->entry(),
-                        TAG_OBJECT);
+  __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(),
+              TAG_OBJECT);
 
   __ bind(deferred->exit());
   if (FLAG_debug_code) {
@@ -5556,7 +5559,10 @@
   }
   if (instr->size()->IsConstantOperand()) {
     int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
-    __ AllocateInNewSpace(size, result, temp, no_reg, deferred->entry(), flags);
+    if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
+      flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
+    }
+    __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
     __ AllocateInNewSpace(size, result, temp, no_reg, deferred->entry(), flags);
@@ -5795,7 +5801,7 @@
   // Allocate all objects that are part of the literal in one big
   // allocation. This avoids multiple limit checks.
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
@@ -5885,7 +5891,7 @@
   __ bind(&materialized);
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 69a0e7f..4a380ef 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -292,6 +292,13 @@
 }
 
 
+void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  base_object()->PrintTo(stream);
+  stream->Add(" + %d", offset());
+}
+
+
 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
   stream->Add("#%d / ", arity());
 }
@@ -718,10 +725,12 @@
 LUnallocated* LChunkBuilder::TempRegister() {
   LUnallocated* operand =
       new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
-  operand->set_virtual_register(allocator_->GetVirtualRegister());
+  int vreg = allocator_->GetVirtualRegister();
   if (!allocator_->AllocationOk()) {
-    Abort("Not enough virtual registers (temps).");
+    Abort("Out of virtual registers while trying to allocate temp register.");
+    return NULL;
   }
+  operand->set_virtual_register(vreg);
   return operand;
 }
 
@@ -984,7 +993,7 @@
   if (value->EmitAtUses()) {
     ASSERT(value->IsConstant());
     ASSERT(!value->representation().IsDouble());
-    HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
+    HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
     return new(zone()) LGoto(successor->block_id());
@@ -1081,6 +1090,15 @@
 }
 
 
+LInstruction* LChunkBuilder::DoInnerAllocatedObject(
+    HInnerAllocatedObject* inner_object) {
+  LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
+  LInnerAllocatedObject* result =
+    new(zone()) LInnerAllocatedObject(base_object);
+  return DefineAsRegister(result);
+}
+
+
 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
   return instr->HasNoUses()
       ? NULL
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 318a51f..0e36474 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -184,7 +184,8 @@
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
   V(WrapReceiver)                               \
-  V(Drop)
+  V(Drop)                                       \
+  V(InnerAllocatedObject)
 
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
@@ -1681,6 +1682,22 @@
 };
 
 
+class LInnerAllocatedObject: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LInnerAllocatedObject(LOperand* base_object) {
+    inputs_[0] = base_object;
+  }
+
+  LOperand* base_object() { return inputs_[0]; }
+  int offset() { return hydrogen()->offset(); }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
+  DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+};
+
+
 class LThisFunction: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 494a1bf..debf64a 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -618,6 +618,7 @@
 
 
 void MacroAssembler::DispatchMap(Register obj,
+                                 Register unused,
                                  Handle<Map> map,
                                  Handle<Code> success,
                                  SmiCheckType smi_check_type) {
@@ -1214,8 +1215,8 @@
 void MacroAssembler::LoadAllocationTopHelper(Register result,
                                              Register scratch,
                                              AllocationFlags flags) {
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
 
   // Just return if allocation top is already known.
   if ((flags & RESULT_CONTAINS_TOP) != 0) {
@@ -1223,7 +1224,7 @@
     ASSERT(scratch.is(no_reg));
 #ifdef DEBUG
     // Assert that result actually contains top on entry.
-    cmp(result, Operand::StaticVariable(new_space_allocation_top));
+    cmp(result, Operand::StaticVariable(allocation_top));
     Check(equal, "Unexpected allocation top");
 #endif
     return;
@@ -1231,39 +1232,40 @@
 
   // Move address of new object to result. Use scratch register if available.
   if (scratch.is(no_reg)) {
-    mov(result, Operand::StaticVariable(new_space_allocation_top));
+    mov(result, Operand::StaticVariable(allocation_top));
   } else {
-    mov(scratch, Immediate(new_space_allocation_top));
+    mov(scratch, Immediate(allocation_top));
     mov(result, Operand(scratch, 0));
   }
 }
 
 
 void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
-                                               Register scratch) {
+                                               Register scratch,
+                                               AllocationFlags flags) {
   if (emit_debug_code()) {
     test(result_end, Immediate(kObjectAlignmentMask));
     Check(zero, "Unaligned allocation in new space");
   }
 
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
 
   // Update new top. Use scratch if available.
   if (scratch.is(no_reg)) {
-    mov(Operand::StaticVariable(new_space_allocation_top), result_end);
+    mov(Operand::StaticVariable(allocation_top), result_end);
   } else {
     mov(Operand(scratch, 0), result_end);
   }
 }
 
 
-void MacroAssembler::AllocateInNewSpace(int object_size,
-                                        Register result,
-                                        Register result_end,
-                                        Register scratch,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
+void MacroAssembler::Allocate(int object_size,
+                              Register result,
+                              Register result_end,
+                              Register scratch,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
@@ -1287,6 +1289,7 @@
   // Align the next allocation. Storing the filler map without checking top is
   // always safe because the limit of the heap is always aligned.
   if ((flags & DOUBLE_ALIGNMENT) != 0) {
+    ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
     ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
     Label aligned;
     test(result, Immediate(kDoubleAlignmentMask));
@@ -1299,20 +1302,20 @@
 
   Register top_reg = result_end.is_valid() ? result_end : result;
 
-  // Calculate new top and bail out if new space is exhausted.
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  // Calculate new top and bail out if space is exhausted.
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
 
   if (!top_reg.is(result)) {
     mov(top_reg, result);
   }
   add(top_reg, Immediate(object_size));
   j(carry, gc_required);
-  cmp(top_reg, Operand::StaticVariable(new_space_allocation_limit));
+  cmp(top_reg, Operand::StaticVariable(allocation_limit));
   j(above, gc_required);
 
   // Update allocation top.
-  UpdateAllocationTopHelper(top_reg, scratch);
+  UpdateAllocationTopHelper(top_reg, scratch, flags);
 
   // Tag result if requested.
   bool tag_result = (flags & TAG_OBJECT) != 0;
@@ -1340,6 +1343,7 @@
     Label* gc_required,
     AllocationFlags flags) {
   ASSERT((flags & SIZE_IN_WORDS) == 0);
+  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -1399,7 +1403,7 @@
   }
 
   // Update allocation top.
-  UpdateAllocationTopHelper(result_end, scratch);
+  UpdateAllocationTopHelper(result_end, scratch, flags);
 }
 
 
@@ -1410,6 +1414,7 @@
                                         Label* gc_required,
                                         AllocationFlags flags) {
   ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
+  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -1459,7 +1464,7 @@
   }
 
   // Update allocation top.
-  UpdateAllocationTopHelper(result_end, scratch);
+  UpdateAllocationTopHelper(result_end, scratch, flags);
 }
 
 
@@ -1482,12 +1487,8 @@
                                         Register scratch2,
                                         Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(HeapNumber::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map.
   mov(FieldOperand(result, HeapObject::kMapOffset),
@@ -1575,12 +1576,8 @@
   ASSERT(length > 0);
 
   // Allocate ASCII string in new space.
-  AllocateInNewSpace(SeqOneByteString::SizeFor(length),
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2,
+           gc_required, TAG_OBJECT);
 
   // Set the map, length and hash field.
   mov(FieldOperand(result, HeapObject::kMapOffset),
@@ -1597,12 +1594,8 @@
                                         Register scratch2,
                                         Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   mov(FieldOperand(result, HeapObject::kMapOffset),
@@ -1615,12 +1608,8 @@
                                              Register scratch2,
                                              Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   mov(FieldOperand(result, HeapObject::kMapOffset),
@@ -1633,12 +1622,8 @@
                                           Register scratch2,
                                           Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   mov(FieldOperand(result, HeapObject::kMapOffset),
@@ -1651,12 +1636,8 @@
                                                Register scratch2,
                                                Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   mov(FieldOperand(result, HeapObject::kMapOffset),
@@ -1830,7 +1811,8 @@
 
 
 void MacroAssembler::TailCallStub(CodeStub* stub) {
-  ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe());
+  ASSERT(allow_stub_calls_ ||
+         stub->CompilingCallsToThisStubIsGCSafe(isolate()));
   jmp(stub->GetCode(isolate()), RelocInfo::CODE_TARGET);
 }
 
@@ -1843,7 +1825,7 @@
 
 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
   if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
-  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe();
+  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe(isolate());
 }
 
 
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 05ad82d..8dd4120 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -410,6 +410,7 @@
   // specified target if equal. Skip the smi check if not required (object is
   // known to be a heap object)
   void DispatchMap(Register obj,
+                   Register unused,
                    Handle<Map> map,
                    Handle<Code> success,
                    SmiCheckType smi_check_type);
@@ -564,22 +565,22 @@
   // ---------------------------------------------------------------------------
   // Allocation support
 
-  // Allocate an object in new space. If the new space is exhausted control
-  // continues at the gc_required label. The allocated object is returned in
-  // result and end of the new object is returned in result_end. The register
-  // scratch can be passed as no_reg in which case an additional object
-  // reference will be added to the reloc info. The returned pointers in result
-  // and result_end have not yet been tagged as heap objects. If
-  // result_contains_top_on_entry is true the content of result is known to be
-  // the allocation top on entry (could be result_end from a previous call to
-  // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
+  // Allocate an object in new space or old pointer space. If the given space
+  // is exhausted control continues at the gc_required label. The allocated
+  // object is returned in result and end of the new object is returned in
+  // result_end. The register scratch can be passed as no_reg in which case
+  // an additional object reference will be added to the reloc info. The
+  // returned pointers in result and result_end have not yet been tagged as
+  // heap objects. If result_contains_top_on_entry is true the content of
+  // result is known to be the allocation top on entry (could be result_end
+  // from a previous call). If result_contains_top_on_entry is true scratch
   // should be no_reg as it is never used.
-  void AllocateInNewSpace(int object_size,
-                          Register result,
-                          Register result_end,
-                          Register scratch,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(int object_size,
+                Register result,
+                Register result_end,
+                Register scratch,
+                Label* gc_required,
+                AllocationFlags flags);
 
   void AllocateInNewSpace(int header_size,
                           ScaleFactor element_size,
@@ -910,7 +911,10 @@
   void LoadAllocationTopHelper(Register result,
                                Register scratch,
                                AllocationFlags flags);
-  void UpdateAllocationTopHelper(Register result_end, Register scratch);
+
+  void UpdateAllocationTopHelper(Register result_end,
+                                 Register scratch,
+                                 AllocationFlags flags);
 
   // Helper for PopHandleScope.  Allowed to perform a GC and returns
   // NULL if gc_allowed.  Does not perform a GC if !gc_allowed, and
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index bb0e0ad..d8f2e8f 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -344,9 +344,6 @@
     __ or_(eax, 0x20);  // Convert match character to lower-case.
     __ lea(ecx, Operand(eax, -'a'));
     __ cmp(ecx, static_cast<int32_t>('z' - 'a'));  // Is eax a lowercase letter?
-#ifndef ENABLE_LATIN_1
-    __ j(above, &fail);  // Weren't letters anyway.
-#else
     Label convert_capture;
     __ j(below_equal, &convert_capture);  // In range 'a'-'z'.
     // Latin-1: Check for values in range [224,254] but not 247.
@@ -356,7 +353,6 @@
     __ cmp(ecx, Immediate(247 - 224));  // Check for 247.
     __ j(equal, &fail);
     __ bind(&convert_capture);
-#endif
     // Also convert capture character.
     __ movzx_b(ecx, Operand(edx, 0));
     __ or_(ecx, 0x20);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index d0b7881..f7e795e 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -369,19 +369,6 @@
 }
 
 
-// Load a fast property out of a holder object (src). In-object properties
-// are loaded directly otherwise the property is loaded from the properties
-// fixed array.
-void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
-                                            Register dst,
-                                            Register src,
-                                            Handle<JSObject> holder,
-                                            PropertyIndex index) {
-  DoGenerateFastPropertyLoad(
-      masm, dst, src, index.is_inobject(holder), index.translate(holder));
-}
-
-
 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
                                               Register dst,
                                               Register src,
@@ -729,28 +716,13 @@
 };
 
 
-void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
-  Handle<Code> code = (kind == Code::LOAD_IC)
-      ? masm->isolate()->builtins()->LoadIC_Miss()
-      : masm->isolate()->builtins()->KeyedLoadIC_Miss();
-  __ jmp(code, RelocInfo::CODE_TARGET);
-}
-
-
-void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
-  Handle<Code> code = (kind == Code::STORE_IC)
-      ? masm->isolate()->builtins()->StoreIC_Miss()
-      : masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(code, RelocInfo::CODE_TARGET);
-}
-
-
-void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
-  Handle<Code> code =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ jmp(code, RelocInfo::CODE_TARGET);
+void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
+                                                Label* label,
+                                                Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ bind(label);
+    __ mov(this->name(), Immediate(name));
+  }
 }
 
 
@@ -763,9 +735,11 @@
                                       Handle<Name> name,
                                       Register receiver_reg,
                                       Register name_reg,
+                                      Register value_reg,
                                       Register scratch1,
                                       Register scratch2,
-                                      Label* miss_label) {
+                                      Label* miss_label,
+                                      Label* miss_restore_name) {
   LookupResult lookup(masm->isolate());
   object->Lookup(*name, &lookup);
   if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
@@ -800,16 +774,8 @@
       } while (holder->GetPrototype()->IsJSObject());
     }
     // We need an extra register, push
-    __ push(name_reg);
-    Label miss_pop, done_check;
     CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, &miss_pop);
-    __ jmp(&done_check);
-    __ bind(&miss_pop);
-    __ pop(name_reg);
-    __ jmp(miss_label);
-    __ bind(&done_check);
-    __ pop(name_reg);
+                    scratch1, scratch2, name, miss_restore_name);
   }
 
   // Stub never generated for non-global objects that require access
@@ -857,11 +823,11 @@
   if (index < 0) {
     // Set the property straight into the object.
     int offset = object->map()->instance_size() + (index * kPointerSize);
-    __ mov(FieldOperand(receiver_reg, offset), eax);
+    __ mov(FieldOperand(receiver_reg, offset), value_reg);
 
     // Update the write barrier for the array address.
     // Pass the value being stored in the now unused name_reg.
-    __ mov(name_reg, eax);
+    __ mov(name_reg, value_reg);
     __ RecordWriteField(receiver_reg,
                         offset,
                         name_reg,
@@ -876,7 +842,7 @@
 
     // Update the write barrier for the array address.
     // Pass the value being stored in the now unused name_reg.
-    __ mov(name_reg, eax);
+    __ mov(name_reg, value_reg);
     __ RecordWriteField(scratch1,
                         offset,
                         name_reg,
@@ -885,6 +851,7 @@
   }
 
   // Return the value (register eax).
+  ASSERT(value_reg.is(eax));
   __ ret(0);
 }
 
@@ -933,15 +900,16 @@
   }
 }
 
-#undef __
-#define __ ACCESS_MASM(masm())
 
-
-void StubCompiler::GenerateTailCall(Handle<Code> code) {
+void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
   __ jmp(code, RelocInfo::CODE_TARGET);
 }
 
 
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
                                        Register object_reg,
                                        Handle<JSObject> holder,
@@ -1062,7 +1030,7 @@
   if (!miss->is_unused()) {
     __ jmp(success);
     __ bind(miss);
-    GenerateLoadMiss(masm(), kind());
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
   }
 }
 
@@ -2581,66 +2549,27 @@
 }
 
 
-Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                  int index,
-                                                  Handle<Map> transition,
-                                                  Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  // Generate store field code.  Trashes the name register.
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     edx, ecx, ebx, edi,
-                     &miss);
-  // Handle store cache miss.
-  __ bind(&miss);
-  __ mov(ecx, Immediate(name));  // restore name
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreCallback(
     Handle<Name> name,
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<JSObject> holder,
     Handle<ExecutableAccessorInfo> callback) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
+  Label miss, miss_restore_name;
   // Check that the maps haven't changed, preserving the value register.
-  __ push(eax);
-  __ JumpIfSmi(edx, &miss);
-  CheckPrototypes(receiver, edx, holder, ebx, eax, edi, name, &miss);
-  __ pop(eax);  // restore value
+  __ JumpIfSmi(receiver(), &miss);
+  CheckPrototypes(object, receiver(), holder,
+                  scratch1(), this->name(), scratch2(),
+                  name, &miss_restore_name);
 
   // Stub never generated for non-global objects that require access checks.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
 
-  __ pop(ebx);  // remove the return address
-  __ push(edx);  // receiver
-  __ push(Immediate(callback));  // callback info
-  __ push(ecx);  // name
-  __ push(eax);  // value
-  __ push(ebx);  // restore return address
+  __ pop(scratch1());  // remove the return address
+  __ push(receiver());
+  __ Push(callback);
+  __ Push(name);
+  __ push(value());
+  __ push(scratch1());  // restore return address
 
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
@@ -2648,13 +2577,12 @@
   __ TailCallExternalReference(store_callback_property, 4, 1);
 
   // Handle store cache miss.
+  GenerateRestoreName(masm(), &miss_restore_name, name);
   __ bind(&miss);
-  __ pop(eax);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
+  return GetICCode(kind(), Code::CALLBACKS, name);
 }
 
 
@@ -2704,67 +2632,30 @@
 #define __ ACCESS_MASM(masm())
 
 
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
-    Handle<Name> name,
-    Handle<JSObject> receiver,
-    Handle<JSObject> holder,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  // Check that the maps haven't changed, preserving the name register.
-  __ push(ecx);
-  __ JumpIfSmi(edx, &miss);
-  CheckPrototypes(receiver, edx, holder, ebx, ecx, edi, name, &miss);
-  __ pop(ecx);
-
-  GenerateStoreViaSetter(masm(), setter);
-
-  __ bind(&miss);
-  __ pop(ecx);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the object hasn't changed.
-  __ CheckMap(edx, Handle<Map>(receiver->map()),
+  __ CheckMap(receiver(), Handle<Map>(object->map()),
               &miss, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform global security token check if needed.
-  if (receiver->IsJSGlobalProxy()) {
+  if (object->IsJSGlobalProxy()) {
     __ CheckAccessGlobalProxy(edx, ebx, &miss);
   }
 
   // Stub never generated for non-global objects that require access
   // checks.
-  ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
+  ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
 
-  __ pop(ebx);  // remove the return address
-  __ push(edx);  // receiver
-  __ push(ecx);  // name
-  __ push(eax);  // value
-  __ push(Immediate(Smi::FromInt(strict_mode_)));
-  __ push(ebx);  // restore return address
+  __ pop(scratch1());  // remove the return address
+  __ push(receiver());
+  __ push(this->name());
+  __ push(value());
+  __ push(Immediate(Smi::FromInt(strict_mode())));
+  __ push(scratch1());  // restore return address
 
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
@@ -2773,11 +2664,10 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::INTERCEPTOR, name);
+  return GetICCode(kind(), Code::INTERCEPTOR, name);
 }
 
 
@@ -2785,22 +2675,17 @@
     Handle<GlobalObject> object,
     Handle<JSGlobalPropertyCell> cell,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the global has not changed.
-  __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
+  __ cmp(FieldOperand(receiver(), HeapObject::kMapOffset),
          Immediate(Handle<Map>(object->map())));
   __ j(not_equal, &miss);
 
   // Compute the cell operand to use.
-  __ mov(ebx, Immediate(cell));
-  Operand cell_operand = FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset);
+  __ mov(scratch1(), Immediate(cell));
+  Operand cell_operand =
+      FieldOperand(scratch1(), JSGlobalPropertyCell::kValueOffset);
 
   // Check that the value in the cell is not the hole. If it is, this
   // cell could have been deleted and reintroducing the global needs
@@ -2810,7 +2695,7 @@
   __ j(equal, &miss);
 
   // Store the value in the cell.
-  __ mov(cell_operand, eax);
+  __ mov(cell_operand, value());
   // No write barrier here, because cells are always rescanned.
 
   // Return the value (register eax).
@@ -2821,77 +2706,10 @@
   // Handle store cache miss.
   __ bind(&miss);
   __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, name);
-}
-
-
-Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                       int index,
-                                                       Handle<Map> transition,
-                                                       Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->keyed_store_field(), 1);
-
-  // Check that the name has not changed.
-  __ cmp(ecx, Immediate(name));
-  __ j(not_equal, &miss);
-
-  // Generate store field code.  Trashes the name register.
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     edx, ecx, ebx, edi,
-                     &miss);
-
-  // Handle store cache miss.
-  __ bind(&miss);
-  __ DecrementCounter(counters->keyed_store_field(), 1);
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
-Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
-  Handle<Code> stub =
-      KeyedStoreElementStub(is_jsarray,
-                            elements_kind,
-                            store_mode_).GetCode(isolate());
-
-  __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
-
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string());
+  return GetICCode(kind(), Code::NORMAL, name);
 }
 
 
@@ -2899,34 +2717,27 @@
     MapHandleList* receiver_maps,
     CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
-  // ----------- S t a t e -------------
-  //  -- eax    : value
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
   Label miss;
-  __ JumpIfSmi(edx, &miss, Label::kNear);
-  __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
-  // ebx: receiver->map().
+  __ JumpIfSmi(receiver(), &miss, Label::kNear);
+  __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_maps->length(); ++i) {
-    __ cmp(edi, receiver_maps->at(i));
+    __ cmp(scratch1(), receiver_maps->at(i));
     if (transitioned_maps->at(i).is_null()) {
       __ j(equal, handler_stubs->at(i));
     } else {
       Label next_map;
       __ j(not_equal, &next_map, Label::kNear);
-      __ mov(ebx, Immediate(transitioned_maps->at(i)));
+      __ mov(transition_map(), Immediate(transitioned_maps->at(i)));
       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
   }
   __ bind(&miss);
-  Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
+  return GetICCode(
+      kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -2964,6 +2775,20 @@
 }
 
 
+Register* StoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg };
+  return registers;
+}
+
+
+Register* KeyedStoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { edx, ecx, eax, ebx, edi, no_reg };
+  return registers;
+}
+
+
 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
                                               Register name_reg,
                                               Label* miss) {
@@ -2972,6 +2797,14 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
+                                               Register name_reg,
+                                               Label* miss) {
+  __ cmp(name_reg, Immediate(name));
+  __ j(not_equal, miss);
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
@@ -3050,34 +2883,6 @@
 }
 
 
-Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : key
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  if (receiver_map->has_fast_elements() ||
-      receiver_map->has_external_array_elements()) {
-    Handle<Code> stub = KeyedLoadFastElementStub(
-        receiver_map->instance_type() == JS_ARRAY_TYPE,
-        elements_kind).GetCode(isolate());
-    __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
-  } else {
-    Handle<Code> stub =
-        KeyedLoadDictionaryElementStub().GetCode(isolate());
-    __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK);
-  }
-
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
-}
-
-
 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
     MapHandleList* receiver_maps,
     CodeHandleList* handlers,
@@ -3100,7 +2905,7 @@
   }
 
   __ bind(&miss);
-  GenerateLoadMiss(masm(), kind());
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
   InlineCacheState state =
@@ -3156,8 +2961,8 @@
   __ cmp(ecx, Immediate(instance_size));
   __ Check(equal, "Instance size of initial map changed.");
 #endif
-  __ AllocateInNewSpace(instance_size, edx, ecx, no_reg,
-                        &generic_stub_call, NO_ALLOCATION_FLAGS);
+  __ Allocate(instance_size, edx, ecx, no_reg, &generic_stub_call,
+              NO_ALLOCATION_FLAGS);
 
   // Allocated the JSObject, now initialize the fields and add the heap tag.
   // ebx: initial map
@@ -3284,10 +3089,7 @@
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
-
-  Handle<Code> slow_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_Slow();
-  __ jmp(slow_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
 
   __ bind(&miss_force_generic);
   // ----------- S t a t e -------------
@@ -3295,10 +3097,7 @@
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
-
-  Handle<Code> miss_force_generic_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
 }
 
 
@@ -3516,9 +3315,7 @@
   //  -- edx    : receiver
   //  -- esp[0] : return address
   // -----------------------------------
-
-  Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
 
   // ----------- S t a t e -------------
   //  -- eax    : value
@@ -3528,9 +3325,7 @@
   // -----------------------------------
 
   __ bind(&miss_force_generic);
-  Handle<Code> miss_ic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ jmp(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 }
 
 
@@ -3606,14 +3401,11 @@
 
   // Handle store cache miss, replacing the ic with the generic stub.
   __ bind(&miss_force_generic);
-  Handle<Code> ic_force_generic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   // Handle transition to other elements kinds without using the generic stub.
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Handle transition requiring the array to grow.
@@ -3631,7 +3423,7 @@
     __ j(not_equal, &check_capacity);
 
     int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, edi, ebx, ecx, &prepare_slow, TAG_OBJECT);
+    __ Allocate(size, edi, ebx, ecx, &prepare_slow, TAG_OBJECT);
     // Restore the key, which is known to be the array length.
 
     // eax: value
@@ -3684,8 +3476,7 @@
     __ mov(ecx, Immediate(0));
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ jmp(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }
 
@@ -3734,14 +3525,11 @@
 
   // Handle store cache miss, replacing the ic with the generic stub.
   __ bind(&miss_force_generic);
-  Handle<Code> ic_force_generic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   // Handle transition to other elements kinds without using the generic stub.
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Handle transition requiring the array to grow.
@@ -3767,7 +3555,7 @@
     __ j(not_equal, &check_capacity);
 
     int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, edi, ebx, ecx, &prepare_slow, TAG_OBJECT);
+    __ Allocate(size, edi, ebx, ecx, &prepare_slow, TAG_OBJECT);
 
     // Restore the key, which is known to be the array length.
     __ mov(ecx, Immediate(0));
@@ -3822,8 +3610,7 @@
     __ mov(ecx, Immediate(0));
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ jmp(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }
 
diff --git a/src/isolate.cc b/src/isolate.cc
index 5f7b3f2..fb9cab1 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -944,11 +944,7 @@
   if (decision != UNKNOWN) return decision == YES;
 
   // Get named access check callback
-  // TODO(dcarney): revert
-  Map* map = receiver->map();
-  CHECK(map->IsMap());
-  CHECK(map->constructor()->IsJSFunction());
-  JSFunction* constructor = JSFunction::cast(map->constructor());
+  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
   if (!constructor->shared()->IsApiFunction()) return false;
 
   Object* data_obj =
@@ -1713,7 +1709,8 @@
   memset(code_kind_statistics_, 0,
          sizeof(code_kind_statistics_[0]) * Code::NUMBER_OF_KINDS);
 
-  allow_handle_deref_ = true;
+  allow_compiler_thread_handle_deref_ = true;
+  allow_execution_thread_handle_deref_ = true;
 #endif
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
@@ -2321,6 +2318,33 @@
 }
 
 
+#ifdef DEBUG
+bool Isolate::AllowHandleDereference() {
+  if (allow_execution_thread_handle_deref_ &&
+      allow_compiler_thread_handle_deref_) {
+    // Short-cut to avoid polling thread id.
+    return true;
+  }
+  if (FLAG_parallel_recompilation &&
+      optimizing_compiler_thread()->IsOptimizerThread()) {
+    return allow_compiler_thread_handle_deref_;
+  } else {
+    return allow_execution_thread_handle_deref_;
+  }
+}
+
+
+void Isolate::SetAllowHandleDereference(bool allow) {
+  if (FLAG_parallel_recompilation &&
+      optimizing_compiler_thread()->IsOptimizerThread()) {
+    allow_compiler_thread_handle_deref_ = allow;
+  } else {
+    allow_execution_thread_handle_deref_ = allow;
+  }
+}
+#endif
+
+
 HStatistics* Isolate::GetHStatistics() {
   if (hstatistics() == NULL) set_hstatistics(new HStatistics());
   return hstatistics();
diff --git a/src/isolate.h b/src/isolate.h
index e6f6d16..d6770cc 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -988,8 +988,9 @@
 
   int* code_kind_statistics() { return code_kind_statistics_; }
 
-  bool allow_handle_deref() { return allow_handle_deref_; }
-  void set_allow_handle_deref(bool allow) { allow_handle_deref_ = allow; }
+  bool AllowHandleDereference();
+
+  void SetAllowHandleDereference(bool allow);
 #endif
 
 #if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
@@ -1305,7 +1306,8 @@
   JSObject::SpillInformation js_spill_information_;
   int code_kind_statistics_[Code::NUMBER_OF_KINDS];
 
-  bool allow_handle_deref_;
+  bool allow_compiler_thread_handle_deref_;
+  bool allow_execution_thread_handle_deref_;
 #endif
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index e73b1d4..b490521 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -2512,11 +2512,7 @@
     // For 2-character preloads in ASCII mode or 1-character preloads in
     // TWO_BYTE mode we also use a 16 bit load with zero extend.
     if (details->characters() == 2 && compiler->ascii()) {
-#ifndef ENABLE_LATIN_1
-      if ((mask & 0x7f7f) == 0xffff) need_mask = false;
-#else
       if ((mask & 0xffff) == 0xffff) need_mask = false;
-#endif
     } else if (details->characters() == 1 && !compiler->ascii()) {
       if ((mask & 0xffff) == 0xffff) need_mask = false;
     } else {
@@ -2794,17 +2790,12 @@
 
 // We need to check for the following characters: 0x39c 0x3bc 0x178.
 static inline bool RangeContainsLatin1Equivalents(CharacterRange range) {
-#ifdef ENABLE_LATIN_1
   // TODO(dcarney): this could be a lot more efficient.
   return range.Contains(0x39c) ||
       range.Contains(0x3bc) || range.Contains(0x178);
-#else
-  return false;
-#endif
 }
 
 
-#ifdef ENABLE_LATIN_1
 static bool RangesContainLatin1Equivalents(ZoneList<CharacterRange>* ranges) {
   for (int i = 0; i < ranges->length(); i++) {
     // TODO(dcarney): this could be a lot more efficient.
@@ -2812,7 +2803,6 @@
   }
   return false;
 }
-#endif
 
 
 RegExpNode* TextNode::FilterASCII(int depth, bool ignore_case) {
@@ -2826,11 +2816,6 @@
     if (elm.type == TextElement::ATOM) {
       Vector<const uc16> quarks = elm.data.u_atom->data();
       for (int j = 0; j < quarks.length(); j++) {
-#ifndef ENABLE_LATIN_1
-        if (quarks[j] > String::kMaxOneByteCharCode) {
-          return set_replacement(NULL);
-        }
-#else
         uint16_t c = quarks[j];
         if (c <= String::kMaxOneByteCharCode) continue;
         if (!ignore_case) return set_replacement(NULL);
@@ -2842,7 +2827,6 @@
         // Convert quark to Latin-1 in place.
         uint16_t* copy = const_cast<uint16_t*>(quarks.start());
         copy[j] = converted;
-#endif
       }
     } else {
       ASSERT(elm.type == TextElement::CHAR_CLASS);
@@ -2857,19 +2841,15 @@
         if (range_count != 0 &&
             ranges->at(0).from() == 0 &&
             ranges->at(0).to() >= String::kMaxOneByteCharCode) {
-#ifdef ENABLE_LATIN_1
           // This will be handled in a later filter.
           if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
-#endif
           return set_replacement(NULL);
         }
       } else {
         if (range_count == 0 ||
             ranges->at(0).from() > String::kMaxOneByteCharCode) {
-#ifdef ENABLE_LATIN_1
           // This will be handled in a later filter.
           if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
-#endif
           return set_replacement(NULL);
         }
       }
diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
index e3b9a88..6ee9ef2 100644
--- a/src/lithium-allocator.cc
+++ b/src/lithium-allocator.cc
@@ -839,8 +839,9 @@
         ASSERT(!cur_input->IsUsedAtStart());
 
         LUnallocated* input_copy = cur_input->CopyUnconstrained(zone());
-        cur_input->set_virtual_register(GetVirtualRegister());
+        int vreg = GetVirtualRegister();
         if (!AllocationOk()) return;
+        cur_input->set_virtual_register(vreg);
 
         if (RequiredRegisterKind(input_copy->virtual_register()) ==
             DOUBLE_REGISTERS) {
@@ -1924,6 +1925,7 @@
     LiveRange* tail = SplitBetween(current,
                                    current->Start(),
                                    block_pos[reg].InstructionStart());
+    if (!AllocationOk()) return;
     AddToUnhandledSorted(tail);
   }
 
@@ -1954,6 +1956,7 @@
       } else {
         SpillBetween(range, split_pos, next_pos->pos());
       }
+      if (!AllocationOk()) return;
       ActiveToHandled(range);
       --i;
     }
@@ -1972,6 +1975,7 @@
           next_intersection = Min(next_intersection, next_pos->pos());
           SpillBetween(range, split_pos, next_intersection);
         }
+        if (!AllocationOk()) return;
         InactiveToHandled(range);
         --i;
       }
@@ -1997,8 +2001,9 @@
   ASSERT(pos.IsInstructionStart() ||
          !chunk_->instructions()->at(pos.InstructionIndex())->IsControl());
 
-  LiveRange* result = LiveRangeFor(GetVirtualRegister());
+  int vreg = GetVirtualRegister();
   if (!AllocationOk()) return NULL;
+  LiveRange* result = LiveRangeFor(vreg);
   range->SplitAt(pos, result, zone_);
   return result;
 }
@@ -2075,6 +2080,7 @@
         second_part,
         second_part->Start().InstructionEnd(),
         end.PrevInstruction().InstructionEnd());
+    if (!AllocationOk()) return;
 
     ASSERT(third_part != second_part);
 
diff --git a/src/lithium-allocator.h b/src/lithium-allocator.h
index 2ca8537..0e24d54 100644
--- a/src/lithium-allocator.h
+++ b/src/lithium-allocator.h
@@ -427,8 +427,10 @@
   Zone* zone() const { return zone_; }
 
   int GetVirtualRegister() {
-    if (next_virtual_register_ > LUnallocated::kMaxVirtualRegisters) {
+    if (next_virtual_register_ >= LUnallocated::kMaxVirtualRegisters) {
       allocation_ok_ = false;
+      // Maintain the invariant that we return something below the maximum.
+      return 0;
     }
     return next_virtual_register_++;
   }
diff --git a/src/log.h b/src/log.h
index 27d517a..5c121bc 100644
--- a/src/log.h
+++ b/src/log.h
@@ -139,6 +139,7 @@
   V(REG_EXP_TAG,                    "RegExp")                           \
   V(SCRIPT_TAG,                     "Script")                           \
   V(STORE_IC_TAG,                   "StoreIC")                          \
+  V(STORE_POLYMORPHIC_IC_TAG,       "StorePolymorphicIC")               \
   V(STUB_TAG,                       "Stub")                             \
   V(NATIVE_FUNCTION_TAG,            "Function")                         \
   V(NATIVE_LAZY_COMPILE_TAG,        "LazyCompile")                      \
diff --git a/src/macro-assembler.h b/src/macro-assembler.h
index 9e71123..55dccfa 100644
--- a/src/macro-assembler.h
+++ b/src/macro-assembler.h
@@ -49,7 +49,9 @@
   // words instead of bytes.
   SIZE_IN_WORDS = 1 << 2,
   // Align the allocation to a multiple of kDoubleSize
-  DOUBLE_ALIGNMENT = 1 << 3
+  DOUBLE_ALIGNMENT = 1 << 3,
+  // Directly allocate in old pointer space
+  PRETENURE_OLD_POINTER_SPACE = 1 << 4
 };
 
 
@@ -168,6 +170,26 @@
 
 #endif  // DEBUG
 
+
+class AllocationUtils {
+ public:
+  static ExternalReference GetAllocationTopReference(
+      Isolate* isolate, AllocationFlags flags) {
+    return ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) ?
+        ExternalReference::old_pointer_space_allocation_top_address(isolate) :
+        ExternalReference::new_space_allocation_top_address(isolate);
+  }
+
+
+  static ExternalReference GetAllocationLimitReference(
+      Isolate* isolate, AllocationFlags flags) {
+    return ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) ?
+        ExternalReference::old_pointer_space_allocation_limit_address(isolate) :
+        ExternalReference::new_space_allocation_limit_address(isolate);
+  }
+};
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_MACRO_ASSEMBLER_H_
diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h
index 1dad815..9c9f611 100644
--- a/src/mips/assembler-mips-inl.h
+++ b/src/mips/assembler-mips-inl.h
@@ -139,14 +139,14 @@
 
 
 Address RelocInfo::target_address() {
-  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
+  ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
   return Assembler::target_address_at(pc_);
 }
 
 
 Address RelocInfo::target_address_address() {
   ASSERT(IsCodeTarget(rmode_) ||
-         rmode_ == RUNTIME_ENTRY ||
+         IsRuntimeEntry(rmode_) ||
          rmode_ == EMBEDDED_OBJECT ||
          rmode_ == EXTERNAL_REFERENCE);
   // Read the address of the word containing the target_address in an
@@ -174,7 +174,7 @@
 
 
 void RelocInfo::set_target_address(Address target, WriteBarrierMode mode) {
-  ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY);
+  ASSERT(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
   Assembler::set_target_address_at(pc_, target);
   if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) {
     Object* target_code = Code::GetCodeFromTargetAddress(target);
@@ -372,7 +372,7 @@
              Isolate::Current()->debug()->has_break_points()) {
     visitor->VisitDebugTarget(this);
 #endif
-  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
+  } else if (RelocInfo::IsRuntimeEntry(mode)) {
     visitor->VisitRuntimeEntry(this);
   }
 }
@@ -399,7 +399,7 @@
               IsPatchedDebugBreakSlotSequence()))) {
     StaticVisitor::VisitDebugTarget(heap, this);
 #endif
-  } else if (mode == RelocInfo::RUNTIME_ENTRY) {
+  } else if (RelocInfo::IsRuntimeEntry(mode)) {
     StaticVisitor::VisitRuntimeEntry(this);
   }
 }
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 1af9d3f..f398a4d 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -4585,7 +4585,7 @@
 
   StubCompiler::GenerateLoadArrayLength(masm, receiver, a3, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -4614,7 +4614,7 @@
 
   StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3, t0, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -4645,7 +4645,7 @@
                                          support_wrapper_);
 
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -4715,7 +4715,7 @@
 
   __ bind(&miss);
 
-  StubCompiler::GenerateStoreMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 3cd89b8..400f26d 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -1268,12 +1268,12 @@
             __ sll(result, left, shift);
           } else if (IsPowerOf2(constant_abs - 1)) {
             int32_t shift = WhichPowerOf2(constant_abs - 1);
-            __ sll(result, left, shift);
-            __ Addu(result, result, left);
+            __ sll(scratch, left, shift);
+            __ Addu(result, scratch, left);
           } else if (IsPowerOf2(constant_abs + 1)) {
             int32_t shift = WhichPowerOf2(constant_abs + 1);
-            __ sll(result, left, shift);
-            __ Subu(result, result, left);
+            __ sll(scratch, left, shift);
+            __ Subu(result, scratch, left);
           }
 
           // Correct the sign of the result is the constant is negative.
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index b233d51..f04a462 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -668,8 +668,12 @@
 LUnallocated* LChunkBuilder::TempRegister() {
   LUnallocated* operand =
       new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
-  operand->set_virtual_register(allocator_->GetVirtualRegister());
-  if (!allocator_->AllocationOk()) Abort("Not enough virtual registers.");
+  int vreg = allocator_->GetVirtualRegister();
+  if (!allocator_->AllocationOk()) {
+    Abort("Out of virtual registers while trying to allocate temp register.");
+    return NULL;
+  }
+  operand->set_virtual_register(vreg);
   return operand;
 }
 
@@ -928,7 +932,7 @@
 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
   HValue* value = instr->value();
   if (value->EmitAtUses()) {
-    HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
+    HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
     return new(zone()) LGoto(successor->block_id());
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 242fa1e..af436b6 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -3960,7 +3960,8 @@
 
 
 void MacroAssembler::TailCallStub(CodeStub* stub) {
-  ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe());
+  ASSERT(allow_stub_calls_ ||
+         stub->CompilingCallsToThisStubIsGCSafe(isolate()));
   Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET);
 }
 
@@ -4078,7 +4079,7 @@
 
 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
   if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
-  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe();
+  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe(isolate());
 }
 
 
@@ -4914,8 +4915,8 @@
     push(object);
     lw(object, FieldMemOperand(object, HeapObject::kMapOffset));
     lbu(object, FieldMemOperand(object, Map::kInstanceTypeOffset));
-    pop(object);
     Check(le, "Operand is not a name", object, Operand(LAST_NAME_TYPE));
+    pop(object);
   }
 }
 
diff --git a/src/mips/regexp-macro-assembler-mips.cc b/src/mips/regexp-macro-assembler-mips.cc
index ce2d635..036cbb1 100644
--- a/src/mips/regexp-macro-assembler-mips.cc
+++ b/src/mips/regexp-macro-assembler-mips.cc
@@ -341,9 +341,6 @@
     __ Or(t0, t0, Operand(0x20));  // Also convert input character.
     __ Branch(&fail, ne, t0, Operand(a3));
     __ Subu(a3, a3, Operand('a'));
-#ifndef ENABLE_LATIN_1
-    __ Branch(&fail, hi, a3, Operand('z' - 'a'));  // Is a3 a lowercase letter?
-#else
     __ Branch(&loop_check, ls, a3, Operand('z' - 'a'));
     // Latin-1: Check for values in range [224,254] but not 247.
     __ Subu(a3, a3, Operand(224 - 'a'));
@@ -351,7 +348,6 @@
     __ Branch(&fail, hi, a3, Operand(254 - 224));
     // Check for 247.
     __ Branch(&fail, eq, a3, Operand(247 - 224));
-#endif
 
     __ bind(&loop_check);
     __ Branch(&loop, lt, a0, Operand(a1));
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 4d58c75..959da8e 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -307,19 +307,6 @@
 }
 
 
-// Load a fast property out of a holder object (src). In-object properties
-// are loaded directly otherwise the property is loaded from the properties
-// fixed array.
-void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
-                                            Register dst,
-                                            Register src,
-                                            Handle<JSObject> holder,
-                                            PropertyIndex index) {
-  DoGenerateFastPropertyLoad(
-      masm, dst, src, index.is_inobject(holder), index.translate(holder));
-}
-
-
 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
                                               Register dst,
                                               Register src,
@@ -433,9 +420,11 @@
                                       Handle<Name> name,
                                       Register receiver_reg,
                                       Register name_reg,
+                                      Register value_reg,
                                       Register scratch1,
                                       Register scratch2,
-                                      Label* miss_label) {
+                                      Label* miss_label,
+                                      Label* miss_restore_name) {
   // a0 : value.
   Label exit;
 
@@ -472,17 +461,8 @@
         holder = JSObject::cast(holder->GetPrototype());
       } while (holder->GetPrototype()->IsJSObject());
     }
-    // We need an extra register, push
-    __ push(name_reg);
-    Label miss_pop, done_check;
     CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, &miss_pop);
-    __ jmp(&done_check);
-    __ bind(&miss_pop);
-    __ pop(name_reg);
-    __ jmp(miss_label);
-    __ bind(&done_check);
-    __ pop(name_reg);
+                    scratch1, scratch2, name, miss_restore_name);
   }
 
   // Stub never generated for non-global objects that require access
@@ -528,14 +508,14 @@
   if (index < 0) {
     // Set the property straight into the object.
     int offset = object->map()->instance_size() + (index * kPointerSize);
-    __ sw(a0, FieldMemOperand(receiver_reg, offset));
+    __ sw(value_reg, FieldMemOperand(receiver_reg, offset));
 
     // Skip updating write barrier if storing a smi.
-    __ JumpIfSmi(a0, &exit, scratch1);
+    __ JumpIfSmi(value_reg, &exit);
 
     // Update the write barrier for the array address.
     // Pass the now unused name_reg as a scratch register.
-    __ mov(name_reg, a0);
+    __ mov(name_reg, value_reg);
     __ RecordWriteField(receiver_reg,
                         offset,
                         name_reg,
@@ -548,14 +528,14 @@
     // Get the properties array.
     __ lw(scratch1,
           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    __ sw(a0, FieldMemOperand(scratch1, offset));
+    __ sw(value_reg, FieldMemOperand(scratch1, offset));
 
     // Skip updating write barrier if storing a smi.
-    __ JumpIfSmi(a0, &exit);
+    __ JumpIfSmi(value_reg, &exit);
 
     // Update the write barrier for the array address.
     // Ok to clobber receiver_reg and name_reg, since we return.
-    __ mov(name_reg, a0);
+    __ mov(name_reg, value_reg);
     __ RecordWriteField(scratch1,
                         offset,
                         name_reg,
@@ -565,27 +545,20 @@
   }
 
   // Return the value (register v0).
+  ASSERT(value_reg.is(a0));
   __ bind(&exit);
   __ mov(v0, a0);
   __ Ret();
 }
 
 
-void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
-  Handle<Code> code = (kind == Code::LOAD_IC)
-      ? masm->isolate()->builtins()->LoadIC_Miss()
-      : masm->isolate()->builtins()->KeyedLoadIC_Miss();
-  __ Jump(code, RelocInfo::CODE_TARGET);
-}
-
-
-void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
-  Handle<Code> code = (kind == Code::STORE_IC)
-      ? masm->isolate()->builtins()->StoreIC_Miss()
-      : masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(code, RelocInfo::CODE_TARGET);
+void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
+                                                Label* label,
+                                                Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ bind(label);
+    __ li(this->name(), Operand(name));
+  }
 }
 
 
@@ -1064,15 +1037,15 @@
 }
 
 
-#undef __
-#define __ ACCESS_MASM(masm())
-
-
-void StubCompiler::GenerateTailCall(Handle<Code> code) {
+void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
   __ Jump(code, RelocInfo::CODE_TARGET);
 }
 
 
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
                                        Register object_reg,
                                        Handle<JSObject> holder,
@@ -1190,7 +1163,7 @@
   if (!miss->is_unused()) {
     __ Branch(success);
     __ bind(miss);
-    GenerateLoadMiss(masm(), kind());
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
   }
 }
 
@@ -2629,38 +2602,6 @@
 }
 
 
-Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                  int index,
-                                                  Handle<Map> transition,
-                                                  Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : receiver
-  //  -- a2    : name
-  //  -- ra    : return address
-  // -----------------------------------
-  Label miss;
-
-  // Name register might be clobbered.
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     a1, a2, a3, t0,
-                     &miss);
-  __ bind(&miss);
-  __ li(a2, Operand(Handle<Name>(name)));  // Restore name.
-  Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreCallback(
     Handle<Name> name,
     Handle<JSObject> receiver,
@@ -2693,11 +2634,10 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
+  return GetICCode(kind(), Code::CALLBACKS, name);
 }
 
 
@@ -2767,11 +2707,10 @@
   GenerateStoreViaSetter(masm(), setter);
 
   __ bind(&miss);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
+  return GetICCode(kind(), Code::CALLBACKS, name);
 }
 
 
@@ -2801,7 +2740,7 @@
 
   __ Push(a1, a2, a0);  // Receiver, name, value.
 
-  __ li(a0, Operand(Smi::FromInt(strict_mode_)));
+  __ li(a0, Operand(Smi::FromInt(strict_mode())));
   __ push(a0);  // Strict mode.
 
   // Do tail-call to the runtime system.
@@ -2812,11 +2751,10 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::INTERCEPTOR, name);
+  return GetICCode(kind(), Code::INTERCEPTOR, name);
 }
 
 
@@ -2857,11 +2795,10 @@
   // Handle store cache miss.
   __ bind(&miss);
   __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3);
-  Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, name);
+  return GetICCode(kind(), Code::NORMAL, name);
 }
 
 
@@ -2898,6 +2835,20 @@
 }
 
 
+Register* StoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { a1, a2, a0, a3, t0, t1 };
+  return registers;
+}
+
+
+Register* KeyedStoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { a2, a1, a0, a3, t0, t1 };
+  return registers;
+}
+
+
 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
                                               Register name_reg,
                                               Label* miss) {
@@ -2905,6 +2856,13 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
+                                               Register name_reg,
+                                               Label* miss) {
+  __ Branch(miss, ne, name_reg, Operand(name));
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
@@ -2998,8 +2956,7 @@
     __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
   }
 
-  Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
   return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
@@ -3029,7 +2986,7 @@
   }
 
   __ bind(&miss);
-  GenerateLoadMiss(masm(), kind());
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
   InlineCacheState state =
@@ -3038,47 +2995,6 @@
 }
 
 
-Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                       int index,
-                                                       Handle<Map> transition,
-                                                       Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- a0    : value
-  //  -- a1    : key
-  //  -- a2    : receiver
-  //  -- ra    : return address
-  // -----------------------------------
-
-  Label miss;
-
-  Counters* counters = masm()->isolate()->counters();
-  __ IncrementCounter(counters->keyed_store_field(), 1, a3, t0);
-
-  // Check that the name has not changed.
-  __ Branch(&miss, ne, a1, Operand(name));
-
-  // a3 is used as scratch register. a1 and a2 keep their values if a jump to
-  // the miss label is generated.
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     a2, a1, a3, t0,
-                     &miss);
-  __ bind(&miss);
-
-  __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0);
-  Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
     Handle<Map> receiver_map) {
   // ----------- S t a t e -------------
@@ -3097,11 +3013,10 @@
 
   __ DispatchMap(a2, a3, receiver_map, stub, DO_SMI_CHECK);
 
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string());
+  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
 }
 
 
@@ -3135,11 +3050,11 @@
   }
 
   __ bind(&miss);
-  Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
+  return GetICCode(
+      kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -3327,9 +3242,7 @@
   //  -- a0     : key
   //  -- a1     : receiver
   // -----------------------------------
-  Handle<Code> slow_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_Slow();
-  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
 
   // Miss case, call the runtime.
   __ bind(&miss_force_generic);
@@ -3339,10 +3252,7 @@
   //  -- a0     : key
   //  -- a1     : receiver
   // -----------------------------------
-
-  Handle<Code> miss_ic =
-     masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
 }
 
 
@@ -3796,9 +3706,7 @@
   //  -- a0     : key
   //  -- a1     : receiver
   // -----------------------------------
-  Handle<Code> slow_ic =
-      masm->isolate()->builtins()->KeyedStoreIC_Slow();
-  __ Jump(slow_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
 
   // Miss case, call the runtime.
   __ bind(&miss_force_generic);
@@ -3808,10 +3716,7 @@
   //  -- a0     : key
   //  -- a1     : receiver
   // -----------------------------------
-
-  Handle<Code> miss_ic =
-     masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ Jump(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 }
 
 
@@ -3902,13 +3807,10 @@
   __ Ret();
 
   __ bind(&miss_force_generic);
-  Handle<Code> ic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Grow the array by a single element if possible.
@@ -3972,8 +3874,7 @@
     __ jmp(&finish_store);
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ Jump(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }
 
@@ -4049,13 +3950,10 @@
 
   // Handle store cache miss, replacing the ic with the generic stub.
   __ bind(&miss_force_generic);
-  Handle<Code> ic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Grow the array by a single element if possible.
@@ -4138,8 +4036,7 @@
     __ jmp(&finish_store);
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ Jump(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }
 
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index a3665e9..abfe693 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -318,11 +318,12 @@
             "\nException thrown while compiling natives - see above.\n\n");
     exit(1);
   }
+  Isolate* isolate = context->GetIsolate();
   if (i::FLAG_extra_code != NULL) {
     context->Enter();
     // Capture 100 frames if anything happens.
     V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
-    HandleScope scope;
+    HandleScope scope(isolate);
     const char* name = i::FLAG_extra_code;
     FILE* file = i::OS::FOpen(name, "rb");
     if (file == NULL) {
@@ -375,7 +376,7 @@
     context->Exit();
   }
   // Make sure all builtin scripts are cached.
-  { HandleScope scope;
+  { HandleScope scope(isolate);
     for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
       i::Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
     }
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 3cb3d24..82a71a5 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -486,19 +486,10 @@
     ConsString::cast(this)->ConsStringVerify();
   } else if (IsSlicedString()) {
     SlicedString::cast(this)->SlicedStringVerify();
-  } else if (IsSeqOneByteString()) {
-    SeqOneByteString::cast(this)->SeqOneByteStringVerify();
   }
 }
 
 
-void SeqOneByteString::SeqOneByteStringVerify() {
-#ifndef ENABLE_LATIN_1
-  CHECK(String::IsAscii(GetChars(), length()));
-#endif
-}
-
-
 void ConsString::ConsStringVerify() {
   CHECK(this->first()->IsString());
   CHECK(this->second() == GetHeap()->empty_string() ||
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 7ddfdfc..9a520b2 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -357,12 +357,7 @@
 
 bool String::HasOnlyAsciiChars() {
   uint32_t type = map()->instance_type();
-#ifndef ENABLE_LATIN_1
-  return (type & kStringEncodingMask) == kOneByteStringTag ||
-         (type & kAsciiDataHintMask) == kAsciiDataHintTag;
-#else
   return (type & kAsciiDataHintMask) == kAsciiDataHintTag;
-#endif
 }
 
 
diff --git a/src/objects.cc b/src/objects.cc
index a57e264..3de981c 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -768,8 +768,6 @@
         // that even though we may not actually end up loading the named
         // property from the current object, we still check that we have
         // access to it.
-        // TODO(dcarney): revert.
-        CHECK(current->IsJSObject());
         JSObject* checked = JSObject::cast(current);
         if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
           return checked->GetPropertyWithFailedAccessCheck(receiver,
@@ -9110,7 +9108,7 @@
     } else if (last_comment != NULL &&
                bailout_id == Deoptimizer::GetDeoptimizationId(
                    info->target_address(), Deoptimizer::EAGER)) {
-      CHECK(info->rmode() == RelocInfo::RUNTIME_ENTRY);
+      CHECK(RelocInfo::IsRuntimeEntry(info->rmode()));
       PrintF("            %s\n", last_comment);
       return;
     }
diff --git a/src/objects.h b/src/objects.h
index 9d52554..89ebf21 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -7796,8 +7796,6 @@
   // Q.v. String::kMaxLength which is the maximal size of concatenated strings.
   static const int kMaxLength = (kMaxSize - kHeaderSize);
 
-  DECLARE_VERIFIER(SeqOneByteString)
-
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqOneByteString);
 };
diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
index abcce7b..b982b94 100644
--- a/src/optimizing-compiler-thread.cc
+++ b/src/optimizing-compiler-thread.cc
@@ -76,29 +76,20 @@
 
 
 void OptimizingCompilerThread::CompileNext() {
-  Heap::RelocationLock relocation_lock(isolate_->heap());
   OptimizingCompiler* optimizing_compiler = NULL;
   input_queue_.Dequeue(&optimizing_compiler);
   Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(-1));
 
-  ASSERT(optimizing_compiler->info()->closure()->IsInRecompileQueue());
-
+  // The function may have already been optimized by OSR.  Simply continue.
   OptimizingCompiler::Status status = optimizing_compiler->OptimizeGraph();
+  USE(status);   // Prevent an unused-variable error in release mode.
   ASSERT(status != OptimizingCompiler::FAILED);
-  // Prevent an unused-variable error in release mode.
-  USE(status);
 
-  output_queue_.Enqueue(optimizing_compiler);
-
-  // The execution thread can call InstallOptimizedFunctions() at any time,
-  // including at this point, after queuing for install and before marking
-  // for install.  To avoid race condition, functions that are queued but not
-  // yet marked for install are not processed by InstallOptimizedFunctions().
-
-  ASSERT(optimizing_compiler->info()->closure()->IsInRecompileQueue());
-  // Mark function to generate and install optimized code.  We assume this
-  // write to be atomic.
+  // The function may have already been optimized by OSR.  Simply continue.
+  // Mark it for installing before queuing so that we can be sure of the write
+  // order: marking first and (after being queued) installing code second.
   optimizing_compiler->info()->closure()->MarkForInstallingRecompiledCode();
+  output_queue_.Enqueue(optimizing_compiler);
 }
 
 
@@ -109,10 +100,6 @@
   stop_semaphore_->Wait();
 
   if (FLAG_parallel_recompilation_delay != 0) {
-    // Execution ended before we managed to compile and install the remaining
-    // functions in the queue.  We still want to do that for debugging though.
-    // At this point the optimizing thread already stopped, so we finish
-    // processing the queue in the main thread.
     InstallOptimizedFunctions();
     // Barrier when loading queue length is not necessary since the write
     // happens in CompileNext on the same thread.
@@ -136,23 +123,9 @@
   HandleScope handle_scope(isolate_);
   int functions_installed = 0;
   while (!output_queue_.IsEmpty()) {
-    OptimizingCompiler* compiler = *output_queue_.Peek();
-
-    if (compiler->info()->closure()->IsInRecompileQueue()) {
-      // A function may be queued for install, but not marked as such yet.
-      // We continue with the output queue the next to avoid race condition.
-      break;
-    }
+    OptimizingCompiler* compiler;
     output_queue_.Dequeue(&compiler);
-
-#ifdef DEBUG
-    // Create new closure handle since the deferred handle is about to die.
-    Handle<JSFunction> closure(*compiler->info()->closure());
-#endif  // DEBUG
-
     Compiler::InstallOptimizedCode(compiler);
-    // Assert that the marker builtin has been replaced by actual code.
-    ASSERT(!closure->IsInRecompileQueue());
     functions_installed++;
   }
 }
@@ -163,6 +136,7 @@
   ASSERT(IsQueueAvailable());
   ASSERT(!IsOptimizerThread());
   Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(1));
+  optimizing_compiler->info()->closure()->MarkInRecompileQueue();
   input_queue_.Enqueue(optimizing_compiler);
   input_queue_semaphore_->Signal();
 }
diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compiler-thread.h
index 40599ff..8cb5e2d 100644
--- a/src/optimizing-compiler-thread.h
+++ b/src/optimizing-compiler-thread.h
@@ -93,7 +93,6 @@
   Isolate* isolate_;
   Semaphore* stop_semaphore_;
   Semaphore* input_queue_semaphore_;
-  Semaphore* output_queue_semaphore_;
   UnboundQueue<OptimizingCompiler*> input_queue_;
   UnboundQueue<OptimizingCompiler*> output_queue_;
   volatile AtomicWord stop_thread_;
diff --git a/src/runtime.cc b/src/runtime.cc
index f68672d..12777e7 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -5675,9 +5675,7 @@
 namespace {
 
 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
-#ifdef ENABLE_LATIN_1
 static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
-#endif
 
 // Given a word and two range boundaries returns a word with high bit
 // set in every byte iff the corresponding input byte was strictly in
@@ -5690,11 +5688,6 @@
   // Use strict inequalities since in edge cases the function could be
   // further simplified.
   ASSERT(0 < m && m < n);
-#ifndef ENABLE_LATIN_1
-  // Every byte in an ASCII string is less than or equal to 0x7F.
-  ASSERT((w & (kOneInEveryByte * 0x7F)) == w);
-  ASSERT(n < 0x7F);
-#endif
   // Has high bit set in every w byte less than n.
   uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
   // Has high bit set in every w byte greater than m.
@@ -5711,11 +5704,7 @@
 
 template <AsciiCaseConversion dir>
 struct FastAsciiConverter {
-#ifdef ENABLE_LATIN_1
   static bool Convert(char* dst, char* src, int length, bool* changed_out) {
-#else
-  static bool Convert(char* dst, char* src, int length) {
-#endif
 #ifdef DEBUG
     char* saved_dst = dst;
     char* saved_src = src;
@@ -5727,18 +5716,14 @@
     const char lo = (dir == ASCII_TO_LOWER) ? 'A' - 1 : 'a' - 1;
     const char hi = (dir == ASCII_TO_LOWER) ? 'Z' + 1 : 'z' + 1;
     bool changed = false;
-#ifdef ENABLE_LATIN_1
     uintptr_t or_acc = 0;
-#endif
     char* const limit = src + length;
 #ifdef V8_HOST_CAN_READ_UNALIGNED
     // Process the prefix of the input that requires no conversion one
     // (machine) word at a time.
     while (src <= limit - sizeof(uintptr_t)) {
       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
-#ifdef ENABLE_LATIN_1
       or_acc |= w;
-#endif
       if (AsciiRangeMask(w, lo, hi) != 0) {
         changed = true;
         break;
@@ -5751,9 +5736,7 @@
     // required one word at a time.
     while (src <= limit - sizeof(uintptr_t)) {
       uintptr_t w = *reinterpret_cast<uintptr_t*>(src);
-#ifdef ENABLE_LATIN_1
       or_acc |= w;
-#endif
       uintptr_t m = AsciiRangeMask(w, lo, hi);
       // The mask has high (7th) bit set in every byte that needs
       // conversion and we know that the distance between cases is
@@ -5767,9 +5750,7 @@
     // unaligned access is not supported).
     while (src < limit) {
       char c = *src;
-#ifdef ENABLE_LATIN_1
       or_acc |= c;
-#endif
       if (lo < c && c < hi) {
         c ^= (1 << 5);
         changed = true;
@@ -5778,20 +5759,14 @@
       ++src;
       ++dst;
     }
-#ifdef ENABLE_LATIN_1
     if ((or_acc & kAsciiMask) != 0) {
       return false;
     }
-#endif
 #ifdef DEBUG
     CheckConvert(saved_dst, saved_src, length, changed);
 #endif
-#ifdef ENABLE_LATIN_1
     *changed_out = changed;
     return true;
-#else
-    return changed;
-#endif
   }
 
 #ifdef DEBUG
@@ -5856,13 +5831,6 @@
       if (!maybe_o->ToObject(&o)) return maybe_o;
     }
     SeqOneByteString* result = SeqOneByteString::cast(o);
-#ifndef ENABLE_LATIN_1
-    bool has_changed_character = ConvertTraits::AsciiConverter::Convert(
-        reinterpret_cast<char*>(result->GetChars()),
-        reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
-        length);
-    return has_changed_character ? result : s;
-#else
     bool has_changed_character;
     bool is_ascii = ConvertTraits::AsciiConverter::Convert(
         reinterpret_cast<char*>(result->GetChars()),
@@ -5873,7 +5841,6 @@
     if (is_ascii) {
       return has_changed_character ? result : s;
     }
-#endif
   }
 
   Object* answer;
@@ -7762,7 +7729,7 @@
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
   if (!AllowOptimization(isolate, function)) {
     function->ReplaceCode(function->shared()->code());
-    return function->code();
+    return isolate->heap()->undefined_value();
   }
   function->shared()->code()->set_profiler_ticks(0);
   ASSERT(FLAG_parallel_recompilation);
@@ -7775,10 +7742,13 @@
   HandleScope handle_scope(isolate);
   ASSERT(args.length() == 1);
   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  if (!V8::UseCrankshaft()) return isolate->heap()->undefined_value();
-  ASSERT(FLAG_parallel_recompilation);
+  ASSERT(V8::UseCrankshaft() && FLAG_parallel_recompilation);
   OptimizingCompilerThread* opt_thread = isolate->optimizing_compiler_thread();
-  opt_thread->InstallOptimizedFunctions();
+  do {
+    // The function could have been marked for installing, but not queued just
+    // yet.  In this case, retry until installed.
+    opt_thread->InstallOptimizedFunctions();
+  } while (function->IsMarkedForInstallingRecompiledCode());
   return function->code();
 }
 
@@ -9127,6 +9097,27 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_AllocateInOldPointerSpace) {
+  // Allocate a block of memory in old pointer space (filled with a filler).
+  // Use as fallback for allocation in generated code when old pointer space
+  // is full.
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Smi, size_smi, 0);
+  int size = size_smi->value();
+  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
+  RUNTIME_ASSERT(size > 0);
+  Heap* heap = isolate->heap();
+  Object* allocation;
+  { MaybeObject* maybe_allocation =
+        heap->old_pointer_space()->AllocateRaw(size);
+    if (maybe_allocation->ToObject(&allocation)) {
+      heap->CreateFillerObjectAt(HeapObject::cast(allocation)->address(), size);
+    }
+    return maybe_allocation;
+  }
+}
+
+
 // Push an object unto an array of objects if it is not already in the
 // array.  Returns true if the element was pushed on the stack and
 // false otherwise.
diff --git a/src/runtime.h b/src/runtime.h
index 934de82..2959fed 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -101,6 +101,7 @@
   F(CompileForOnStackReplacement, 1, 1) \
   F(SetNewFunctionAttributes, 1, 1) \
   F(AllocateInNewSpace, 1, 1) \
+  F(AllocateInOldPointerSpace, 1, 1) \
   F(SetNativeFlag, 1, 1) \
   F(StoreArrayLiteralElement, 5, 1) \
   F(DebugCallbackSupportsStepping, 1, 1) \
diff --git a/src/serialize.cc b/src/serialize.cc
index e587dfa..0ba730f 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -544,6 +544,20 @@
       UNCLASSIFIED,
       55,
       "Runtime::AllocateInNewSpace");
+  Add(ExternalReference::old_pointer_space_allocation_top_address(
+      isolate).address(),
+      UNCLASSIFIED,
+      56,
+      "Heap::OldPointerSpaceAllocationTopAddress");
+  Add(ExternalReference::old_pointer_space_allocation_limit_address(
+      isolate).address(),
+      UNCLASSIFIED,
+      57,
+      "Heap::OldPointerSpaceAllocationLimitAddress");
+  Add(ExternalReference(Runtime::kAllocateInOldPointerSpace, isolate).address(),
+      UNCLASSIFIED,
+      58,
+      "Runtime::AllocateInOldPointerSpace");
 
   // Add a small set of deopt entry addresses to encoder without generating the
   // deopt table code, which isn't possible at deserialization time.
@@ -554,7 +568,7 @@
         entry,
         Deoptimizer::LAZY,
         Deoptimizer::CALCULATE_ENTRY_ADDRESS);
-    Add(address, LAZY_DEOPTIMIZATION, 56 + entry, "lazy_deopt");
+    Add(address, LAZY_DEOPTIMIZATION, 59 + entry, "lazy_deopt");
   }
 }
 
diff --git a/src/spaces.cc b/src/spaces.cc
index 701d46f..2952fd5 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -537,6 +537,17 @@
 void MemoryChunk::InsertAfter(MemoryChunk* other) {
   next_chunk_ = other->next_chunk_;
   prev_chunk_ = other;
+
+  // This memory barrier is needed since concurrent sweeper threads may iterate
+  // over the list of pages while a new page is inserted.
+  // TODO(hpayer): find a cleaner way to guarantee that the page list can be
+  // expanded concurrently
+  MemoryBarrier();
+
+  // The following two write operations can take effect in arbitrary order
+  // since pages are always iterated by the sweeper threads in LIFO order, i.e,
+  // the inserted page becomes visible for the sweeper threads after
+  // other->next_chunk_ = this;
   other->next_chunk_->prev_chunk_ = this;
   other->next_chunk_ = this;
 }
diff --git a/src/spaces.h b/src/spaces.h
index 6847b31..39c19a4 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1663,6 +1663,10 @@
   Address top() { return allocation_info_.top; }
   Address limit() { return allocation_info_.limit; }
 
+  // The allocation top and limit addresses.
+  Address* allocation_top_address() { return &allocation_info_.top; }
+  Address* allocation_limit_address() { return &allocation_info_.limit; }
+
   // Allocate the requested number of bytes in the space if possible, return a
   // failure object if not.
   MUST_USE_RESULT inline MaybeObject* AllocateRaw(int size_in_bytes);
diff --git a/src/string-search.h b/src/string-search.h
index 86237f3..bc685ff 100644
--- a/src/string-search.h
+++ b/src/string-search.h
@@ -53,11 +53,7 @@
   // a potentially less efficient searching, but is a safe approximation.
   // For needles using only characters in the same Unicode 256-code point page,
   // there is no search speed degradation.
-#ifndef ENABLE_LATIN_1
-  static const int kAsciiAlphabetSize = 128;
-#else
   static const int kAsciiAlphabetSize = 256;
-#endif
   static const int kUC16AlphabetSize = Isolate::kUC16AlphabetSize;
 
   // Bad-char shift table stored in the state. It's length is the alphabet size.
@@ -155,11 +151,7 @@
   void PopulateBoyerMooreTable();
 
   static inline bool exceedsOneByte(uint8_t c) {
-#ifdef ENABLE_LATIN_1
     return false;
-#else
-    return c > String::kMaxOneByteCharCodeU;
-#endif
   }
 
   static inline bool exceedsOneByte(uint16_t c) {
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index ac94fff..3dba2d6 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -112,9 +112,9 @@
 Handle<Code> StubCache::FindIC(Handle<Name> name,
                                Handle<JSObject> stub_holder,
                                Code::Kind kind,
-                               Code::StubType type) {
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      kind, Code::kNoExtraICState, type);
+                               Code::StubType type,
+                               Code::ExtraICState extra_ic_state) {
+  Code::Flags flags = Code::ComputeMonomorphicFlags(kind, extra_ic_state, type);
   Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
                        isolate_);
   if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -122,18 +122,14 @@
 }
 
 
-Handle<Code> StubCache::FindStub(Handle<Name> name,
-                                 Handle<JSObject> stub_holder,
-                                 Code::Kind kind,
-                                 Code::StubType type) {
+Handle<Code> StubCache::FindHandler(Handle<Name> name,
+                                    Handle<JSObject> stub_holder,
+                                    Code::Kind kind,
+                                    Code::StubType type,
+                                    Code::ExtraICState extra_ic_state) {
   ASSERT(type != Code::NORMAL);
-  int extra_flags = -1;
-  if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC) {
-    extra_flags = kind;
-    kind = Code::STUB;
-  }
   Code::Flags flags = Code::ComputeMonomorphicFlags(
-      kind, Code::kNoExtraICState, type, extra_flags);
+      Code::STUB, extra_ic_state, type, kind);
   Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
                        isolate_);
   if (probe->IsCode()) return Handle<Code>::cast(probe);
@@ -197,7 +193,7 @@
 
   // Compile the stub that is either shared for all names or
   // name specific if there are global objects involved.
-  Handle<Code> handler = FindStub(
+  Handle<Code> handler = FindHandler(
       cache_name, receiver, Code::LOAD_IC, Code::NONEXISTENT);
   if (!handler.is_null()) return handler;
 
@@ -221,7 +217,7 @@
   }
 
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> stub = FindStub(
+  Handle<Code> stub = FindHandler(
       name, stub_holder, Code::LOAD_IC, Code::FIELD);
   if (!stub.is_null()) return stub;
 
@@ -240,7 +236,7 @@
     Handle<ExecutableAccessorInfo> callback) {
   ASSERT(v8::ToCData<Address>(callback->getter()) != 0);
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> stub = FindStub(
+  Handle<Code> stub = FindHandler(
       name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
   if (!stub.is_null()) return stub;
 
@@ -257,7 +253,7 @@
                                              Handle<JSObject> holder,
                                              Handle<JSFunction> getter) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> stub = FindStub(
+  Handle<Code> stub = FindHandler(
       name, stub_holder, Code::LOAD_IC, Code::CALLBACKS);
   if (!stub.is_null()) return stub;
 
@@ -274,7 +270,7 @@
                                             Handle<JSObject> holder,
                                             Handle<JSFunction> value) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> handler = FindStub(
+  Handle<Code> handler = FindHandler(
       name, stub_holder, Code::LOAD_IC, Code::CONSTANT_FUNCTION);
   if (!handler.is_null()) return handler;
 
@@ -290,7 +286,7 @@
                                                Handle<JSObject> receiver,
                                                Handle<JSObject> holder) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> stub = FindStub(
+  Handle<Code> stub = FindHandler(
       name, stub_holder, Code::LOAD_IC, Code::INTERCEPTOR);
   if (!stub.is_null()) return stub;
 
@@ -337,7 +333,7 @@
   }
 
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> stub = FindStub(
+  Handle<Code> stub = FindHandler(
       name, stub_holder, Code::KEYED_LOAD_IC, Code::FIELD);
   if (!stub.is_null()) return stub;
 
@@ -354,7 +350,7 @@
                                                  Handle<JSObject> holder,
                                                  Handle<JSFunction> value) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> handler = FindStub(
+  Handle<Code> handler = FindHandler(
       name, stub_holder, Code::KEYED_LOAD_IC, Code::CONSTANT_FUNCTION);
   if (!handler.is_null()) return handler;
 
@@ -369,7 +365,7 @@
                                                     Handle<JSObject> receiver,
                                                     Handle<JSObject> holder) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> stub = FindStub(
+  Handle<Code> stub = FindHandler(
       name, stub_holder, Code::KEYED_LOAD_IC, Code::INTERCEPTOR);
   if (!stub.is_null()) return stub;
 
@@ -387,7 +383,7 @@
     Handle<JSObject> holder,
     Handle<ExecutableAccessorInfo> callback) {
   Handle<JSObject> stub_holder = StubHolder(receiver, holder);
-  Handle<Code> stub = FindStub(
+  Handle<Code> stub = FindHandler(
       name, stub_holder, Code::KEYED_LOAD_IC, Code::CALLBACKS);
   if (!stub.is_null()) return stub;
 
@@ -405,12 +401,11 @@
                                           Handle<Map> transition,
                                           StrictModeFlag strict_mode) {
   Code::StubType type =
-      (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      Code::STORE_IC, strict_mode, type);
-  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
-                       isolate_);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
+      transition.is_null() ? Code::FIELD : Code::MAP_TRANSITION;
+
+  Handle<Code> stub = FindIC(
+      name, receiver, Code::STORE_IC, type, strict_mode);
+  if (!stub.is_null()) return stub;
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> code =
@@ -473,11 +468,9 @@
                                            Handle<GlobalObject> receiver,
                                            Handle<JSGlobalPropertyCell> cell,
                                            StrictModeFlag strict_mode) {
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      Code::STORE_IC, strict_mode);
-  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
-                       isolate_);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
+  Handle<Code> stub = FindIC(
+      name, receiver, Code::STORE_IC, Code::NORMAL, strict_mode);
+  if (!stub.is_null()) return stub;
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name);
@@ -493,11 +486,9 @@
     Handle<ExecutableAccessorInfo> callback,
     StrictModeFlag strict_mode) {
   ASSERT(v8::ToCData<Address>(callback->setter()) != 0);
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      Code::STORE_IC, strict_mode, Code::CALLBACKS);
-  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
-                       isolate_);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
+  Handle<Code> stub = FindIC(
+      name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode);
+  if (!stub.is_null()) return stub;
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> code =
@@ -512,11 +503,9 @@
                                               Handle<JSObject> holder,
                                               Handle<JSFunction> setter,
                                               StrictModeFlag strict_mode) {
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      Code::STORE_IC, strict_mode, Code::CALLBACKS);
-  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
-                       isolate_);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
+  Handle<Code> stub = FindIC(
+      name, receiver, Code::STORE_IC, Code::CALLBACKS, strict_mode);
+  if (!stub.is_null()) return stub;
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> code =
@@ -529,11 +518,9 @@
 Handle<Code> StubCache::ComputeStoreInterceptor(Handle<Name> name,
                                                 Handle<JSObject> receiver,
                                                 StrictModeFlag strict_mode) {
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      Code::STORE_IC, strict_mode, Code::INTERCEPTOR);
-  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
-                       isolate_);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
+  Handle<Code> stub = FindIC(
+      name, receiver, Code::STORE_IC, Code::INTERCEPTOR, strict_mode);
+  if (!stub.is_null()) return stub;
 
   StoreStubCompiler compiler(isolate_, strict_mode);
   Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name);
@@ -548,11 +535,9 @@
                                                StrictModeFlag strict_mode) {
   Code::StubType type =
       (transition.is_null()) ? Code::FIELD : Code::MAP_TRANSITION;
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      Code::KEYED_STORE_IC, strict_mode, type);
-  Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
-                       isolate_);
-  if (probe->IsCode()) return Handle<Code>::cast(probe);
+  Handle<Code> stub = FindIC(
+      name, receiver, Code::KEYED_STORE_IC, type, strict_mode);
+  if (!stub.is_null()) return stub;
 
   KeyedStoreStubCompiler compiler(isolate(), strict_mode, STANDARD_STORE);
   Handle<Code> code =
@@ -1452,16 +1437,29 @@
   Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss);
 
   LoadFieldStub stub(reg, field.is_inobject(holder), field.translate(holder));
-  GenerateTailCall(stub.GetCode(isolate()));
+  GenerateTailCall(masm(), stub.GetCode(isolate()));
 
   __ bind(&miss);
-  GenerateLoadMiss(masm(), kind());
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
   return GetCode(kind(), Code::FIELD, name);
 }
 
 
+// Load a fast property out of a holder object (src). In-object properties
+// are loaded directly otherwise the property is loaded from the properties
+// fixed array.
+void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
+                                            Register dst,
+                                            Register src,
+                                            Handle<JSObject> holder,
+                                            PropertyIndex index) {
+  DoGenerateFastPropertyLoad(
+      masm, dst, src, index.is_inobject(holder), index.translate(holder));
+}
+
+
 Handle<Code> BaseLoadStubCompiler::CompileLoadConstant(
     Handle<JSObject> object,
     Handle<JSObject> holder,
@@ -1527,7 +1525,7 @@
       LoadFieldStub stub(interceptor_reg,
                          field.is_inobject(holder),
                          field.translate(holder));
-      GenerateTailCall(stub.GetCode(isolate()));
+      GenerateTailCall(masm(), stub.GetCode(isolate()));
     } else {
       // We found FIELD property in prototype chain of interceptor's holder.
       // Retrieve a field from field's holder.
@@ -1581,9 +1579,110 @@
 }
 
 
+Handle<Code> BaseStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
+                                                      int index,
+                                                      Handle<Map> transition,
+                                                      Handle<Name> name) {
+  Label miss, miss_restore_name;
+
+  GenerateNameCheck(name, this->name(), &miss);
+
+  // Generate store field code.
+  GenerateStoreField(masm(),
+                     object,
+                     index,
+                     transition,
+                     name,
+                     receiver(), this->name(), value(), scratch1(), scratch2(),
+                     &miss,
+                     &miss_restore_name);
+
+  // Handle store cache miss.
+  GenerateRestoreName(masm(), &miss_restore_name, name);
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  return GetICCode(kind(),
+                   transition.is_null() ? Code::FIELD : Code::MAP_TRANSITION,
+                   name);
+}
+
+
+Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
+    Handle<Name> name,
+    Handle<JSObject> object,
+    Handle<JSObject> holder,
+    Handle<JSFunction> setter) {
+  Label miss, miss_restore_name;
+
+  // Check that the maps haven't changed, preserving the name register.
+  __ JumpIfSmi(receiver(), &miss);
+  CheckPrototypes(object, receiver(), holder,
+                  this->name(), scratch1(), scratch2(),
+                  name, &miss_restore_name);
+
+  GenerateStoreViaSetter(masm(), setter);
+
+  GenerateRestoreName(masm(), &miss_restore_name, name);
+
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  return GetICCode(kind(), Code::CALLBACKS, name);
+}
+
+
+Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
+    Handle<Map> receiver_map) {
+  ElementsKind elements_kind = receiver_map->elements_kind();
+  if (receiver_map->has_fast_elements() ||
+      receiver_map->has_external_array_elements()) {
+    Handle<Code> stub = KeyedLoadFastElementStub(
+        receiver_map->instance_type() == JS_ARRAY_TYPE,
+        elements_kind).GetCode(isolate());
+    __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
+  } else {
+    Handle<Code> stub =
+        KeyedLoadDictionaryElementStub().GetCode(isolate());
+    __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
+  }
+
+  TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
+
+  // Return the generated code.
+  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
+}
+
+
+Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
+    Handle<Map> receiver_map) {
+  ElementsKind elements_kind = receiver_map->elements_kind();
+  bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
+  Handle<Code> stub =
+      KeyedStoreElementStub(is_jsarray,
+                            elements_kind,
+                            store_mode_).GetCode(isolate());
+
+  __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
+
+  TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
+
+  // Return the generated code.
+  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
+}
+
+
 #undef __
 
 
+void StubCompiler::TailCallBuiltin(MacroAssembler* masm, Builtins::Name name) {
+  Handle<Code> code(masm->isolate()->builtins()->builtin(name));
+  GenerateTailCall(masm, code);
+}
+
+
 void LoadStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
   GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code));
 }
@@ -1594,6 +1693,16 @@
 }
 
 
+void StoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
+  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
+}
+
+
+void KeyedStoreStubCompiler::JitEvent(Handle<Name> name, Handle<Code> code) {
+  GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
+}
+
+
 Handle<Code> BaseLoadStubCompiler::GetICCode(Code::Kind kind,
                                              Code::StubType type,
                                              Handle<Name> name,
@@ -1620,6 +1729,32 @@
 }
 
 
+Handle<Code> BaseStoreStubCompiler::GetICCode(Code::Kind kind,
+                                              Code::StubType type,
+                                              Handle<Name> name,
+                                              InlineCacheState state) {
+  Code::Flags flags = Code::ComputeFlags(
+      kind, state, extra_state(), type);
+  Handle<Code> code = GetCodeWithFlags(flags, name);
+  PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
+  JitEvent(name, code);
+  return code;
+}
+
+
+Handle<Code> BaseStoreStubCompiler::GetCode(Code::Kind kind,
+                                            Code::StubType type,
+                                            Handle<Name> name) {
+  ASSERT(type != Code::NORMAL);
+  Code::Flags flags = Code::ComputeFlags(
+      Code::STUB, MONOMORPHIC, extra_state(), type, kind);
+  Handle<Code> code = GetCodeWithFlags(flags, name);
+  PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
+  JitEvent(name, code);
+  return code;
+}
+
+
 void KeyedLoadStubCompiler::CompileElementHandlers(MapHandleList* receiver_maps,
                                                    CodeHandleList* handlers) {
   for (int i = 0; i < receiver_maps->length(); ++i) {
@@ -1648,31 +1783,6 @@
 }
 
 
-Handle<Code> StoreStubCompiler::GetCode(Code::StubType type,
-                                        Handle<Name> name) {
-  Code::Flags flags = Code::ComputeMonomorphicFlags(
-      Code::STORE_IC, strict_mode_, type);
-  Handle<Code> code = GetCodeWithFlags(flags, name);
-  PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name));
-  GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code));
-  return code;
-}
-
-
-Handle<Code> KeyedStoreStubCompiler::GetCode(Code::StubType type,
-                                             Handle<Name> name,
-                                             InlineCacheState state) {
-  Code::ExtraICState extra_state =
-      Code::ComputeExtraICState(store_mode_, strict_mode_);
-  Code::Flags flags =
-      Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type);
-  Handle<Code> code = GetCodeWithFlags(flags, name);
-  PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name));
-  GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code));
-  return code;
-}
-
-
 Handle<Code> KeyedStoreStubCompiler::CompileStoreElementPolymorphic(
     MapHandleList* receiver_maps) {
   // Collect MONOMORPHIC stubs for all |receiver_maps|.
@@ -1696,7 +1806,7 @@
           elements_kind,
           transitioned_map->elements_kind(),
           is_js_array,
-          strict_mode_,
+          strict_mode(),
           store_mode_).GetCode(isolate());
     } else {
       cached_stub = KeyedStoreElementStub(
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 56e3d4f..7c45566 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -80,12 +80,15 @@
   Handle<Code> FindIC(Handle<Name> name,
                       Handle<JSObject> stub_holder,
                       Code::Kind kind,
-                      Code::StubType type);
+                      Code::StubType type,
+                      Code::ExtraICState extra_state = Code::kNoExtraICState);
 
-  Handle<Code> FindStub(Handle<Name> name,
-                        Handle<JSObject> stub_holder,
-                        Code::Kind kind,
-                        Code::StubType type);
+  Handle<Code> FindHandler(
+      Handle<Name> name,
+      Handle<JSObject> stub_holder,
+      Code::Kind kind,
+      Code::StubType type,
+      Code::ExtraICState extra_state = Code::kNoExtraICState);
 
   Handle<Code> ComputeMonomorphicIC(Handle<JSObject> receiver,
                                     Handle<Code> handler,
@@ -513,14 +516,23 @@
                           Handle<Name> name,
                           Register receiver_reg,
                           Register name_reg,
+                          Register value_reg,
                           Register scratch1,
                           Register scratch2,
-                          Label* miss_label);
+                          Label* miss_label,
+                          Label* miss_restore_name);
 
-  static void GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind);
-  static void GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind);
-
-  static void GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm);
+  static Builtins::Name MissBuiltin(Code::Kind kind) {
+    switch (kind) {
+      case Code::LOAD_IC: return Builtins::kLoadIC_Miss;
+      case Code::STORE_IC: return Builtins::kStoreIC_Miss;
+      case Code::KEYED_LOAD_IC: return Builtins::kKeyedLoadIC_Miss;
+      case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Miss;
+      default: UNREACHABLE();
+    }
+    return Builtins::kLoadIC_Miss;
+  }
+  static void TailCallBuiltin(MacroAssembler* masm, Builtins::Name name);
 
   // Generates code that verifies that the property holder has not changed
   // (checking maps of objects in the prototype chain for fast and global
@@ -577,7 +589,7 @@
   Heap* heap() { return isolate()->heap(); }
   Factory* factory() { return isolate()->factory(); }
 
-  void GenerateTailCall(Handle<Code> code);
+  static void GenerateTailCall(MacroAssembler* masm, Handle<Code> code);
 
  private:
   Isolate* isolate_;
@@ -739,8 +751,6 @@
   void CompileElementHandlers(MapHandleList* receiver_maps,
                               CodeHandleList* handlers);
 
-  Handle<Code> CompileLoadElementPolymorphic(MapHandleList* receiver_maps);
-
   static void GenerateLoadDictionaryElement(MacroAssembler* masm);
 
   static Register receiver() { return registers()[0]; }
@@ -760,17 +770,63 @@
 };
 
 
-class StoreStubCompiler: public StubCompiler {
+class BaseStoreStubCompiler: public StubCompiler {
  public:
-  StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
-    : StubCompiler(isolate), strict_mode_(strict_mode) { }
+  BaseStoreStubCompiler(Isolate* isolate,
+                        StrictModeFlag strict_mode,
+                        Register* registers)
+      : StubCompiler(isolate),
+        strict_mode_(strict_mode),
+        registers_(registers) { }
 
+  virtual ~BaseStoreStubCompiler() { }
 
   Handle<Code> CompileStoreField(Handle<JSObject> object,
                                  int index,
                                  Handle<Map> transition,
                                  Handle<Name> name);
 
+ protected:
+  Handle<Code> GetICCode(Code::Kind kind,
+                         Code::StubType type,
+                         Handle<Name> name,
+                         InlineCacheState state = MONOMORPHIC);
+
+  Handle<Code> GetCode(Code::Kind kind,
+                       Code::StubType type,
+                       Handle<Name> name);
+
+  void GenerateRestoreName(MacroAssembler* masm,
+                           Label* label,
+                           Handle<Name> name);
+
+  Register receiver() { return registers_[0]; }
+  Register name()     { return registers_[1]; }
+  Register value()    { return registers_[2]; }
+  Register scratch1() { return registers_[3]; }
+  Register scratch2() { return registers_[4]; }
+  Register scratch3() { return registers_[5]; }
+  StrictModeFlag strict_mode() { return strict_mode_; }
+  virtual Code::ExtraICState extra_state() { return strict_mode_; }
+
+ private:
+  virtual Code::Kind kind() = 0;
+  virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) = 0;
+  virtual void JitEvent(Handle<Name> name, Handle<Code> code) = 0;
+  virtual void GenerateNameCheck(Handle<Name> name,
+                                 Register name_reg,
+                                 Label* miss) { }
+  StrictModeFlag strict_mode_;
+  Register* registers_;
+};
+
+
+class StoreStubCompiler: public BaseStoreStubCompiler {
+ public:
+  StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
+      : BaseStoreStubCompiler(isolate, strict_mode, registers()) { }
+
+
   Handle<Code> CompileStoreCallback(Handle<Name> name,
                                     Handle<JSObject> object,
                                     Handle<JSObject> holder,
@@ -792,25 +848,24 @@
                                   Handle<Name> name);
 
  private:
-  Handle<Code> GetCode(Code::StubType type, Handle<Name> name);
-
-  StrictModeFlag strict_mode_;
+  static Register* registers();
+  virtual Code::Kind kind() { return Code::STORE_IC; }
+  virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
+    if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
+    return code->ic_state() == MONOMORPHIC
+        ? Logger::STORE_IC_TAG : Logger::STORE_POLYMORPHIC_IC_TAG;
+  }
+  virtual void JitEvent(Handle<Name> name, Handle<Code> code);
 };
 
 
-class KeyedStoreStubCompiler: public StubCompiler {
+class KeyedStoreStubCompiler: public BaseStoreStubCompiler {
  public:
   KeyedStoreStubCompiler(Isolate* isolate,
                          StrictModeFlag strict_mode,
                          KeyedAccessStoreMode store_mode)
-    : StubCompiler(isolate),
-      strict_mode_(strict_mode),
-      store_mode_(store_mode) { }
-
-  Handle<Code> CompileStoreField(Handle<JSObject> object,
-                                 int index,
-                                 Handle<Map> transition,
-                                 Handle<Name> name);
+      : BaseStoreStubCompiler(isolate, strict_mode, registers()),
+        store_mode_(store_mode) { }
 
   Handle<Code> CompileStoreElement(Handle<Map> receiver_map);
 
@@ -834,12 +889,27 @@
 
   static void GenerateStoreDictionaryElement(MacroAssembler* masm);
 
- private:
-  Handle<Code> GetCode(Code::StubType type,
-                       Handle<Name> name,
-                       InlineCacheState state = MONOMORPHIC);
+ protected:
+  virtual Code::ExtraICState extra_state() {
+    return Code::ComputeExtraICState(store_mode_, strict_mode());
+  }
 
-  StrictModeFlag strict_mode_;
+ private:
+  Register transition_map() {
+    return registers()[3];
+  }
+
+  static Register* registers();
+  virtual Code::Kind kind() { return Code::KEYED_STORE_IC; }
+  virtual Logger::LogEventsAndTags log_kind(Handle<Code> code) {
+    if (!code->is_inline_cache_stub()) return Logger::STUB_TAG;
+    return code->ic_state() == MONOMORPHIC
+        ? Logger::KEYED_STORE_IC_TAG : Logger::KEYED_STORE_POLYMORPHIC_IC_TAG;
+  }
+  virtual void JitEvent(Handle<Name> name, Handle<Code> code);
+  virtual void GenerateNameCheck(Handle<Name> name,
+                                 Register name_reg,
+                                 Label* miss);
   KeyedAccessStoreMode store_mode_;
 };
 
diff --git a/src/unicode-inl.h b/src/unicode-inl.h
index c80c67e..02be457 100644
--- a/src/unicode-inl.h
+++ b/src/unicode-inl.h
@@ -95,6 +95,18 @@
 }
 
 
+unsigned Utf8::EncodeOneByte(char* str, uint8_t c) {
+  static const int kMask = ~(1 << 6);
+  if (c <= kMaxOneByteChar) {
+    str[0] = c;
+    return 1;
+  }
+  str[0] = 0xC0 | (c >> 6);
+  str[1] = 0x80 | (c & kMask);
+  return 2;
+}
+
+
 unsigned Utf8::Encode(char* str, uchar c, int previous) {
   static const int kMask = ~(1 << 6);
   if (c <= kMaxOneByteChar) {
diff --git a/src/unicode.h b/src/unicode.h
index f8a1f60..42a8182 100644
--- a/src/unicode.h
+++ b/src/unicode.h
@@ -135,11 +135,7 @@
 
 class Latin1 {
  public:
-#ifndef ENABLE_LATIN_1
-  static const unsigned kMaxChar = 0x7f;
-#else
   static const unsigned kMaxChar = 0xff;
-#endif
   // Returns 0 if character does not convert to single latin-1 character
   // or if the character doesn't not convert back to latin-1 via inverse
   // operation (upper to lower, etc).
@@ -149,6 +145,7 @@
 class Utf8 {
  public:
   static inline uchar Length(uchar chr, int previous);
+  static inline unsigned EncodeOneByte(char* out, uint8_t c);
   static inline unsigned Encode(
       char* out, uchar c, int previous);
   static uchar CalculateValue(const byte* str,
diff --git a/src/v8.cc b/src/v8.cc
index 1753650..2e8cd50 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -268,6 +268,7 @@
     FLAG_gc_global = true;
     FLAG_max_new_space_size = (1 << (kPageSizeBits - 10)) * 2;
   }
+  if (FLAG_trace_hydrogen) FLAG_parallel_recompilation = false;
   OS::SetUp();
   CPU::SetUp();
   use_crankshaft_ = FLAG_crankshaft
diff --git a/src/version.cc b/src/version.cc
index b3e5c45..919c8a3 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     17
-#define BUILD_NUMBER      10
+#define BUILD_NUMBER      11
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 7a1e88f..0b70c1a 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -1118,12 +1118,7 @@
   if (initial_capacity > 0) {
     size += FixedArray::SizeFor(initial_capacity);
   }
-  __ AllocateInNewSpace(size,
-                        result,
-                        scratch2,
-                        scratch3,
-                        gc_required,
-                        TAG_OBJECT);
+  __ Allocate(size, result, scratch2, scratch3, gc_required, TAG_OBJECT);
 
   // Allocated the JSArray. Now initialize the fields except for the elements
   // array.
@@ -1646,12 +1641,12 @@
 
   // Allocate a JSValue and put the tagged pointer into rax.
   Label gc_required;
-  __ AllocateInNewSpace(JSValue::kSize,
-                        rax,  // Result.
-                        rcx,  // New allocation top (we ignore it).
-                        no_reg,
-                        &gc_required,
-                        TAG_OBJECT);
+  __ Allocate(JSValue::kSize,
+              rax,  // Result.
+              rcx,  // New allocation top (we ignore it).
+              no_reg,
+              &gc_required,
+              TAG_OBJECT);
 
   // Set the map.
   __ LoadGlobalFunctionInitialMap(rdi, rcx);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 7ebc103..04c3e68 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -140,7 +140,7 @@
   Counters* counters = masm->isolate()->counters();
 
   Label gc;
-  __ AllocateInNewSpace(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);
+  __ Allocate(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);
 
   __ IncrementCounter(counters->fast_new_closure_total(), 1);
 
@@ -274,8 +274,8 @@
   // Try to allocate the context in new space.
   Label gc;
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
-  __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize,
-                        rax, rbx, rcx, &gc, TAG_OBJECT);
+  __ Allocate((length * kPointerSize) + FixedArray::kHeaderSize,
+              rax, rbx, rcx, &gc, TAG_OBJECT);
 
   // Get the function from the stack.
   __ movq(rcx, Operand(rsp, 1 * kPointerSize));
@@ -320,8 +320,8 @@
   // Try to allocate the context in new space.
   Label gc;
   int length = slots_ + Context::MIN_CONTEXT_SLOTS;
-  __ AllocateInNewSpace(FixedArray::SizeFor(length),
-                        rax, rbx, rcx, &gc, TAG_OBJECT);
+  __ Allocate(FixedArray::SizeFor(length),
+              rax, rbx, rcx, &gc, TAG_OBJECT);
 
   // Get the function from the stack.
   __ movq(rcx, Operand(rsp, 1 * kPointerSize));
@@ -406,7 +406,7 @@
   if (mode == FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS) {
     flags = static_cast<AllocationFlags>(DOUBLE_ALIGNMENT | flags);
   }
-  __ AllocateInNewSpace(size, rax, rbx, rdx, fail, flags);
+  __ Allocate(size, rax, rbx, rdx, fail, flags);
 
   if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
     __ LoadRoot(kScratchRegister, Heap::kAllocationSiteInfoMapRootIndex);
@@ -1316,12 +1316,8 @@
         // Allocate heap number in new space.
         // Not using AllocateHeapNumber macro in order to reuse
         // already loaded heap_number_map.
-        __ AllocateInNewSpace(HeapNumber::kSize,
-                              rax,
-                              rdx,
-                              no_reg,
-                              &allocation_failed,
-                              TAG_OBJECT);
+        __ Allocate(HeapNumber::kSize, rax, rdx, no_reg, &allocation_failed,
+                    TAG_OBJECT);
         // Set the map.
         __ AssertRootValue(heap_number_map,
                            Heap::kHeapNumberMapRootIndex,
@@ -2403,7 +2399,7 @@
 
   StubCompiler::GenerateLoadArrayLength(masm, receiver, r8, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -2431,7 +2427,7 @@
 
   StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, r9, &miss);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -2460,7 +2456,7 @@
   StubCompiler::GenerateLoadStringLength(masm, receiver, r8, r9, &miss,
                                          support_wrapper_);
   __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -2523,7 +2519,7 @@
 
   __ bind(&miss);
 
-  StubCompiler::GenerateStoreMiss(masm, kind());
+  StubCompiler::TailCallBuiltin(masm, StubCompiler::MissBuiltin(kind()));
 }
 
 
@@ -5756,32 +5752,22 @@
   // Compare lengths (precomputed).
   __ bind(&compare_lengths);
   __ SmiTest(length_difference);
-#ifndef ENABLE_LATIN_1
-  __ j(not_zero, &result_not_equal, Label::kNear);
-#else
   Label length_not_equal;
   __ j(not_zero, &length_not_equal, Label::kNear);
-#endif
 
   // Result is EQUAL.
   __ Move(rax, Smi::FromInt(EQUAL));
   __ ret(0);
 
   Label result_greater;
-#ifdef ENABLE_LATIN_1
   Label result_less;
   __ bind(&length_not_equal);
   __ j(greater, &result_greater, Label::kNear);
   __ jmp(&result_less, Label::kNear);
-#endif
   __ bind(&result_not_equal);
   // Unequal comparison of left to right, either character or length.
-#ifndef ENABLE_LATIN_1
-  __ j(greater, &result_greater, Label::kNear);
-#else
   __ j(above, &result_greater, Label::kNear);
   __ bind(&result_less);
-#endif
 
   // Result is LESS.
   __ Move(rax, Smi::FromInt(LESS));
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index ee510eb..8ff12df 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1514,7 +1514,7 @@
   __ bind(&materialized);
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index b185684..0a9ceaa 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -1333,8 +1333,7 @@
   Isolate::Current()->stub_cache()->GenerateProbe(
       masm, flags, rax, rcx, rbx, rdx);
 
-  // Cache miss: Jump to runtime.
-  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
+  GenerateMiss(masm);
 }
 
 
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index cf78698..3d167ef 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3949,6 +3949,13 @@
 }
 
 
+void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
+  Register result = ToRegister(instr->result());
+  Register base = ToRegister(instr->base_object());
+  __ lea(result, Operand(base, instr->offset()));
+}
+
+
 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
   Register object = ToRegister(instr->object());
   Register value = ToRegister(instr->value());
@@ -5025,12 +5032,8 @@
   // the constructor's prototype changes, but instance size and property
   // counts remain unchanged (if slack tracking finished).
   ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress());
-  __ AllocateInNewSpace(instance_size,
-                        result,
-                        no_reg,
-                        scratch,
-                        deferred->entry(),
-                        TAG_OBJECT);
+  __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(),
+              TAG_OBJECT);
 
   __ bind(deferred->exit());
   if (FLAG_debug_code) {
@@ -5119,7 +5122,10 @@
   }
   if (instr->size()->IsConstantOperand()) {
     int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
-    __ AllocateInNewSpace(size, result, temp, no_reg, deferred->entry(), flags);
+    if (instr->hydrogen()->CanAllocateInOldPointerSpace()) {
+      flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
+    }
+    __ Allocate(size, result, temp, no_reg, deferred->entry(), flags);
   } else {
     Register size = ToRegister(instr->size());
     __ AllocateInNewSpace(size, result, temp, no_reg, deferred->entry(), flags);
@@ -5340,7 +5346,7 @@
   // Allocate all objects that are part of the literal in one big
   // allocation. This avoids multiple limit checks.
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
@@ -5427,7 +5433,7 @@
   __ bind(&materialized);
   int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
   Label allocated, runtime_allocate;
-  __ AllocateInNewSpace(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT);
+  __ Allocate(size, rax, rcx, rdx, &runtime_allocate, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&runtime_allocate);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 009df37..d9c2f95 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -292,6 +292,13 @@
 }
 
 
+void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  base_object()->PrintTo(stream);
+  stream->Add(" + %d", offset());
+}
+
+
 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
   stream->Add("#%d / ", arity());
 }
@@ -676,8 +683,12 @@
 LUnallocated* LChunkBuilder::TempRegister() {
   LUnallocated* operand =
       new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
-  operand->set_virtual_register(allocator_->GetVirtualRegister());
-  if (!allocator_->AllocationOk()) Abort("Not enough virtual registers.");
+  int vreg = allocator_->GetVirtualRegister();
+  if (!allocator_->AllocationOk()) {
+    Abort("Out of virtual registers while trying to allocate temp register.");
+    return NULL;
+  }
+  operand->set_virtual_register(vreg);
   return operand;
 }
 
@@ -938,7 +949,7 @@
   if (value->EmitAtUses()) {
     ASSERT(value->IsConstant());
     ASSERT(!value->representation().IsDouble());
-    HBasicBlock* successor = HConstant::cast(value)->ToBoolean()
+    HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
         ? instr->FirstSuccessor()
         : instr->SecondSuccessor();
     return new(zone()) LGoto(successor->block_id());
@@ -1024,6 +1035,15 @@
 }
 
 
+LInstruction* LChunkBuilder::DoInnerAllocatedObject(
+    HInnerAllocatedObject* inner_object) {
+  LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
+  LInnerAllocatedObject* result =
+    new(zone()) LInnerAllocatedObject(base_object);
+  return DefineAsRegister(result);
+}
+
+
 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
   return instr->HasNoUses()
       ? NULL
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 22a1f96..9e3e836 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -188,7 +188,8 @@
   V(LoadFieldByIndex)                           \
   V(DateField)                                  \
   V(WrapReceiver)                               \
-  V(Drop)
+  V(Drop)                                       \
+  V(InnerAllocatedObject)
 
 
 #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)              \
@@ -1594,6 +1595,22 @@
 };
 
 
+class LInnerAllocatedObject: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LInnerAllocatedObject(LOperand* base_object) {
+    inputs_[0] = base_object;
+  }
+
+  LOperand* base_object() { return inputs_[0]; }
+  int offset() { return hydrogen()->offset(); }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "sub-allocated-object")
+  DECLARE_HYDROGEN_ACCESSOR(InnerAllocatedObject)
+};
+
+
 class LThisFunction: public LTemplateInstruction<1, 0, 0> {
  public:
   DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 5a263ab..9ecf66c 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -551,7 +551,8 @@
 
 
 void MacroAssembler::TailCallStub(CodeStub* stub) {
-  ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe());
+  ASSERT(allow_stub_calls_ ||
+         stub->CompilingCallsToThisStubIsGCSafe(isolate()));
   Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET);
 }
 
@@ -564,7 +565,7 @@
 
 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
   if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
-  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe();
+  return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe(isolate());
 }
 
 
@@ -2943,6 +2944,7 @@
 
 
 void MacroAssembler::DispatchMap(Register obj,
+                                 Register unused,
                                  Handle<Map> map,
                                  Handle<Code> success,
                                  SmiCheckType smi_check_type) {
@@ -3714,8 +3716,8 @@
 void MacroAssembler::LoadAllocationTopHelper(Register result,
                                              Register scratch,
                                              AllocationFlags flags) {
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
 
   // Just return if allocation top is already known.
   if ((flags & RESULT_CONTAINS_TOP) != 0) {
@@ -3723,7 +3725,7 @@
     ASSERT(!scratch.is_valid());
 #ifdef DEBUG
     // Assert that result actually contains top on entry.
-    Operand top_operand = ExternalOperand(new_space_allocation_top);
+    Operand top_operand = ExternalOperand(allocation_top);
     cmpq(result, top_operand);
     Check(equal, "Unexpected allocation top");
 #endif
@@ -3733,40 +3735,41 @@
   // Move address of new object to result. Use scratch register if available,
   // and keep address in scratch until call to UpdateAllocationTopHelper.
   if (scratch.is_valid()) {
-    LoadAddress(scratch, new_space_allocation_top);
+    LoadAddress(scratch, allocation_top);
     movq(result, Operand(scratch, 0));
   } else {
-    Load(result, new_space_allocation_top);
+    Load(result, allocation_top);
   }
 }
 
 
 void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
-                                               Register scratch) {
+                                               Register scratch,
+                                               AllocationFlags flags) {
   if (emit_debug_code()) {
     testq(result_end, Immediate(kObjectAlignmentMask));
     Check(zero, "Unaligned allocation in new space");
   }
 
-  ExternalReference new_space_allocation_top =
-      ExternalReference::new_space_allocation_top_address(isolate());
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
 
   // Update new top.
   if (scratch.is_valid()) {
     // Scratch already contains address of allocation top.
     movq(Operand(scratch, 0), result_end);
   } else {
-    Store(new_space_allocation_top, result_end);
+    Store(allocation_top, result_end);
   }
 }
 
 
-void MacroAssembler::AllocateInNewSpace(int object_size,
-                                        Register result,
-                                        Register result_end,
-                                        Register scratch,
-                                        Label* gc_required,
-                                        AllocationFlags flags) {
+void MacroAssembler::Allocate(int object_size,
+                              Register result,
+                              Register result_end,
+                              Register scratch,
+                              Label* gc_required,
+                              AllocationFlags flags) {
   ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
@@ -3795,8 +3798,8 @@
   }
 
   // Calculate new top and bail out if new space is exhausted.
-  ExternalReference new_space_allocation_limit =
-      ExternalReference::new_space_allocation_limit_address(isolate());
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
 
   Register top_reg = result_end.is_valid() ? result_end : result;
 
@@ -3805,12 +3808,12 @@
   }
   addq(top_reg, Immediate(object_size));
   j(carry, gc_required);
-  Operand limit_operand = ExternalOperand(new_space_allocation_limit);
+  Operand limit_operand = ExternalOperand(allocation_limit);
   cmpq(top_reg, limit_operand);
   j(above, gc_required);
 
   // Update allocation top.
-  UpdateAllocationTopHelper(top_reg, scratch);
+  UpdateAllocationTopHelper(top_reg, scratch, flags);
 
   bool tag_result = (flags & TAG_OBJECT) != 0;
   if (top_reg.is(result)) {
@@ -3836,6 +3839,7 @@
                                         Label* gc_required,
                                         AllocationFlags flags) {
   ASSERT((flags & SIZE_IN_WORDS) == 0);
+  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -3875,7 +3879,7 @@
   j(above, gc_required);
 
   // Update allocation top.
-  UpdateAllocationTopHelper(result_end, scratch);
+  UpdateAllocationTopHelper(result_end, scratch, flags);
 
   // Tag the result if requested.
   if ((flags & TAG_OBJECT) != 0) {
@@ -3892,6 +3896,7 @@
                                         Label* gc_required,
                                         AllocationFlags flags) {
   ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
+  ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
   if (!FLAG_inline_new) {
     if (emit_debug_code()) {
       // Trash the registers to simulate an allocation failure.
@@ -3923,7 +3928,7 @@
   j(above, gc_required);
 
   // Update allocation top.
-  UpdateAllocationTopHelper(result_end, scratch);
+  UpdateAllocationTopHelper(result_end, scratch, flags);
 
   // Align the next allocation. Storing the filler map without checking top is
   // always safe because the limit of the heap is always aligned.
@@ -3958,12 +3963,7 @@
                                         Register scratch,
                                         Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(HeapNumber::kSize,
-                     result,
-                     scratch,
-                     no_reg,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT);
 
   // Set the map.
   LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex);
@@ -4053,12 +4053,8 @@
                                         Register scratch2,
                                         Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex);
@@ -4071,12 +4067,8 @@
                                              Register scratch2,
                                              Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(ConsString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex);
@@ -4089,12 +4081,8 @@
                                           Register scratch2,
                                           Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex);
@@ -4107,12 +4095,8 @@
                                                Register scratch2,
                                                Label* gc_required) {
   // Allocate heap number in new space.
-  AllocateInNewSpace(SlicedString::kSize,
-                     result,
-                     scratch1,
-                     scratch2,
-                     gc_required,
-                     TAG_OBJECT);
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
 
   // Set the map. The other fields are left uninitialized.
   LoadRoot(kScratchRegister, Heap::kSlicedAsciiStringMapRootIndex);
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 7827feb..df52159 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -909,6 +909,7 @@
   // specified target if equal. Skip the smi check if not required (object is
   // known to be a heap object)
   void DispatchMap(Register obj,
+                   Register unused,
                    Handle<Map> map,
                    Handle<Code> success,
                    SmiCheckType smi_check_type);
@@ -1024,22 +1025,22 @@
   // ---------------------------------------------------------------------------
   // Allocation support
 
-  // Allocate an object in new space. If the new space is exhausted control
-  // continues at the gc_required label. The allocated object is returned in
-  // result and end of the new object is returned in result_end. The register
-  // scratch can be passed as no_reg in which case an additional object
-  // reference will be added to the reloc info. The returned pointers in result
-  // and result_end have not yet been tagged as heap objects. If
-  // result_contains_top_on_entry is true the content of result is known to be
-  // the allocation top on entry (could be result_end from a previous call to
-  // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
+  // Allocate an object in new space or old pointer space. If the given space
+  // is exhausted control continues at the gc_required label. The allocated
+  // object is returned in result and end of the new object is returned in
+  // result_end. The register scratch can be passed as no_reg in which case
+  // an additional object reference will be added to the reloc info. The
+  // returned pointers in result and result_end have not yet been tagged as
+  // heap objects. If result_contains_top_on_entry is true the content of
+  // result is known to be the allocation top on entry (could be result_end
+  // from a previous call). If result_contains_top_on_entry is true scratch
   // should be no_reg as it is never used.
-  void AllocateInNewSpace(int object_size,
-                          Register result,
-                          Register result_end,
-                          Register scratch,
-                          Label* gc_required,
-                          AllocationFlags flags);
+  void Allocate(int object_size,
+                Register result,
+                Register result_end,
+                Register scratch,
+                Label* gc_required,
+                AllocationFlags flags);
 
   void AllocateInNewSpace(int header_size,
                           ScaleFactor element_size,
@@ -1388,9 +1389,12 @@
   void LoadAllocationTopHelper(Register result,
                                Register scratch,
                                AllocationFlags flags);
+
   // Update allocation top with value in result_end register.
   // If scratch is valid, it contains the address of the allocation top.
-  void UpdateAllocationTopHelper(Register result_end, Register scratch);
+  void UpdateAllocationTopHelper(Register result_end,
+                                 Register scratch,
+                                 AllocationFlags flags);
 
   // Helper for PopHandleScope.  Allowed to perform a GC and returns
   // NULL if gc_allowed.  Does not perform a GC if !gc_allowed, and
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index c9871f0..914241e 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -393,9 +393,6 @@
     __ j(not_equal, on_no_match);  // Definitely not equal.
     __ subb(rax, Immediate('a'));
     __ cmpb(rax, Immediate('z' - 'a'));
-#ifndef ENABLE_LATIN_1
-    __ j(above, on_no_match);  // Weren't letters anyway.
-#else
     __ j(below_equal, &loop_increment);  // In range 'a'-'z'.
     // Latin-1: Check for values in range [224,254] but not 247.
     __ subb(rax, Immediate(224 - 'a'));
@@ -403,7 +400,6 @@
     __ j(above, on_no_match);  // Weren't Latin-1 letters.
     __ cmpb(rax, Immediate(247 - 224));  // Check for 247.
     __ j(equal, on_no_match);
-#endif
     __ bind(&loop_increment);
     // Increment pointers into match and capture strings.
     __ addq(r11, Immediate(1));
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 0e8e74e..69d7a91 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -343,19 +343,6 @@
 }
 
 
-// Load a fast property out of a holder object (src). In-object properties
-// are loaded directly otherwise the property is loaded from the properties
-// fixed array.
-void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
-                                            Register dst,
-                                            Register src,
-                                            Handle<JSObject> holder,
-                                            PropertyIndex index) {
-  DoGenerateFastPropertyLoad(
-      masm, dst, src, index.is_inobject(holder), index.translate(holder));
-}
-
-
 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
                                               Register dst,
                                               Register src,
@@ -715,28 +702,13 @@
 };
 
 
-void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
-  Handle<Code> code = (kind == Code::LOAD_IC)
-      ? masm->isolate()->builtins()->LoadIC_Miss()
-      : masm->isolate()->builtins()->KeyedLoadIC_Miss();
-  __ Jump(code, RelocInfo::CODE_TARGET);
-}
-
-
-void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
-  Handle<Code> code = (kind == Code::STORE_IC)
-      ? masm->isolate()->builtins()->StoreIC_Miss()
-      : masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(code, RelocInfo::CODE_TARGET);
-}
-
-
-void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
-  Handle<Code> code =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ Jump(code, RelocInfo::CODE_TARGET);
+void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
+                                                Label* label,
+                                                Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ bind(label);
+    __ Move(this->name(), name);
+  }
 }
 
 
@@ -749,9 +721,11 @@
                                       Handle<Name> name,
                                       Register receiver_reg,
                                       Register name_reg,
+                                      Register value_reg,
                                       Register scratch1,
                                       Register scratch2,
-                                      Label* miss_label) {
+                                      Label* miss_label,
+                                      Label* miss_restore_name) {
   LookupResult lookup(masm->isolate());
   object->Lookup(*name, &lookup);
   if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
@@ -785,17 +759,8 @@
         holder = JSObject::cast(holder->GetPrototype());
       } while (holder->GetPrototype()->IsJSObject());
     }
-    // We need an extra register, push
-    __ push(name_reg);
-    Label miss_pop, done_check;
     CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
-                    scratch1, scratch2, name, &miss_pop);
-    __ jmp(&done_check);
-    __ bind(&miss_pop);
-    __ pop(name_reg);
-    __ jmp(miss_label);
-    __ bind(&done_check);
-    __ pop(name_reg);
+                    scratch1, scratch2, name, miss_restore_name);
   }
 
   // Stub never generated for non-global objects that require access
@@ -809,7 +774,7 @@
     __ pop(scratch1);  // Return address.
     __ push(receiver_reg);
     __ Push(transition);
-    __ push(rax);
+    __ push(value_reg);
     __ push(scratch1);
     __ TailCallExternalReference(
         ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
@@ -843,11 +808,11 @@
   if (index < 0) {
     // Set the property straight into the object.
     int offset = object->map()->instance_size() + (index * kPointerSize);
-    __ movq(FieldOperand(receiver_reg, offset), rax);
+    __ movq(FieldOperand(receiver_reg, offset), value_reg);
 
     // Update the write barrier for the array address.
     // Pass the value being stored in the now unused name_reg.
-    __ movq(name_reg, rax);
+    __ movq(name_reg, value_reg);
     __ RecordWriteField(
         receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs);
   } else {
@@ -855,16 +820,17 @@
     int offset = index * kPointerSize + FixedArray::kHeaderSize;
     // Get the properties array (optimistically).
     __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
-    __ movq(FieldOperand(scratch1, offset), rax);
+    __ movq(FieldOperand(scratch1, offset), value_reg);
 
     // Update the write barrier for the array address.
     // Pass the value being stored in the now unused name_reg.
-    __ movq(name_reg, rax);
+    __ movq(name_reg, value_reg);
     __ RecordWriteField(
         scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs);
   }
 
   // Return the value (register rax).
+  ASSERT(value_reg.is(rax));
   __ ret(0);
 }
 
@@ -908,15 +874,16 @@
   }
 }
 
-#undef __
-#define __ ACCESS_MASM((masm()))
 
-
-void StubCompiler::GenerateTailCall(Handle<Code> code) {
+void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
   __ jmp(code, RelocInfo::CODE_TARGET);
 }
 
 
+#undef __
+#define __ ACCESS_MASM((masm()))
+
+
 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
                                        Register object_reg,
                                        Handle<JSObject> holder,
@@ -1039,7 +1006,7 @@
   if (!miss->is_unused()) {
     __ jmp(success);
     __ bind(miss);
-    GenerateLoadMiss(masm(), kind());
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
   }
 }
 
@@ -2408,64 +2375,26 @@
 }
 
 
-Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                  int index,
-                                                  Handle<Map> transition,
-                                                  Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : name
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  // Generate store field code.  Preserves receiver and name on jump to miss.
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     rdx, rcx, rbx, rdi,
-                     &miss);
-
-  // Handle store cache miss.
-  __ bind(&miss);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreCallback(
     Handle<Name> name,
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<JSObject> holder,
     Handle<ExecutableAccessorInfo> callback) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : name
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
   Label miss;
   // Check that the maps haven't changed.
-  __ JumpIfSmi(rdx, &miss);
-  CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss);
+  __ JumpIfSmi(receiver(), &miss);
+  CheckPrototypes(object, receiver(), holder,
+                  scratch1(), scratch2(), scratch3(), name, &miss);
 
   // Stub never generated for non-global objects that require access checks.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
 
-  __ pop(rbx);  // remove the return address
-  __ push(rdx);  // receiver
+  __ pop(scratch1());  // remove the return address
+  __ push(receiver());
   __ Push(callback);  // callback info
-  __ push(rcx);  // name
-  __ push(rax);  // value
-  __ push(rbx);  // restore return address
+  __ push(this->name());
+  __ push(value());
+  __ push(scratch1());  // restore return address
 
   // Do tail-call to the runtime system.
   ExternalReference store_callback_property =
@@ -2474,11 +2403,10 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
+  return GetICCode(kind(), Code::CALLBACKS, name);
 }
 
 
@@ -2528,64 +2456,30 @@
 #define __ ACCESS_MASM(masm())
 
 
-Handle<Code> StoreStubCompiler::CompileStoreViaSetter(
-    Handle<Name> name,
-    Handle<JSObject> receiver,
-    Handle<JSObject> holder,
-    Handle<JSFunction> setter) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : name
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  // Check that the maps haven't changed.
-  __ JumpIfSmi(rdx, &miss);
-  CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss);
-
-  GenerateStoreViaSetter(masm(), setter);
-
-  __ bind(&miss);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(Code::CALLBACKS, name);
-}
-
-
 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
-    Handle<JSObject> receiver,
+    Handle<JSObject> object,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : name
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the object hasn't changed.
-  __ CheckMap(rdx, Handle<Map>(receiver->map()), &miss,
+  __ CheckMap(receiver(), Handle<Map>(object->map()), &miss,
               DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform global security token check if needed.
-  if (receiver->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(rdx, rbx, &miss);
+  if (object->IsJSGlobalProxy()) {
+    __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
   }
 
   // Stub never generated for non-global objects that require access
   // checks.
-  ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
+  ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
 
-  __ pop(rbx);  // remove the return address
-  __ push(rdx);  // receiver
-  __ push(rcx);  // name
-  __ push(rax);  // value
-  __ Push(Smi::FromInt(strict_mode_));
-  __ push(rbx);  // restore return address
+  __ pop(scratch1());  // remove the return address
+  __ push(receiver());
+  __ push(this->name());
+  __ push(value());
+  __ Push(Smi::FromInt(strict_mode()));
+  __ push(scratch1());  // restore return address
 
   // Do tail-call to the runtime system.
   ExternalReference store_ic_property =
@@ -2594,11 +2488,10 @@
 
   // Handle store cache miss.
   __ bind(&miss);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::INTERCEPTOR, name);
+  return GetICCode(kind(), Code::INTERCEPTOR, name);
 }
 
 
@@ -2606,22 +2499,17 @@
     Handle<GlobalObject> object,
     Handle<JSGlobalPropertyCell> cell,
     Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : name
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
   Label miss;
 
   // Check that the map of the global has not changed.
-  __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
+  __ Cmp(FieldOperand(receiver(), HeapObject::kMapOffset),
          Handle<Map>(object->map()));
   __ j(not_equal, &miss);
 
   // Compute the cell operand to use.
-  __ Move(rbx, cell);
-  Operand cell_operand = FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset);
+  __ Move(scratch1(), cell);
+  Operand cell_operand =
+      FieldOperand(scratch1(), JSGlobalPropertyCell::kValueOffset);
 
   // Check that the value in the cell is not the hole. If it is, this
   // cell could have been deleted and reintroducing the global needs
@@ -2631,7 +2519,7 @@
   __ j(equal, &miss);
 
   // Store the value in the cell.
-  __ movq(cell_operand, rax);
+  __ movq(cell_operand, value());
   // Cells are always rescanned, so no write barrier here.
 
   // Return the value (register rax).
@@ -2642,78 +2530,10 @@
   // Handle store cache miss.
   __ bind(&miss);
   __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
-  Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, name);
-}
-
-
-Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
-                                                       int index,
-                                                       Handle<Map> transition,
-                                                       Handle<Name> name) {
-  // ----------- S t a t e -------------
-  //  -- rax     : value
-  //  -- rcx     : key
-  //  -- rdx     : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  Counters* counters = isolate()->counters();
-  __ IncrementCounter(counters->keyed_store_field(), 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rcx, name);
-  __ j(not_equal, &miss);
-
-  // Generate store field code.  Preserves receiver and name on jump to miss.
-  GenerateStoreField(masm(),
-                     object,
-                     index,
-                     transition,
-                     name,
-                     rdx, rcx, rbx, rdi,
-                     &miss);
-
-  // Handle store cache miss.
-  __ bind(&miss);
-  __ DecrementCounter(counters->keyed_store_field(), 1);
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition.is_null()
-                 ? Code::FIELD
-                 : Code::MAP_TRANSITION, name);
-}
-
-
-Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
-  Handle<Code> stub =
-      KeyedStoreElementStub(is_js_array,
-                            elements_kind,
-                            store_mode_).GetCode(isolate());
-
-  __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
-
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string());
+  return GetICCode(kind(), Code::NORMAL, name);
 }
 
 
@@ -2721,37 +2541,34 @@
     MapHandleList* receiver_maps,
     CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
   Label miss;
-  __ JumpIfSmi(rdx, &miss, Label::kNear);
+  __ JumpIfSmi(receiver(), &miss, Label::kNear);
 
-  __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset));
+  __ movq(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
   int receiver_count = receiver_maps->length();
   for (int i = 0; i < receiver_count; ++i) {
     // Check map and tail call if there's a match
-    __ Cmp(rdi, receiver_maps->at(i));
+    __ Cmp(scratch1(), receiver_maps->at(i));
     if (transitioned_maps->at(i).is_null()) {
       __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET);
     } else {
       Label next_map;
       __ j(not_equal, &next_map, Label::kNear);
-      __ movq(rbx, transitioned_maps->at(i), RelocInfo::EMBEDDED_OBJECT);
+      __ movq(transition_map(),
+              transitioned_maps->at(i),
+              RelocInfo::EMBEDDED_OBJECT);
       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
   }
 
   __ bind(&miss);
-  Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
-  return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
+  return GetICCode(
+      kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
 }
 
 
@@ -2789,6 +2606,20 @@
 }
 
 
+Register* StoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
+  return registers;
+}
+
+
+Register* KeyedStoreStubCompiler::registers() {
+  // receiver, name, value, scratch1, scratch2, scratch3.
+  static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
+  return registers;
+}
+
+
 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
                                               Register name_reg,
                                               Label* miss) {
@@ -2797,6 +2628,14 @@
 }
 
 
+void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
+                                               Register name_reg,
+                                               Label* miss) {
+  __ Cmp(name_reg, name);
+  __ j(not_equal, miss);
+}
+
+
 #undef __
 #define __ ACCESS_MASM(masm)
 
@@ -2875,33 +2714,6 @@
 }
 
 
-Handle<Code> KeyedLoadStubCompiler::CompileLoadElement(
-    Handle<Map> receiver_map) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  ElementsKind elements_kind = receiver_map->elements_kind();
-  if (receiver_map->has_fast_elements() ||
-      receiver_map->has_external_array_elements()) {
-    Handle<Code> stub = KeyedLoadFastElementStub(
-        receiver_map->instance_type() == JS_ARRAY_TYPE,
-        elements_kind).GetCode(isolate());
-    __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
-  } else {
-    Handle<Code> stub =
-        KeyedLoadDictionaryElementStub().GetCode(isolate());
-    __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
-  }
-
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
-}
-
-
 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
     MapHandleList* receiver_maps,
     CodeHandleList* handlers,
@@ -2925,7 +2737,7 @@
   }
 
   __  bind(&miss);
-  GenerateLoadMiss(masm(), kind());
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
 
   // Return the generated code.
   InlineCacheState state =
@@ -2985,8 +2797,8 @@
   __ cmpq(rcx, Immediate(instance_size));
   __ Check(equal, "Instance size of initial map changed.");
 #endif
-  __ AllocateInNewSpace(instance_size, rdx, rcx, no_reg,
-                        &generic_stub_call, NO_ALLOCATION_FLAGS);
+  __ Allocate(instance_size, rdx, rcx, no_reg, &generic_stub_call,
+              NO_ALLOCATION_FLAGS);
 
   // Allocated the JSObject, now initialize the fields and add the heap tag.
   // rbx: initial map
@@ -3101,9 +2913,7 @@
   //  -- rdx    : receiver
   //  -- rsp[0]  : return address
   // -----------------------------------
-  Handle<Code> slow_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_Slow();
-  __ jmp(slow_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
 
   __ bind(&miss_force_generic);
   // ----------- S t a t e -------------
@@ -3111,9 +2921,7 @@
   //  -- rdx    : receiver
   //  -- rsp[0]  : return address
   // -----------------------------------
-  Handle<Code> miss_ic =
-      masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
-  __ jmp(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
 }
 
 
@@ -3311,9 +3119,7 @@
   //  -- rdx     : receiver
   //  -- rsp[0]  : return address
   // -----------------------------------
-
-  Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-  __ jmp(ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
 
   // Miss case: call runtime.
   __ bind(&miss_force_generic);
@@ -3324,10 +3130,7 @@
   //  -- rdx    : receiver
   //  -- rsp[0] : return address
   // -----------------------------------
-
-  Handle<Code> miss_ic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ jmp(miss_ic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 }
 
 
@@ -3396,13 +3199,10 @@
 
   // Handle store cache miss.
   __ bind(&miss_force_generic);
-  Handle<Code> ic_force_generic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Grow the array by a single element if possible.
@@ -3420,7 +3220,7 @@
     __ j(not_equal, &check_capacity);
 
     int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, rdi, rbx, r8, &slow, TAG_OBJECT);
+    __ Allocate(size, rdi, rbx, r8, &slow, TAG_OBJECT);
 
     // rax: value
     // rcx: key
@@ -3468,8 +3268,7 @@
     __ jmp(&finish_store);
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ jmp(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }
 
@@ -3519,16 +3318,13 @@
 
   // Handle store cache miss, replacing the ic with the generic stub.
   __ bind(&miss_force_generic);
-  Handle<Code> ic_force_generic =
-      masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
-  __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
 
   __ bind(&restore_key_transition_elements_kind);
   // Restore smi-tagging of rcx.
   __ Integer32ToSmi(rcx, rcx);
   __ bind(&transition_elements_kind);
-  Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
-  __ jmp(ic_miss, RelocInfo::CODE_TARGET);
+  TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
 
   if (is_js_array && IsGrowStoreMode(store_mode)) {
     // Grow the array by a single element if possible.
@@ -3554,7 +3350,7 @@
     __ j(not_equal, &check_capacity);
 
     int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements);
-    __ AllocateInNewSpace(size, rdi, rbx, r8, &slow, TAG_OBJECT);
+    __ Allocate(size, rdi, rbx, r8, &slow, TAG_OBJECT);
 
     // rax: value
     // rcx: key
@@ -3602,8 +3398,7 @@
     __ jmp(&finish_store);
 
     __ bind(&slow);
-    Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow();
-    __ jmp(ic_slow, RelocInfo::CODE_TARGET);
+    TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
   }
 }