Version 3.0.6

Allowed getters and setters on JSArray elements (Issue 900).

Stopped JSON objects from hitting inherited setters (part of
Issue 1015).

Allowed numbers and strings as names of getters/setters in object
initializer (Issue 820).

Added use_system_v8 option to gyp (off by default), to make it easier
for Linux distributions to ship with system-provided V8 library.

Exported external array data accessors (Issue 1016).

Added labelled thread names to help with debugging (on Linux).

git-svn-id: http://v8.googlecode.com/svn/trunk@6169 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 36f7507f..cd7f07f 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -66,13 +66,14 @@
 // such that we use an enum in optimized mode, and the struct in debug
 // mode. This way we get the compile-time error checking in debug mode
 // and best performance in optimized code.
-//
+
 // Core register
 struct Register {
   static const int kNumRegisters = 16;
   static const int kNumAllocatableRegisters = 8;
 
   static int ToAllocationIndex(Register reg) {
+    ASSERT(reg.code() < kNumAllocatableRegisters);
     return reg.code();
   }
 
@@ -132,7 +133,7 @@
 const Register r6  = {  6 };
 const Register r7  = {  7 };
 const Register r8  = {  8 };  // Used as context register.
-const Register r9  = {  9 };
+const Register r9  = {  9 };  // Used as lithium codegen scratch register.
 const Register r10 = { 10 };  // Used as roots register.
 const Register fp  = { 11 };
 const Register ip  = { 12 };
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 7c3ea89..577ac63 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -917,13 +917,6 @@
 }
 
 
-void RecordWriteStub::Generate(MacroAssembler* masm) {
-  __ add(offset_, object_, Operand(offset_));
-  __ RecordWriteHelper(object_, offset_, scratch_);
-  __ Ret();
-}
-
-
 // On entry lhs_ and rhs_ are the values to be compared.
 // On exit r0 is 0, positive or negative to indicate the result of
 // the comparison.
@@ -1229,16 +1222,22 @@
   bool generate_code_to_calculate_answer = true;
 
   if (ShouldGenerateFPCode()) {
+    // DIV has neither SmiSmi fast code nor specialized slow code.
+    // So don't try to patch a DIV Stub.
     if (runtime_operands_type_ == BinaryOpIC::DEFAULT) {
       switch (op_) {
         case Token::ADD:
         case Token::SUB:
         case Token::MUL:
-        case Token::DIV:
           GenerateTypeTransition(masm);  // Tail call.
           generate_code_to_calculate_answer = false;
           break;
 
+        case Token::DIV:
+          // DIV has neither SmiSmi fast code nor specialized slow code.
+          // So don't try to patch a DIV Stub.
+          break;
+
         default:
           break;
       }
@@ -1299,7 +1298,8 @@
       // HEAP_NUMBERS stub is slower than GENERIC on a pair of smis.
       // r0 is known to be a smi. If r1 is also a smi then switch to GENERIC.
       Label r1_is_not_smi;
-      if (runtime_operands_type_ == BinaryOpIC::HEAP_NUMBERS) {
+      if ((runtime_operands_type_ == BinaryOpIC::HEAP_NUMBERS) &&
+          HasSmiSmiFastPath()) {
         __ tst(r1, Operand(kSmiTagMask));
         __ b(ne, &r1_is_not_smi);
         GenerateTypeTransition(masm);  // Tail call.
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index 8ffca77..9fa8687 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -77,7 +77,7 @@
         rhs_(rhs),
         constant_rhs_(constant_rhs),
         specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)),
-        runtime_operands_type_(BinaryOpIC::DEFAULT),
+        runtime_operands_type_(BinaryOpIC::UNINIT_OR_SMI),
         name_(NULL) { }
 
   GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info)
@@ -178,6 +178,10 @@
     return lhs_is_r0 ? r1 : r0;
   }
 
+  bool HasSmiSmiFastPath() {
+    return op_ != Token::DIV;
+  }
+
   bool ShouldGenerateSmiCode() {
     return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) &&
         runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS &&
@@ -437,43 +441,6 @@
 };
 
 
-class RecordWriteStub : public CodeStub {
- public:
-  RecordWriteStub(Register object, Register offset, Register scratch)
-      : object_(object), offset_(offset), scratch_(scratch) { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  Register object_;
-  Register offset_;
-  Register scratch_;
-
-  // Minor key encoding in 12 bits. 4 bits for each of the three
-  // registers (object, offset and scratch) OOOOAAAASSSS.
-  class ScratchBits: public BitField<uint32_t, 0, 4> {};
-  class OffsetBits: public BitField<uint32_t, 4, 4> {};
-  class ObjectBits: public BitField<uint32_t, 8, 4> {};
-
-  Major MajorKey() { return RecordWrite; }
-
-  int MinorKey() {
-    // Encode the registers.
-    return ObjectBits::encode(object_.code()) |
-           OffsetBits::encode(offset_.code()) |
-           ScratchBits::encode(scratch_.code());
-  }
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("RecordWriteStub (object reg %d), (offset reg %d),"
-           " (scratch reg %d)\n",
-           object_.code(), offset_.code(), scratch_.code());
-  }
-#endif
-};
-
-
 // Enter C code from generated RegExp code in a way that allows
 // the C code to fix the return address in case of a GC.
 // Currently only needed on ARM.
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 59bc14e..4d061d2 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -5618,12 +5618,10 @@
   // (or them and test against Smi mask.)
 
   __ mov(tmp2, tmp1);
-  RecordWriteStub recordWrite1(tmp1, index1, tmp3);
-  __ CallStub(&recordWrite1);
-
-  RecordWriteStub recordWrite2(tmp2, index2, tmp3);
-  __ CallStub(&recordWrite2);
-
+  __ add(index1, index1, tmp1);
+  __ add(index2, index2, tmp1);
+  __ RecordWriteHelper(tmp1, index1, tmp3);
+  __ RecordWriteHelper(tmp2, index2, tmp3);
   __ bind(&done);
 
   deferred->BindExit();
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index d254918..0275730 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -38,6 +38,8 @@
 #include "scopes.h"
 #include "stub-cache.h"
 
+#include "arm/code-stubs-arm.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 9c8e834..87efc92 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -767,11 +767,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DefineSameAsAny(LInstruction* instr) {
-  return Define(instr, new LUnallocated(LUnallocated::SAME_AS_ANY_INPUT));
-}
-
-
 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) {
   return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
 }
@@ -1016,9 +1011,6 @@
   HInstruction* current = block->first();
   int start = chunk_->instructions()->length();
   while (current != NULL && !is_aborted()) {
-    if (FLAG_trace_environment) {
-      PrintF("Process instruction %d\n", current->id());
-    }
     // Code for constants in registers is generated lazily.
     if (!current->EmitAtUses()) {
       VisitInstruction(current);
@@ -1125,7 +1117,7 @@
   LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
   int ast_id = hydrogen_env->ast_id();
   ASSERT(ast_id != AstNode::kNoNumber);
-  int value_count = hydrogen_env->values()->length();
+  int value_count = hydrogen_env->length();
   LEnvironment* result = new LEnvironment(hydrogen_env->closure(),
                                           ast_id,
                                           hydrogen_env->parameter_count(),
@@ -1225,7 +1217,6 @@
       ASSERT(compare->value()->representation().IsTagged());
 
       return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()),
-                                           TempRegister(),
                                            first_id,
                                            second_id);
     } else if (v->IsHasCachedArrayIndex()) {
@@ -1238,11 +1229,8 @@
       HIsNull* compare = HIsNull::cast(v);
       ASSERT(compare->value()->representation().IsTagged());
 
-      // We only need a temp register for non-strict compare.
-      LOperand* temp = compare->is_strict() ? NULL : TempRegister();
       return new LIsNullAndBranch(UseRegisterAtStart(compare->value()),
                                   compare->is_strict(),
-                                  temp,
                                   first_id,
                                   second_id);
     } else if (v->IsIsObject()) {
@@ -1295,12 +1283,8 @@
     HCompareMapAndBranch* instr) {
   ASSERT(instr->value()->representation().IsTagged());
   LOperand* value = UseRegisterAtStart(instr->value());
-  HBasicBlock* first = instr->FirstSuccessor();
-  HBasicBlock* second = instr->SecondSuccessor();
-  return new LCmpMapAndBranch(value,
-                              instr->map(),
-                              first->block_id(),
-                              second->block_id());
+  LOperand* temp = TempRegister();
+  return new LCmpMapAndBranch(value, temp);
 }
 
 
@@ -1370,6 +1354,9 @@
       return AssignEnvironment(DefineAsRegister(result));
     case kMathSqrt:
       return DefineSameAsFirst(result);
+    case kMathRound:
+      Abort("MathRound LUnaryMathOperation not implemented");
+      return NULL;
     case kMathPowHalf:
       Abort("MathPowHalf LUnaryMathOperation not implemented");
       return NULL;
@@ -1774,9 +1761,11 @@
 
 
 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
-  LOperand* temp = TempRegister();
+  LOperand* temp1 = TempRegister();
+  LOperand* temp2 = TempRegister();
   LInstruction* result =
-      new LCheckPrototypeMaps(temp,
+      new LCheckPrototypeMaps(temp1,
+                              temp2,
                               instr->holder(),
                               instr->receiver_map());
   return AssignEnvironment(result);
@@ -1853,8 +1842,7 @@
 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
     HLoadFunctionPrototype* instr) {
   return AssignEnvironment(DefineAsRegister(
-      new LLoadFunctionPrototype(UseRegister(instr->function()),
-                                 TempRegister())));
+      new LLoadFunctionPrototype(UseRegister(instr->function()))));
 }
 
 
@@ -2058,13 +2046,7 @@
     }
   }
 
-  if (FLAG_trace_environment) {
-    PrintF("Reconstructed environment ast_id=%d, instr_id=%d\n",
-           instr->ast_id(),
-           instr->id());
-    env->PrintToStd();
-  }
-  ASSERT(env->values()->length() == instr->environment_height());
+  ASSERT(env->length() == instr->environment_length());
 
   // If there is an instruction pending deoptimization environment create a
   // lazy bailout instruction to capture the environment.
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 5b152ef..2f8cc1c 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -726,11 +726,9 @@
  public:
   LIsNullAndBranch(LOperand* value,
                    bool is_strict,
-                   LOperand* temp,
                    int true_block_id,
                    int false_block_id)
       : LIsNull(value, is_strict),
-        temp_(temp),
         true_block_id_(true_block_id),
         false_block_id_(false_block_id) { }
 
@@ -741,10 +739,7 @@
   int true_block_id() const { return true_block_id_; }
   int false_block_id() const { return false_block_id_; }
 
-  LOperand* temp() const { return temp_; }
-
  private:
-  LOperand* temp_;
   int true_block_id_;
   int false_block_id_;
 };
@@ -839,11 +834,9 @@
 class LHasInstanceTypeAndBranch: public LHasInstanceType {
  public:
   LHasInstanceTypeAndBranch(LOperand* value,
-                            LOperand* temporary,
                             int true_block_id,
                             int false_block_id)
       : LHasInstanceType(value),
-        temp_(temporary),
         true_block_id_(true_block_id),
         false_block_id_(false_block_id) { }
 
@@ -855,10 +848,7 @@
   int true_block_id() const { return true_block_id_; }
   int false_block_id() const { return false_block_id_; }
 
-  LOperand* temp() { return temp_; }
-
  private:
-  LOperand* temp_;
   int true_block_id_;
   int false_block_id_;
 };
@@ -1121,27 +1111,25 @@
 
 class LCmpMapAndBranch: public LUnaryOperation {
  public:
-  LCmpMapAndBranch(LOperand* value,
-                   Handle<Map> map,
-                   int true_block_id,
-                   int false_block_id)
-      : LUnaryOperation(value),
-        map_(map),
-        true_block_id_(true_block_id),
-        false_block_id_(false_block_id) { }
+  LCmpMapAndBranch(LOperand* value, LOperand* temp)
+      : LUnaryOperation(value), temp_(temp) { }
 
   DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareMapAndBranch)
 
   virtual bool IsControl() const { return true; }
 
-  Handle<Map> map() const { return map_; }
-  int true_block_id() const { return true_block_id_; }
-  int false_block_id() const { return false_block_id_; }
+  LOperand* temp() const { return temp_; }
+  Handle<Map> map() const { return hydrogen()->map(); }
+  int true_block_id() const {
+    return hydrogen()->true_destination()->block_id();
+  }
+  int false_block_id() const {
+    return hydrogen()->false_destination()->block_id();
+  }
 
  private:
-  Handle<Map> map_;
-  int true_block_id_;
-  int false_block_id_;
+  LOperand* temp_;
 };
 
 
@@ -1265,17 +1253,13 @@
 
 class LLoadFunctionPrototype: public LUnaryOperation {
  public:
-  LLoadFunctionPrototype(LOperand* function, LOperand* temporary)
-      : LUnaryOperation(function), temporary_(temporary) { }
+  explicit LLoadFunctionPrototype(LOperand* function)
+      : LUnaryOperation(function) { }
 
   DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
   DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
 
   LOperand* function() const { return input(); }
-  LOperand* temporary() const { return temporary_; }
-
- private:
-  LOperand* temporary_;
 };
 
 
@@ -1678,21 +1662,25 @@
 
 class LCheckPrototypeMaps: public LInstruction {
  public:
-  LCheckPrototypeMaps(LOperand* temp,
+  LCheckPrototypeMaps(LOperand* temp1,
+                      LOperand* temp2,
                       Handle<JSObject> holder,
                       Handle<Map> receiver_map)
-      : temp_(temp),
+      : temp1_(temp1),
+        temp2_(temp2),
         holder_(holder),
         receiver_map_(receiver_map) { }
 
   DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps")
 
-  LOperand* temp() const { return temp_; }
+  LOperand* temp1() const { return temp1_; }
+  LOperand* temp2() const { return temp2_; }
   Handle<JSObject> holder() const { return holder_; }
   Handle<Map> receiver_map() const { return receiver_map_; }
 
  private:
-  LOperand* temp_;
+  LOperand* temp1_;
+  LOperand* temp2_;
   Handle<JSObject> holder_;
   Handle<Map> receiver_map_;
 };
@@ -2074,7 +2062,6 @@
   LInstruction* Define(LInstruction* instr);
   LInstruction* DefineAsRegister(LInstruction* instr);
   LInstruction* DefineAsSpilled(LInstruction* instr, int index);
-  LInstruction* DefineSameAsAny(LInstruction* instr);
   LInstruction* DefineSameAsFirst(LInstruction* instr);
   LInstruction* DefineFixed(LInstruction* instr, Register reg);
   LInstruction* DefineFixedDouble(LInstruction* instr, DoubleRegister reg);
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 53a4325..bb2461c 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -598,7 +598,7 @@
   DoubleRegister dbl_scratch = d0;
   LUnallocated marker_operand(LUnallocated::NONE);
 
-  Register core_scratch = r9;
+  Register core_scratch = scratch0();
   bool destroys_core_scratch = false;
 
   LGapResolver resolver(move->move_operands(), &marker_operand);
@@ -730,7 +730,53 @@
 
 
 void LCodeGen::DoCallStub(LCallStub* instr) {
-  Abort("DoCallStub unimplemented.");
+  ASSERT(ToRegister(instr->result()).is(r0));
+  switch (instr->hydrogen()->major_key()) {
+    case CodeStub::RegExpConstructResult: {
+      RegExpConstructResultStub stub;
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::RegExpExec: {
+      RegExpExecStub stub;
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::SubString: {
+      SubStringStub stub;
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::StringCharAt: {
+      Abort("StringCharAtStub unimplemented.");
+      break;
+    }
+    case CodeStub::MathPow: {
+      Abort("MathPowStub unimplemented.");
+      break;
+    }
+    case CodeStub::NumberToString: {
+      NumberToStringStub stub;
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::StringAdd: {
+      StringAddStub stub(NO_STRING_ADD_FLAGS);
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::StringCompare: {
+      StringCompareStub stub;
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::TranscendentalCache: {
+      Abort("TranscendentalCache unimplemented.");
+      break;
+    }
+    default:
+      UNREACHABLE();
+  }
 }
 
 
@@ -750,8 +796,8 @@
 
 
 void LCodeGen::DoMulI(LMulI* instr) {
+  Register scratch = scratch0();
   Register left = ToRegister(instr->left());
-  Register scratch = r9;
   Register right = EmitLoadRegister(instr->right(), scratch);
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) &&
@@ -813,6 +859,7 @@
 
 
 void LCodeGen::DoShiftI(LShiftI* instr) {
+  Register scratch = scratch0();
   LOperand* left = instr->left();
   LOperand* right = instr->right();
   ASSERT(left->Equals(instr->result()));
@@ -820,21 +867,21 @@
   Register result = ToRegister(left);
   if (right->IsRegister()) {
     // Mask the right operand.
-    __ and_(r9, ToRegister(right), Operand(0x1F));
+    __ and_(scratch, ToRegister(right), Operand(0x1F));
     switch (instr->op()) {
       case Token::SAR:
-        __ mov(result, Operand(result, ASR, r9));
+        __ mov(result, Operand(result, ASR, scratch));
         break;
       case Token::SHR:
         if (instr->can_deopt()) {
-          __ mov(result, Operand(result, LSR, r9), SetCC);
+          __ mov(result, Operand(result, LSR, scratch), SetCC);
           DeoptimizeIf(mi, instr->environment());
         } else {
-          __ mov(result, Operand(result, LSR, r9));
+          __ mov(result, Operand(result, LSR, scratch));
         }
         break;
       case Token::SHL:
-        __ mov(result, Operand(result, LSL, r9));
+        __ mov(result, Operand(result, LSL, scratch));
         break;
       default:
         UNREACHABLE();
@@ -902,7 +949,6 @@
   Register result = ToRegister(instr->result());
   Register array = ToRegister(instr->input());
   __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
-  Abort("DoJSArrayLength untested.");
 }
 
 
@@ -1060,11 +1106,10 @@
       // Test for double values. Zero is false.
       Label call_stub;
       DoubleRegister dbl_scratch = d0;
-      Register core_scratch = r9;
-      ASSERT(!reg.is(core_scratch));
-      __ ldr(core_scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
+      Register scratch = scratch0();
+      __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
       __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
-      __ cmp(core_scratch, Operand(ip));
+      __ cmp(scratch, Operand(ip));
       __ b(ne, &call_stub);
       __ sub(ip, reg, Operand(kHeapObjectTag));
       __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
@@ -1171,11 +1216,41 @@
 
 
 void LCodeGen::DoIsNull(LIsNull* instr) {
-  Abort("DoIsNull unimplemented.");
+  Register reg = ToRegister(instr->input());
+  Register result = ToRegister(instr->result());
+
+  __ LoadRoot(ip, Heap::kNullValueRootIndex);
+  __ cmp(reg, ip);
+  if (instr->is_strict()) {
+    __ LoadRoot(result, Heap::kTrueValueRootIndex, eq);
+    __ LoadRoot(result, Heap::kFalseValueRootIndex, ne);
+  } else {
+    Label true_value, false_value, done;
+    __ b(eq, &true_value);
+    __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+    __ cmp(ip, reg);
+    __ b(eq, &true_value);
+    __ tst(reg, Operand(kSmiTagMask));
+    __ b(eq, &false_value);
+    // Check for undetectable objects by looking in the bit field in
+    // the map. The object has already been smi checked.
+    Register scratch = result;
+    __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
+    __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+    __ tst(scratch, Operand(1 << Map::kIsUndetectable));
+    __ b(ne, &true_value);
+    __ bind(&false_value);
+    __ LoadRoot(result, Heap::kFalseValueRootIndex);
+    __ jmp(&done);
+    __ bind(&true_value);
+    __ LoadRoot(result, Heap::kTrueValueRootIndex);
+    __ bind(&done);
+  }
 }
 
 
 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
+  Register scratch = scratch0();
   Register reg = ToRegister(instr->input());
 
   // TODO(fsc): If the expression is known to be a smi, then it's
@@ -1199,7 +1274,6 @@
     __ b(eq, false_label);
     // Check for undetectable objects by looking in the bit field in
     // the map. The object has already been smi checked.
-    Register scratch = ToRegister(instr->temp());
     __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
     __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
     __ tst(scratch, Operand(1 << Map::kIsUndetectable));
@@ -1277,8 +1351,8 @@
 
 
 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
+  Register scratch = scratch0();
   Register input = ToRegister(instr->input());
-  Register temp = ToRegister(instr->temp());
 
   int true_block = chunk_->LookupDestination(instr->true_block_id());
   int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -1288,7 +1362,7 @@
   __ tst(input, Operand(kSmiTagMask));
   __ b(eq, false_label);
 
-  __ CompareObjectType(input, temp, temp, instr->TestType());
+  __ CompareObjectType(input, scratch, scratch, instr->TestType());
   EmitBranch(true_block, false_block, instr->BranchCondition());
 }
 
@@ -1327,7 +1401,14 @@
 
 
 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
-  Abort("DoCmpMapAndBranch unimplemented.");
+  Register reg = ToRegister(instr->input());
+  Register temp = ToRegister(instr->temp());
+  int true_block = instr->true_block_id();
+  int false_block = instr->false_block_id();
+
+  __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
+  __ cmp(temp, Operand(instr->map()));
+  EmitBranch(true_block, false_block, eq);
 }
 
 
@@ -1429,7 +1510,14 @@
 
 
 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
-  Abort("DoLoadNamedField unimplemented.");
+  Register object = ToRegister(instr->input());
+  Register result = ToRegister(instr->result());
+  if (instr->hydrogen()->is_in_object()) {
+    __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset()));
+  } else {
+    __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
+    __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset()));
+  }
 }
 
 
@@ -1445,19 +1533,19 @@
 
 
 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
+  Register scratch = scratch0();
   Register function = ToRegister(instr->function());
-  Register temp = ToRegister(instr->temporary());
   Register result = ToRegister(instr->result());
 
   // Check that the function really is a function. Load map into the
   // result register.
-  __ CompareObjectType(function, result, temp, JS_FUNCTION_TYPE);
+  __ CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE);
   DeoptimizeIf(ne, instr->environment());
 
   // Make sure that the function has an instance prototype.
   Label non_instance;
-  __ ldrb(temp, FieldMemOperand(result, Map::kBitFieldOffset));
-  __ tst(temp, Operand(1 << Map::kHasNonInstancePrototype));
+  __ ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset));
+  __ tst(scratch, Operand(1 << Map::kHasNonInstancePrototype));
   __ b(ne, &non_instance);
 
   // Get the prototype or initial map from the function.
@@ -1471,7 +1559,7 @@
 
   // If the function does not have an initial map, we're done.
   Label done;
-  __ CompareObjectType(result, temp, temp, MAP_TYPE);
+  __ CompareObjectType(result, scratch, scratch, MAP_TYPE);
   __ b(ne, &done);
 
   // Get the prototype from the initial map.
@@ -1585,7 +1673,9 @@
 
 
 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
-  Abort("DoCallConstantFunction unimplemented.");
+  ASSERT(ToRegister(instr->result()).is(r0));
+  __ mov(r1, Operand(instr->function()));
+  CallKnownFunction(instr->function(), instr->arity(), instr);
 }
 
 
@@ -1645,7 +1735,13 @@
 
 
 void LCodeGen::DoCallFunction(LCallFunction* instr) {
-  Abort("DoCallFunction unimplemented.");
+  ASSERT(ToRegister(instr->result()).is(r0));
+
+  int arity = instr->arity();
+  CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_VALUE);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+  __ Drop(1);
+  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
 }
 
 
@@ -1693,7 +1789,8 @@
 
 
 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
-  Abort("DoBoundsCheck unimplemented.");
+  __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
+  DeoptimizeIf(hs, instr->environment());
 }
 
 
@@ -1798,10 +1895,10 @@
   };
 
   DoubleRegister input_reg = ToDoubleRegister(instr->input());
+  Register scratch = scratch0();
   Register reg = ToRegister(instr->result());
   Register temp1 = ToRegister(instr->temp1());
   Register temp2 = ToRegister(instr->temp2());
-  Register scratch = r9;
 
   DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
   if (FLAG_inline_new) {
@@ -1849,8 +1946,7 @@
 void LCodeGen::EmitNumberUntagD(Register input_reg,
                                 DoubleRegister result_reg,
                                 LEnvironment* env) {
-  Register core_scratch = r9;
-  ASSERT(!input_reg.is(core_scratch));
+  Register scratch = scratch0();
   SwVfpRegister flt_scratch = s0;
   ASSERT(!result_reg.is(d0));
 
@@ -1861,9 +1957,9 @@
   __ b(eq, &load_smi);
 
   // Heap number map check.
-  __ ldr(core_scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
+  __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
   __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
-  __ cmp(core_scratch, Operand(ip));
+  __ cmp(scratch, Operand(ip));
   __ b(eq, &heap_number);
 
   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
@@ -1905,16 +2001,15 @@
 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
   Label done;
   Register input_reg = ToRegister(instr->input());
-  Register core_scratch = r9;
-  ASSERT(!input_reg.is(core_scratch));
+  Register scratch = scratch0();
   DoubleRegister dbl_scratch = d0;
   SwVfpRegister flt_scratch = s0;
   DoubleRegister dbl_tmp = ToDoubleRegister(instr->temp());
 
   // Heap number map check.
-  __ ldr(core_scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
+  __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
   __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
-  __ cmp(core_scratch, Operand(ip));
+  __ cmp(scratch, Operand(ip));
 
   if (instr->truncating()) {
     Label heap_number;
@@ -2026,33 +2121,99 @@
 
 
 void LCodeGen::DoCheckMap(LCheckMap* instr) {
+  Register scratch = scratch0();
   LOperand* input = instr->input();
   ASSERT(input->IsRegister());
   Register reg = ToRegister(input);
-  __ ldr(r9, FieldMemOperand(reg, HeapObject::kMapOffset));
-  __ cmp(r9, Operand(instr->hydrogen()->map()));
+  __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
+  __ cmp(scratch, Operand(instr->hydrogen()->map()));
   DeoptimizeIf(ne, instr->environment());
 }
 
 
 void LCodeGen::LoadPrototype(Register result,
                              Handle<JSObject> prototype) {
-  Abort("LoadPrototype unimplemented.");
+  if (Heap::InNewSpace(*prototype)) {
+    Handle<JSGlobalPropertyCell> cell =
+        Factory::NewJSGlobalPropertyCell(prototype);
+    __ mov(result, Operand(cell));
+  } else {
+    __ mov(result, Operand(prototype));
+  }
 }
 
 
 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
-  Abort("DoCheckPrototypeMaps unimplemented.");
+  Register temp1 = ToRegister(instr->temp1());
+  Register temp2 = ToRegister(instr->temp2());
+
+  Handle<JSObject> holder = instr->holder();
+  Handle<Map> receiver_map = instr->receiver_map();
+  Handle<JSObject> current_prototype(JSObject::cast(receiver_map->prototype()));
+
+  // Load prototype object.
+  LoadPrototype(temp1, current_prototype);
+
+  // Check prototype maps up to the holder.
+  while (!current_prototype.is_identical_to(holder)) {
+    __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
+    __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
+    DeoptimizeIf(ne, instr->environment());
+    current_prototype =
+        Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
+    // Load next prototype object.
+    LoadPrototype(temp1, current_prototype);
+  }
+
+  // Check the holder map.
+  __ ldr(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
+  __ cmp(temp2, Operand(Handle<Map>(current_prototype->map())));
+  DeoptimizeIf(ne, instr->environment());
 }
 
 
 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
-  Abort("DoArrayLiteral unimplemented.");
+  __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
+  __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
+  __ mov(r1, Operand(instr->hydrogen()->constant_elements()));
+  __ Push(r3, r2, r1);
+
+  // Pick the right runtime function or stub to call.
+  int length = instr->hydrogen()->length();
+  if (instr->hydrogen()->IsCopyOnWrite()) {
+    ASSERT(instr->hydrogen()->depth() == 1);
+    FastCloneShallowArrayStub::Mode mode =
+        FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS;
+    FastCloneShallowArrayStub stub(mode, length);
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+  } else if (instr->hydrogen()->depth() > 1) {
+    CallRuntime(Runtime::kCreateArrayLiteral, 3, instr);
+  } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) {
+    CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr);
+  } else {
+    FastCloneShallowArrayStub::Mode mode =
+        FastCloneShallowArrayStub::CLONE_ELEMENTS;
+    FastCloneShallowArrayStub stub(mode, length);
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+  }
 }
 
 
 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) {
-  Abort("DoObjectLiteral unimplemented.");
+  __ ldr(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ ldr(r4, FieldMemOperand(r4, JSFunction::kLiteralsOffset));
+  __ mov(r3, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
+  __ mov(r2, Operand(instr->hydrogen()->constant_properties()));
+  __ mov(r1, Operand(Smi::FromInt(instr->hydrogen()->fast_elements() ? 1 : 0)));
+  __ Push(r4, r3, r2, r1);
+
+  // Pick the right runtime function to call.
+  if (instr->hydrogen()->depth() > 1) {
+    CallRuntime(Runtime::kCreateObjectLiteral, 4, instr);
+  } else {
+    CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr);
+  }
 }
 
 
@@ -2097,8 +2258,7 @@
                                  Register input,
                                  Handle<String> type_name) {
   Condition final_branch_condition = no_condition;
-  Register core_scratch = r9;
-  ASSERT(!input.is(core_scratch));
+  Register scratch = scratch0();
   if (type_name->Equals(Heap::number_symbol())) {
     __ tst(input, Operand(kSmiTagMask));
     __ b(eq, true_label);
@@ -2114,7 +2274,7 @@
     __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
     __ tst(ip, Operand(1 << Map::kIsUndetectable));
     __ b(ne, false_label);
-    __ CompareInstanceType(input, core_scratch, FIRST_NONSTRING_TYPE);
+    __ CompareInstanceType(input, scratch, FIRST_NONSTRING_TYPE);
     final_branch_condition = lo;
 
   } else if (type_name->Equals(Heap::boolean_symbol())) {
@@ -2140,10 +2300,10 @@
   } else if (type_name->Equals(Heap::function_symbol())) {
     __ tst(input, Operand(kSmiTagMask));
     __ b(eq, false_label);
-    __ CompareObjectType(input, input, core_scratch, JS_FUNCTION_TYPE);
+    __ CompareObjectType(input, input, scratch, JS_FUNCTION_TYPE);
     __ b(eq, true_label);
     // Regular expressions => 'function' (they are callable).
-    __ CompareInstanceType(input, core_scratch, JS_REGEXP_TYPE);
+    __ CompareInstanceType(input, scratch, JS_REGEXP_TYPE);
     final_branch_condition = eq;
 
   } else if (type_name->Equals(Heap::object_symbol())) {
@@ -2153,16 +2313,16 @@
     __ cmp(input, ip);
     __ b(eq, true_label);
     // Regular expressions => 'function', not 'object'.
-    __ CompareObjectType(input, input, core_scratch, JS_REGEXP_TYPE);
+    __ CompareObjectType(input, input, scratch, JS_REGEXP_TYPE);
     __ b(eq, false_label);
     // Check for undetectable objects => false.
     __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
     __ tst(ip, Operand(1 << Map::kIsUndetectable));
     __ b(ne, false_label);
     // Check for JS objects => true.
-    __ CompareInstanceType(input, core_scratch, FIRST_JS_OBJECT_TYPE);
+    __ CompareInstanceType(input, scratch, FIRST_JS_OBJECT_TYPE);
     __ b(lo, false_label);
-    __ CompareInstanceType(input, core_scratch, LAST_JS_OBJECT_TYPE);
+    __ CompareInstanceType(input, scratch, LAST_JS_OBJECT_TYPE);
     final_branch_condition = ls;
 
   } else {
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index 541a699..608efa9 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -103,6 +103,8 @@
   HGraph* graph() const { return chunk_->graph(); }
   MacroAssembler* masm() const { return masm_; }
 
+  Register scratch0() { return r9; }
+
   int GetNextEmittedBlock(int block);
   LInstruction* GetNextInstruction();
 
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index f13c0ee..fcf539f 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -47,7 +47,8 @@
 
 
 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
-    : generator_(generator),
+    : Thread("v8:ProfEvntProc"),
+      generator_(generator),
       running_(true),
       ticks_buffer_(sizeof(TickSampleEventRecord),
                     kTickSamplesBufferChunkSize,
diff --git a/src/d8-debug.h b/src/d8-debug.h
index c7acc2f..4e33e6f 100644
--- a/src/d8-debug.h
+++ b/src/d8-debug.h
@@ -98,7 +98,8 @@
 class ReceiverThread: public i::Thread {
  public:
   explicit ReceiverThread(RemoteDebugger* remote_debugger)
-      : remote_debugger_(remote_debugger) {}
+      : Thread("d8:ReceiverThrd"),
+        remote_debugger_(remote_debugger) {}
   ~ReceiverThread() {}
 
   void Run();
@@ -112,7 +113,8 @@
 class KeyboardThread: public i::Thread {
  public:
   explicit KeyboardThread(RemoteDebugger* remote_debugger)
-      : remote_debugger_(remote_debugger) {}
+      : Thread("d8:KeyboardThrd"),
+        remote_debugger_(remote_debugger) {}
   ~KeyboardThread() {}
 
   void Run();
diff --git a/src/d8.cc b/src/d8.cc
index 5a1e63a..f0da7ac 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -599,7 +599,8 @@
 class ShellThread : public i::Thread {
  public:
   ShellThread(int no, i::Vector<const char> files)
-    : no_(no), files_(files) { }
+    : Thread("d8:ShellThread"),
+      no_(no), files_(files) { }
   virtual void Run();
  private:
   int no_;
diff --git a/src/data-flow.h b/src/data-flow.h
index 6e2230c..79d760f 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -112,10 +112,13 @@
   }
 
   void CopyFrom(const BitVector& other) {
-    ASSERT(other.length() == length());
-    for (int i = 0; i < data_length_; i++) {
+    ASSERT(other.length() <= length());
+    for (int i = 0; i < other.data_length_; i++) {
       data_[i] = other.data_[i];
     }
+    for (int i = other.data_length_; i < data_length_; i++) {
+      data_[i] = 0;
+    }
   }
 
   bool Contains(int i) const {
diff --git a/src/debug-agent.h b/src/debug-agent.h
index 3647994..4cedb83 100644
--- a/src/debug-agent.h
+++ b/src/debug-agent.h
@@ -44,7 +44,8 @@
 class DebuggerAgent: public Thread {
  public:
   explicit DebuggerAgent(const char* name, int port)
-      : name_(StrDup(name)), port_(port),
+      : Thread(name),
+        name_(StrDup(name)), port_(port),
         server_(OS::CreateSocket()), terminate_(false),
         session_access_(OS::CreateMutex()), session_(NULL),
         terminate_now_(OS::CreateSemaphore(0)),
@@ -90,7 +91,8 @@
 class DebuggerAgentSession: public Thread {
  public:
   DebuggerAgentSession(DebuggerAgent* agent, Socket* client)
-      : agent_(agent), client_(client) {}
+      : Thread("v8:DbgAgntSessn"),
+        agent_(agent), client_(client) {}
 
   void DebuggerMessage(Vector<uint16_t> message);
   void Shutdown();
diff --git a/src/debug.cc b/src/debug.cc
index ca3c1db..c41e545 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -3037,7 +3037,8 @@
 
 
 MessageDispatchHelperThread::MessageDispatchHelperThread()
-    : sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
+    : Thread("v8:MsgDispHelpr"),
+      sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
       already_signalled_(false) {
 }
 
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index f160a85..2b24d13 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -122,7 +122,6 @@
 DEFINE_bool(trace_alloc, false, "trace register allocator")
 DEFINE_bool(trace_range, false, "trace range analysis")
 DEFINE_bool(trace_gvn, false, "trace global value numbering")
-DEFINE_bool(trace_environment, false, "trace lithium environments")
 DEFINE_bool(trace_representation, false, "trace representation types")
 DEFINE_bool(stress_pointer_maps, false, "pointer map for every instruction")
 DEFINE_bool(stress_environments, false, "environment for every instruction")
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 7b91e87..e7700e9 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -521,6 +521,10 @@
   CALL_AND_RETRY(FUNCTION_CALL, return, return)
 
 
+#define CALL_HEAP_FUNCTION_INLINE(FUNCTION_CALL) \
+  CALL_AND_RETRY(FUNCTION_CALL, break, break)
+
+
 #ifdef DEBUG
 
 inline bool Heap::allow_allocation(bool new_state) {
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index e9c437f..a3c23c6 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -910,6 +910,9 @@
   virtual HBasicBlock* FirstSuccessor() const { return true_destination_; }
   virtual HBasicBlock* SecondSuccessor() const { return false_destination_; }
 
+  HBasicBlock* true_destination() const { return true_destination_; }
+  HBasicBlock* false_destination() const { return false_destination_; }
+
   virtual void PrintDataTo(StringStream* stream) const;
 
   Handle<Map> map() const { return map_; }
@@ -1020,10 +1023,10 @@
 
 class HSimulate: public HInstruction {
  public:
-  HSimulate(int ast_id, int pop_count, int environment_height)
+  HSimulate(int ast_id, int pop_count, int environment_length)
       : ast_id_(ast_id),
         pop_count_(pop_count),
-        environment_height_(environment_height),
+        environment_length_(environment_length),
         values_(2),
         assigned_indexes_(2) {}
   virtual ~HSimulate() {}
@@ -1037,7 +1040,7 @@
     ast_id_ = id;
   }
 
-  int environment_height() const { return environment_height_; }
+  int environment_length() const { return environment_length_; }
   int pop_count() const { return pop_count_; }
   const ZoneList<HValue*>* values() const { return &values_; }
   int GetAssignedIndexAt(int index) const {
@@ -1079,7 +1082,7 @@
   }
   int ast_id_;
   int pop_count_;
-  int environment_height_;
+  int environment_length_;
   ZoneList<HValue*> values_;
   ZoneList<int> assigned_indexes_;
 };
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 03ce5b3..9612ce8 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -128,7 +128,7 @@
   int push_count = environment->push_count();
   int pop_count = environment->pop_count();
 
-  int length = environment->values()->length();
+  int length = environment->length();
   HSimulate* instr = new HSimulate(id, pop_count, length);
   for (int i = push_count - 1; i >= 0; --i) {
     instr->AddPushedValue(environment->ExpressionStackAt(i));
@@ -222,7 +222,7 @@
     ASSERT(IsLoopHeader() || first_ == NULL);
     HEnvironment* incoming_env = pred->last_environment();
     if (IsLoopHeader()) {
-      ASSERT(phis()->length() == incoming_env->values()->length());
+      ASSERT(phis()->length() == incoming_env->length());
       for (int i = 0; i < phis_.length(); ++i) {
         phis_[i]->AddInput(incoming_env->values()->at(i));
       }
@@ -1982,7 +1982,7 @@
     : owner_(owner), kind_(kind), outer_(owner->ast_context()) {
   owner->set_ast_context(this);  // Push.
 #ifdef DEBUG
-  original_count_ = owner->environment()->total_count();
+  original_length_ = owner->environment()->length();
 #endif
 }
 
@@ -1995,14 +1995,14 @@
 EffectContext::~EffectContext() {
   ASSERT(owner()->HasStackOverflow() ||
          !owner()->subgraph()->HasExit() ||
-         owner()->environment()->total_count() == original_count_);
+         owner()->environment()->length() == original_length_);
 }
 
 
 ValueContext::~ValueContext() {
   ASSERT(owner()->HasStackOverflow() ||
          !owner()->subgraph()->HasExit() ||
-         owner()->environment()->total_count() == original_count_ + 1);
+         owner()->environment()->length() == original_length_ + 1);
 }
 
 
@@ -2343,7 +2343,7 @@
   }
 
   // Set the initial values of stack-allocated locals.
-  for (int i = count; i < environment()->values()->length(); ++i) {
+  for (int i = count; i < environment()->length(); ++i) {
     environment()->Bind(i, undefined_constant);
   }
 
@@ -2702,7 +2702,7 @@
   int osr_entry_id = statement->OsrEntryId();
   // We want the correct environment at the OsrEntry instruction.  Build
   // it explicitly.  The expression stack should be empty.
-  int count = osr_entry->last_environment()->total_count();
+  int count = osr_entry->last_environment()->length();
   ASSERT(count == (osr_entry->last_environment()->parameter_count() +
                    osr_entry->last_environment()->local_count()));
   for (int i = 0; i < count; ++i) {
@@ -5279,6 +5279,19 @@
 }
 
 
+void HEnvironment::Initialize(const HEnvironment* other) {
+  closure_ = other->closure();
+  values_.AddAll(other->values_);
+  assigned_variables_.AddAll(other->assigned_variables_);
+  parameter_count_ = other->parameter_count_;
+  local_count_ = other->local_count_;
+  if (other->outer_ != NULL) outer_ = other->outer_->Copy();  // Deep copy.
+  pop_count_ = other->pop_count_;
+  push_count_ = other->push_count_;
+  ast_id_ = other->ast_id_;
+}
+
+
 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) {
   ASSERT(!block->IsLoopHeader());
   ASSERT(values_.length() == other->values_.length());
@@ -5309,26 +5322,45 @@
 }
 
 
-void HEnvironment::Initialize(const HEnvironment* other) {
-  closure_ = other->closure();
-  values_.AddAll(other->values_);
-  assigned_variables_.AddAll(other->assigned_variables_);
-  parameter_count_ = other->parameter_count_;
-  local_count_ = other->local_count_;
-  if (other->outer_ != NULL) outer_ = other->outer_->Copy();  // Deep copy.
-  pop_count_ = other->pop_count_;
-  push_count_ = other->push_count_;
-  ast_id_ = other->ast_id_;
+void HEnvironment::Bind(int index, HValue* value) {
+  ASSERT(value != NULL);
+  if (!assigned_variables_.Contains(index)) {
+    assigned_variables_.Add(index);
+  }
+  values_[index] = value;
 }
 
 
-int HEnvironment::IndexFor(Variable* variable) const {
-  Slot* slot = variable->AsSlot();
-  ASSERT(slot != NULL && slot->IsStackAllocated());
-  if (slot->type() == Slot::PARAMETER) {
-    return slot->index() + 1;
-  } else {
-    return parameter_count_ + slot->index();
+bool HEnvironment::HasExpressionAt(int index) const {
+  return index >= parameter_count_ + local_count_;
+}
+
+
+bool HEnvironment::ExpressionStackIsEmpty() const {
+  int first_expression = parameter_count() + local_count();
+  ASSERT(length() >= first_expression);
+  return length() == first_expression;
+}
+
+
+void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) {
+  int count = index_from_top + 1;
+  int index = values_.length() - count;
+  ASSERT(HasExpressionAt(index));
+  // The push count must include at least the element in question or else
+  // the new value will not be included in this environment's history.
+  if (push_count_ < count) {
+    // This is the same effect as popping then re-pushing 'count' elements.
+    pop_count_ += (count - push_count_);
+    push_count_ = count;
+  }
+  values_[index] = value;
+}
+
+
+void HEnvironment::Drop(int count) {
+  for (int i = 0; i < count; ++i) {
+    Pop();
   }
 }
 
@@ -5393,7 +5425,7 @@
 
 
 void HEnvironment::PrintTo(StringStream* stream) {
-  for (int i = 0; i < total_count(); i++) {
+  for (int i = 0; i < length(); i++) {
     if (i == 0) stream->Add("parameters\n");
     if (i == parameter_count()) stream->Add("locals\n");
     if (i == parameter_count() + local_count()) stream->Add("expressions");
diff --git a/src/hydrogen.h b/src/hydrogen.h
index ebabf3d..872ae98 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -401,27 +401,33 @@
                Scope* scope,
                Handle<JSFunction> closure);
 
+  // Simple accessors.
+  Handle<JSFunction> closure() const { return closure_; }
+  const ZoneList<HValue*>* values() const { return &values_; }
+  const ZoneList<int>* assigned_variables() const {
+    return &assigned_variables_;
+  }
+  int parameter_count() const { return parameter_count_; }
+  int local_count() const { return local_count_; }
+  HEnvironment* outer() const { return outer_; }
+  int pop_count() const { return pop_count_; }
+  int push_count() const { return push_count_; }
+
+  int ast_id() const { return ast_id_; }
+  void set_ast_id(int id) { ast_id_ = id; }
+
+  int length() const { return values_.length(); }
+
   void Bind(Variable* variable, HValue* value) {
     Bind(IndexFor(variable), value);
-
-    if (FLAG_trace_environment) {
-      PrintF("Slot index=%d name=%s\n",
-             variable->AsSlot()->index(),
-             *variable->name()->ToCString());
-    }
   }
 
-  void Bind(int index, HValue* value) {
-    ASSERT(value != NULL);
-    if (!assigned_variables_.Contains(index)) {
-      assigned_variables_.Add(index);
-    }
-    values_[index] = value;
-  }
+  void Bind(int index, HValue* value);
 
   HValue* Lookup(Variable* variable) const {
     return Lookup(IndexFor(variable));
   }
+
   HValue* Lookup(int index) const {
     HValue* result = values_[index];
     ASSERT(result != NULL);
@@ -434,53 +440,28 @@
     values_.Add(value);
   }
 
-  HValue* Top() const { return ExpressionStackAt(0); }
-
-  HValue* ExpressionStackAt(int index_from_top) const {
-    int index = values_.length() - index_from_top - 1;
-    ASSERT(IsExpressionStackIndex(index));
-    return values_[index];
-  }
-
-  void SetExpressionStackAt(int index_from_top, HValue* value) {
-    int index = values_.length() - index_from_top - 1;
-    ASSERT(IsExpressionStackIndex(index));
-    values_[index] = value;
-  }
-
   HValue* Pop() {
-    ASSERT(!IsExpressionStackEmpty());
+    ASSERT(!ExpressionStackIsEmpty());
     if (push_count_ > 0) {
       --push_count_;
-      ASSERT(push_count_ >= 0);
     } else {
       ++pop_count_;
     }
     return values_.RemoveLast();
   }
 
-  void Drop(int count) {
-    for (int i = 0; i < count; ++i) {
-      Pop();
-    }
+  void Drop(int count);
+
+  HValue* Top() const { return ExpressionStackAt(0); }
+
+  HValue* ExpressionStackAt(int index_from_top) const {
+    int index = length() - index_from_top - 1;
+    ASSERT(HasExpressionAt(index));
+    return values_[index];
   }
 
-  Handle<JSFunction> closure() const { return closure_; }
+  void SetExpressionStackAt(int index_from_top, HValue* value);
 
-  // ID of the original AST node to identify deoptimization points.
-  int ast_id() const { return ast_id_; }
-  void set_ast_id(int id) { ast_id_ = id; }
-
-  const ZoneList<HValue*>* values() const { return &values_; }
-  const ZoneList<int>* assigned_variables() const {
-    return &assigned_variables_;
-  }
-  int parameter_count() const { return parameter_count_; }
-  int local_count() const { return local_count_; }
-  int push_count() const { return push_count_; }
-  int pop_count() const { return pop_count_; }
-  int total_count() const { return values_.length(); }
-  HEnvironment* outer() const { return outer_; }
   HEnvironment* Copy() const;
   HEnvironment* CopyWithoutHistory() const;
   HEnvironment* CopyAsLoopHeader(HBasicBlock* block) const;
@@ -496,13 +477,15 @@
                                 HConstant* undefined) const;
 
   void AddIncomingEdge(HBasicBlock* block, HEnvironment* other);
+
   void ClearHistory() {
     pop_count_ = 0;
     push_count_ = 0;
     assigned_variables_.Clear();
   }
+
   void SetValueAt(int index, HValue* value) {
-    ASSERT(index < total_count());
+    ASSERT(index < length());
     values_[index] = value;
   }
 
@@ -512,19 +495,23 @@
  private:
   explicit HEnvironment(const HEnvironment* other);
 
-  bool IsExpressionStackIndex(int index) const {
-    return index >= parameter_count_ + local_count_;
-  }
-  bool IsExpressionStackEmpty() const {
-    int length = values_.length();
-    int first_expression = parameter_count() + local_count();
-    ASSERT(length >= first_expression);
-    return length == first_expression;
-  }
+  // True if index is included in the expression stack part of the environment.
+  bool HasExpressionAt(int index) const;
+
+  bool ExpressionStackIsEmpty() const;
+
   void Initialize(int parameter_count, int local_count, int stack_height);
   void Initialize(const HEnvironment* other);
-  int VariableToIndex(Variable* var);
-  int IndexFor(Variable* variable) const;
+
+  // Map a variable to an environment index.  Parameter indices are shifted
+  // by 1 (receiver is parameter index -1 but environment index 0).
+  // Stack-allocated local indices are shifted by the number of parameters.
+  int IndexFor(Variable* variable) const {
+    Slot* slot = variable->AsSlot();
+    ASSERT(slot != NULL && slot->IsStackAllocated());
+    int shift = (slot->type() == Slot::PARAMETER) ? 1 : parameter_count_;
+    return slot->index() + shift;
+  }
 
   Handle<JSFunction> closure_;
   // Value array [parameters] [locals] [temporaries].
@@ -567,7 +554,7 @@
   // We want to be able to assert, in a context-specific way, that the stack
   // height makes sense when the context is filled.
 #ifdef DEBUG
-  int original_count_;
+  int original_length_;
 #endif
 
  private:
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 918f346..0a3e093 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -399,7 +399,7 @@
 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
                                              bool is_construct) {
   // Clear the context before we push it when entering the JS frame.
-  __ xor_(esi, Operand(esi));  // clear esi
+  __ Set(esi, Immediate(0));
 
   // Enter an internal frame.
   __ EnterInternalFrame();
@@ -421,7 +421,7 @@
 
   // Copy arguments to the stack in a loop.
   Label loop, entry;
-  __ xor_(ecx, Operand(ecx));  // clear ecx
+  __ Set(ecx, Immediate(0));
   __ jmp(&entry);
   __ bind(&loop);
   __ mov(edx, Operand(ebx, ecx, times_4, 0));  // push parameter from argv
@@ -644,7 +644,7 @@
   __ bind(&non_function);
   __ mov(Operand(esp, eax, times_4, 0), edi);
   // Clear edi to indicate a non-function being called.
-  __ xor_(edi, Operand(edi));
+  __ Set(edi, Immediate(0));
 
   // 4. Shift arguments and return address one slot down on the stack
   //    (overwriting the original receiver).  Adjust argument count to make
@@ -665,7 +665,7 @@
   { Label function;
     __ test(edi, Operand(edi));
     __ j(not_zero, &function, taken);
-    __ xor_(ebx, Operand(ebx));
+    __ Set(ebx, Immediate(0));
     __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
     __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
            RelocInfo::CODE_TARGET);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index a371c96..bd95c8d 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -104,7 +104,7 @@
          Immediate(Smi::FromInt(length)));
 
   // Setup the fixed slots.
-  __ xor_(ebx, Operand(ebx));  // Set to NULL.
+  __ Set(ebx, Immediate(0));  // Set to NULL.
   __ mov(Operand(eax, Context::SlotOffset(Context::CLOSURE_INDEX)), ecx);
   __ mov(Operand(eax, Context::SlotOffset(Context::FCONTEXT_INDEX)), eax);
   __ mov(Operand(eax, Context::SlotOffset(Context::PREVIOUS_INDEX)), ebx);
@@ -4303,7 +4303,7 @@
       // that contains the exponent and high bit of the mantissa.
       STATIC_ASSERT(((kQuietNaNHighBitsMask << 1) & 0x80000000u) != 0);
       __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
-      __ xor_(eax, Operand(eax));
+      __ Set(eax, Immediate(0));
       // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
       // bits.
       __ add(edx, Operand(edx));
@@ -4433,7 +4433,7 @@
       __ j(below, &below_label, not_taken);
       __ j(above, &above_label, not_taken);
 
-      __ xor_(eax, Operand(eax));
+      __ Set(eax, Immediate(0));
       __ ret(0);
 
       __ bind(&below_label);
@@ -4646,7 +4646,7 @@
   // Before returning we restore the context from the frame pointer if
   // not NULL.  The frame pointer is NULL in the exception handler of
   // a JS entry frame.
-  __ xor_(esi, Operand(esi));  // Tentatively set context pointer to NULL.
+  __ Set(esi, Immediate(0));  // Tentatively set context pointer to NULL.
   NearLabel skip;
   __ cmp(ebp, 0);
   __ j(equal, &skip, not_taken);
@@ -4799,7 +4799,7 @@
   }
 
   // Clear the context pointer.
-  __ xor_(esi, Operand(esi));
+  __ Set(esi, Immediate(0));
 
   // Restore fp from handler and discard handler state.
   STATIC_ASSERT(StackHandlerConstants::kFPOffset == 1 * kPointerSize);
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
index ee94565..678cc93 100644
--- a/src/ia32/debug-ia32.cc
+++ b/src/ia32/debug-ia32.cc
@@ -125,7 +125,7 @@
 #ifdef DEBUG
   __ RecordComment("// Calling from debug break to runtime - come in - over");
 #endif
-  __ Set(eax, Immediate(0));  // no arguments
+  __ Set(eax, Immediate(0));  // No arguments.
   __ mov(ebx, Immediate(ExternalReference::debug_break()));
 
   CEntryStub ceb(1);
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 9c9304d..90bfd4b 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -1199,7 +1199,7 @@
         break;
       case kExternalShortArray:
       case kExternalUnsignedShortArray:
-        __ xor_(ecx, Operand(ecx));
+        __ Set(ecx, Immediate(0));
         __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
         break;
       case kExternalIntArray:
@@ -1219,9 +1219,6 @@
 }
 
 
-// Defined in ic.cc.
-Object* CallIC_Miss(Arguments args);
-
 // The generated code does not accept smi keys.
 // The generated code falls through if both probes miss.
 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
@@ -1567,9 +1564,6 @@
 }
 
 
-// Defined in ic.cc.
-Object* LoadIC_Miss(Arguments args);
-
 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : receiver
@@ -1795,10 +1789,6 @@
 }
 
 
-// Defined in ic.cc.
-Object* KeyedLoadIC_Miss(Arguments args);
-
-
 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : key
@@ -1982,9 +1972,6 @@
 }
 
 
-// Defined in ic.cc.
-Object* KeyedStoreIC_Miss(Arguments args);
-
 void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- eax    : value
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 9569ac8..0f56825 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3039,7 +3039,7 @@
   __ push(Immediate(instr->hydrogen()->constant_properties()));
   __ push(Immediate(Smi::FromInt(instr->hydrogen()->fast_elements() ? 1 : 0)));
 
-  // Pick the right runtime function or stub to call.
+  // Pick the right runtime function to call.
   if (instr->hydrogen()->depth() > 1) {
     CallRuntime(Runtime::kCreateObjectLiteral, 4, instr);
   } else {
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 8c003a5..4fde3d4 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -767,11 +767,6 @@
 }
 
 
-LInstruction* LChunkBuilder::DefineSameAsAny(LInstruction* instr) {
-  return Define(instr, new LUnallocated(LUnallocated::SAME_AS_ANY_INPUT));
-}
-
-
 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) {
   return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
 }
@@ -1016,9 +1011,6 @@
   HInstruction* current = block->first();
   int start = chunk_->instructions()->length();
   while (current != NULL && !is_aborted()) {
-    if (FLAG_trace_environment) {
-      PrintF("Process instruction %d\n", current->id());
-    }
     // Code for constants in registers is generated lazily.
     if (!current->EmitAtUses()) {
       VisitInstruction(current);
@@ -1125,7 +1117,7 @@
   LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
   int ast_id = hydrogen_env->ast_id();
   ASSERT(ast_id != AstNode::kNoNumber);
-  int value_count = hydrogen_env->values()->length();
+  int value_count = hydrogen_env->length();
   LEnvironment* result = new LEnvironment(hydrogen_env->closure(),
                                           ast_id,
                                           hydrogen_env->parameter_count(),
@@ -2039,7 +2031,7 @@
 
 
 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
-  LInstruction* result = new LTypeof(Use(instr->value()));
+  LInstruction* result = new LTypeof(UseAtStart(instr->value()));
   return MarkAsCall(DefineFixed(result, eax), instr);
 }
 
@@ -2063,14 +2055,7 @@
       env->Push(value);
     }
   }
-
-  if (FLAG_trace_environment) {
-    PrintF("Reconstructed environment ast_id=%d, instr_id=%d\n",
-           instr->ast_id(),
-           instr->id());
-    env->PrintToStd();
-  }
-  ASSERT(env->values()->length() == instr->environment_height());
+  ASSERT(env->length() == instr->environment_length());
 
   // If there is an instruction pending deoptimization environment create a
   // lazy bailout instruction to capture the environment.
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 94bf8fd..00dc394 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -2087,7 +2087,6 @@
   LInstruction* Define(LInstruction* instr);
   LInstruction* DefineAsRegister(LInstruction* instr);
   LInstruction* DefineAsSpilled(LInstruction* instr, int index);
-  LInstruction* DefineSameAsAny(LInstruction* instr);
   LInstruction* DefineSameAsFirst(LInstruction* instr);
   LInstruction* DefineFixed(LInstruction* instr, Register reg);
   LInstruction* DefineFixedDouble(LInstruction* instr, XMMRegister reg);
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index cc2f30d..1213448 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -652,7 +652,7 @@
 
 void RegExpMacroAssemblerIA32::Fail() {
   ASSERT(FAILURE == 0);  // Return value for failure is zero.
-  __ xor_(eax, Operand(eax));  // zero eax.
+  __ Set(eax, Immediate(0));
   __ jmp(&exit_label_);
 }
 
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 99888b0..bcb02ed 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1686,6 +1686,7 @@
 
   Label miss;
   Label index_out_of_range;
+
   GenerateNameCheck(name, &miss);
 
   // Check that the maps starting from the prototype haven't changed.
diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
index ac61c17..eecc441 100644
--- a/src/lithium-allocator.cc
+++ b/src/lithium-allocator.cc
@@ -27,7 +27,6 @@
 
 #include "lithium-allocator.h"
 
-#include "data-flow.h"
 #include "hydrogen.h"
 #include "string-stream.h"
 
@@ -107,9 +106,6 @@
         case LUnallocated::SAME_AS_FIRST_INPUT:
           stream->Add("(1)");
           break;
-        case LUnallocated::SAME_AS_ANY_INPUT:
-          stream->Add("(A)");
-          break;
         case LUnallocated::ANY:
           stream->Add("(-)");
           break;
@@ -834,6 +830,13 @@
       } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) {
         LUnallocated* input_copy = cur_input->CopyUnconstrained();
         cur_input->set_virtual_register(next_virtual_register_++);
+
+        if (RequiredRegisterKind(input_copy->virtual_register()) ==
+            DOUBLE_REGISTERS) {
+          double_artificial_registers_.Add(
+              cur_input->virtual_register() - first_artificial_register_);
+        }
+
         second->AddTemp(cur_input);
         AddConstraintsGapMove(gap_index, input_copy, cur_input);
       }
@@ -1036,6 +1039,7 @@
 
 void LAllocator::MeetRegisterConstraints() {
   HPhase phase("Register constraints", chunk());
+  first_artificial_register_ = next_virtual_register_;
   const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
   for (int i = 0; i < blocks->length(); ++i) {
     HBasicBlock* block = blocks->at(i);
@@ -1564,16 +1568,42 @@
 
 
 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const {
-  HValue* value = graph()->LookupValue(virtual_register);
-  if (value != NULL && value->representation().IsDouble()) {
+  if (virtual_register < first_artificial_register_) {
+    HValue* value = graph()->LookupValue(virtual_register);
+    if (value != NULL && value->representation().IsDouble()) {
+      return DOUBLE_REGISTERS;
+    }
+  } else if (double_artificial_registers_.Contains(
+      virtual_register - first_artificial_register_)) {
     return DOUBLE_REGISTERS;
   }
+
   return GENERAL_REGISTERS;
 }
 
 
 void LAllocator::MarkAsCall() {
-  current_summary()->MarkAsCall();
+  // Call instructions can use only fixed registers as
+  // temporaries and outputs because all registers
+  // are blocked by the calling convention.
+  // Inputs can use either fixed register or have a short lifetime (be
+  // used at start of the instruction).
+  InstructionSummary* summary = current_summary();
+#ifdef DEBUG
+  ASSERT(summary->Output() == NULL ||
+         LUnallocated::cast(summary->Output())->HasFixedPolicy() ||
+         !LUnallocated::cast(summary->Output())->HasRegisterPolicy());
+  for (int i = 0; i < summary->InputCount(); i++) {
+    ASSERT(LUnallocated::cast(summary->InputAt(i))->HasFixedPolicy() ||
+           LUnallocated::cast(summary->InputAt(i))->IsUsedAtStart() ||
+           !LUnallocated::cast(summary->InputAt(i))->HasRegisterPolicy());
+  }
+  for (int i = 0; i < summary->TempCount(); i++) {
+    ASSERT(LUnallocated::cast(summary->TempAt(i))->HasFixedPolicy() ||
+           !LUnallocated::cast(summary->TempAt(i))->HasRegisterPolicy());
+  }
+#endif
+  summary->MarkAsCall();
 }
 
 
diff --git a/src/lithium-allocator.h b/src/lithium-allocator.h
index 3ec984e..fe837e2 100644
--- a/src/lithium-allocator.h
+++ b/src/lithium-allocator.h
@@ -30,6 +30,7 @@
 
 #include "v8.h"
 
+#include "data-flow.h"
 #include "zone.h"
 
 namespace v8 {
@@ -204,7 +205,6 @@
     MUST_HAVE_REGISTER,
     WRITABLE_REGISTER,
     SAME_AS_FIRST_INPUT,
-    SAME_AS_ANY_INPUT,
     IGNORE
   };
 
@@ -275,7 +275,7 @@
     return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER;
   }
   bool HasSameAsInputPolicy() const {
-    return policy() == SAME_AS_FIRST_INPUT || policy() == SAME_AS_ANY_INPUT;
+    return policy() == SAME_AS_FIRST_INPUT;
   }
   Policy policy() const { return PolicyField::decode(value_); }
   void set_policy(Policy policy) {
@@ -754,6 +754,40 @@
 };
 
 
+class GrowableBitVector BASE_EMBEDDED {
+ public:
+  GrowableBitVector() : bits_(NULL) { }
+
+  bool Contains(int value) const {
+    if (!InBitsRange(value)) return false;
+    return bits_->Contains(value);
+  }
+
+  void Add(int value) {
+    EnsureCapacity(value);
+    bits_->Add(value);
+  }
+
+ private:
+  static const int kInitialLength = 1024;
+
+  bool InBitsRange(int value) const {
+    return bits_ != NULL && bits_->length() > value;
+  }
+
+  void EnsureCapacity(int value) {
+    if (InBitsRange(value)) return;
+    int new_length = bits_ == NULL ? kInitialLength : bits_->length();
+    while (new_length <= value) new_length *= 2;
+    BitVector* new_bits = new BitVector(new_length);
+    if (bits_ != NULL) new_bits->CopyFrom(*bits_);
+    bits_ = new_bits;
+  }
+
+  BitVector* bits_;
+};
+
+
 class LAllocator BASE_EMBEDDED {
  public:
   explicit LAllocator(int first_virtual_register, HGraph* graph)
@@ -770,6 +804,7 @@
         inactive_live_ranges_(8),
         reusable_slots_(8),
         next_virtual_register_(first_virtual_register),
+        first_artificial_register_(first_virtual_register),
         mode_(NONE),
         num_registers_(-1),
         graph_(graph),
@@ -972,6 +1007,8 @@
 
   // Next virtual register number to be assigned to temporaries.
   int next_virtual_register_;
+  int first_artificial_register_;
+  GrowableBitVector double_artificial_registers_;
 
   RegisterKind mode_;
   int num_registers_;
diff --git a/src/log.cc b/src/log.cc
index db9ff7a..6eb3c9b 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -276,7 +276,8 @@
 // Profiler implementation.
 //
 Profiler::Profiler()
-    : head_(0),
+    : Thread("v8:Profiler"),
+      head_(0),
       tail_(0),
       overflow_(false),
       buffer_semaphore_(OS::CreateSemaphore(0)),
diff --git a/src/objects.cc b/src/objects.cc
index 8c8b6e0..927194f 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2932,7 +2932,6 @@
 
   uint32_t index = 0;
   bool is_element = name->AsArrayIndex(&index);
-  if (is_element && IsJSArray()) return Heap::undefined_value();
 
   if (is_element) {
     switch (GetElementsKind()) {
@@ -6795,7 +6794,8 @@
 
 
 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index,
-                                                 Object* value) {
+                                                 Object* value,
+                                                 bool check_prototype) {
   // Make sure that the top context does not change when doing
   // callbacks or interceptor calls.
   AssertNoContextChange ncc;
@@ -6819,7 +6819,9 @@
     if (!result.IsEmpty()) return *value_handle;
   }
   MaybeObject* raw_result =
-      this_handle->SetElementWithoutInterceptor(index, *value_handle);
+      this_handle->SetElementWithoutInterceptor(index,
+                                                *value_handle,
+                                                check_prototype);
   RETURN_IF_SCHEDULED_EXCEPTION();
   return raw_result;
 }
@@ -6930,7 +6932,9 @@
 // Adding n elements in fast case is O(n*n).
 // Note: revisit design to have dual undefined values to capture absent
 // elements.
-MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value) {
+MaybeObject* JSObject::SetFastElement(uint32_t index,
+                                      Object* value,
+                                      bool check_prototype) {
   ASSERT(HasFastElements());
 
   Object* elms_obj;
@@ -6940,12 +6944,13 @@
   FixedArray* elms = FixedArray::cast(elms_obj);
   uint32_t elms_length = static_cast<uint32_t>(elms->length());
 
-  if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) {
-    if (SetElementWithCallbackSetterInPrototypes(index, value)) {
-      return value;
-    }
+  if (check_prototype &&
+      (index >= elms_length || elms->get(index)->IsTheHole()) &&
+      SetElementWithCallbackSetterInPrototypes(index, value)) {
+    return value;
   }
 
+
   // Check whether there is extra space in fixed array..
   if (index < elms_length) {
     elms->set(index, value);
@@ -6983,11 +6988,13 @@
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
   ASSERT(HasDictionaryElements());
-  return SetElement(index, value);
+  return SetElement(index, value, check_prototype);
 }
 
 
-MaybeObject* JSObject::SetElement(uint32_t index, Object* value) {
+MaybeObject* JSObject::SetElement(uint32_t index,
+                                  Object* value,
+                                  bool check_prototype) {
   // Check access rights if needed.
   if (IsAccessCheckNeeded() &&
       !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) {
@@ -7001,24 +7008,25 @@
     Object* proto = GetPrototype();
     if (proto->IsNull()) return value;
     ASSERT(proto->IsJSGlobalObject());
-    return JSObject::cast(proto)->SetElement(index, value);
+    return JSObject::cast(proto)->SetElement(index, value, check_prototype);
   }
 
   // Check for lookup interceptor
   if (HasIndexedInterceptor()) {
-    return SetElementWithInterceptor(index, value);
+    return SetElementWithInterceptor(index, value, check_prototype);
   }
 
-  return SetElementWithoutInterceptor(index, value);
+  return SetElementWithoutInterceptor(index, value, check_prototype);
 }
 
 
 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
-                                                    Object* value) {
+                                                    Object* value,
+                                                    bool check_prototype) {
   switch (GetElementsKind()) {
     case FAST_ELEMENTS:
       // Fast case.
-      return SetFastElement(index, value);
+      return SetFastElement(index, value, check_prototype);
     case PIXEL_ELEMENTS: {
       PixelArray* pixels = PixelArray::cast(elements());
       return pixels->SetValue(index, value);
@@ -7071,10 +7079,9 @@
         }
       } else {
         // Index not already used. Look for an accessor in the prototype chain.
-        if (!IsJSArray()) {
-          if (SetElementWithCallbackSetterInPrototypes(index, value)) {
-            return value;
-          }
+        if (check_prototype &&
+            SetElementWithCallbackSetterInPrototypes(index, value)) {
+          return value;
         }
         // When we set the is_extensible flag to false we always force
         // the element into dictionary mode (and force them to stay there).
diff --git a/src/objects.h b/src/objects.h
index 163b713..eac7f92 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1505,11 +1505,15 @@
   bool HasElementWithInterceptor(JSObject* receiver, uint32_t index);
   bool HasElementPostInterceptor(JSObject* receiver, uint32_t index);
 
-  MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index, Object* value);
+  MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
+                                              Object* value,
+                                              bool check_prototype = true);
 
   // Set the index'th array element.
   // A Failure object is returned if GC is needed.
-  MUST_USE_RESULT MaybeObject* SetElement(uint32_t index, Object* value);
+  MUST_USE_RESULT MaybeObject* SetElement(uint32_t index,
+                                          Object* value,
+                                          bool check_prototype = true);
 
   // Returns the index'th element.
   // The undefined object if index is out of bounds.
@@ -1763,9 +1767,12 @@
                                       Object* value,
                                       JSObject* holder);
   MUST_USE_RESULT MaybeObject* SetElementWithInterceptor(uint32_t index,
-                                                         Object* value);
-  MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor(uint32_t index,
-                                                            Object* value);
+                                                         Object* value,
+                                                         bool check_prototype);
+  MUST_USE_RESULT MaybeObject* SetElementWithoutInterceptor(
+      uint32_t index,
+      Object* value,
+      bool check_prototype);
 
   MaybeObject* GetElementPostInterceptor(JSObject* receiver, uint32_t index);
 
diff --git a/src/parser.cc b/src/parser.cc
index 03819ee..5526933 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -2995,14 +2995,22 @@
   // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
   // We have already read the "get" or "set" keyword.
   Token::Value next = Next();
-  // TODO(820): Allow NUMBER and STRING as well (and handle array indices).
-  if (next == Token::IDENTIFIER || Token::IsKeyword(next)) {
-    Handle<String> name = GetSymbol(CHECK_OK);
+  bool is_keyword = Token::IsKeyword(next);
+  if (next == Token::IDENTIFIER || next == Token::NUMBER ||
+      next == Token::STRING || is_keyword) {
+    Handle<String> name;
+    if (is_keyword) {
+      name = Factory::LookupAsciiSymbol(Token::String(next));
+    } else {
+      name = GetSymbol(CHECK_OK);
+    }
     FunctionLiteral* value =
         ParseFunctionLiteral(name,
                              RelocInfo::kNoPosition,
                              DECLARATION,
                              CHECK_OK);
+    // Allow any number of parameters for compatiabilty with JSC.
+    // Specification only allows zero parameters for get and one for set.
     ObjectLiteral::Property* property =
         new ObjectLiteral::Property(is_getter, value);
     return property;
@@ -3672,9 +3680,11 @@
       if (value.is_null()) return Handle<Object>::null();
       uint32_t index;
       if (key->AsArrayIndex(&index)) {
-        SetElement(json_object, index, value);
+        CALL_HEAP_FUNCTION_INLINE(
+            (*json_object)->SetElement(index, *value, true));
       } else {
-        SetProperty(json_object, key, value, NONE);
+        CALL_HEAP_FUNCTION_INLINE(
+            (*json_object)->SetPropertyPostInterceptor(*key, *value, NONE));
       }
     } while (scanner_.Next() == Token::COMMA);
     if (scanner_.current_token() != Token::RBRACE) {
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index b58d066..ad1e499 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -411,6 +411,12 @@
 
 
 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
+  set_name("v8:<unknown>");
+}
+
+
+Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
+  set_names(name);
 }
 
 
@@ -430,6 +436,12 @@
 }
 
 
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
 void Thread::Start() {
   pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
   ASSERT(IsValid());
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 7efb25d..755e8cd 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -31,6 +31,7 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
+#include <sys/prctl.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/syscall.h>
@@ -551,6 +552,12 @@
 
 
 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
+  set_name("v8:<unknown>");
+}
+
+
+Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
+  set_name(name);
 }
 
 
@@ -563,6 +570,7 @@
   // This is also initialized by the first argument to pthread_create() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
+  prctl(PR_SET_NAME, thread->name(), 0, 0, 0);
   thread->thread_handle_data()->thread_ = pthread_self();
   ASSERT(thread->IsValid());
   thread->Run();
@@ -570,6 +578,12 @@
 }
 
 
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
 void Thread::Start() {
   pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
   ASSERT(IsValid());
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 85c7088..ce53305 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -28,6 +28,7 @@
 // Platform specific code for MacOS goes here. For the POSIX comaptible parts
 // the implementation is in platform-posix.cc.
 
+#include <dlfcn.h>
 #include <unistd.h>
 #include <sys/mman.h>
 #include <mach/mach_init.h>
@@ -49,7 +50,6 @@
 #include <sys/types.h>
 #include <stdarg.h>
 #include <stdlib.h>
-
 #include <errno.h>
 
 #undef MAP_TYPE
@@ -411,6 +411,12 @@
 
 
 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
+  set_name("v8:<unknown>");
+}
+
+
+Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
+  set_name(name);
 }
 
 
@@ -418,18 +424,43 @@
 }
 
 
+
+static void SetThreadName(const char* name) {
+  // pthread_setname_np is only available in 10.6 or later, so test
+  // for it at runtime.
+  int (*dynamic_pthread_setname_np)(const char*);
+  *reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
+    dlsym(RTLD_DEFAULT, "pthread_setname_np");
+  if (!dynamic_pthread_setname_np)
+    return;
+
+  // Mac OS X does not expose the length limit of the name, so hardcode it.
+  static const int kMaxNameLength = 63;
+  USE(kMaxNameLength);
+  ASSERT(Thread::kMaxThreadNameLength <= kMaxNameLength);
+  dynamic_pthread_setname_np(name);
+}
+
+
 static void* ThreadEntry(void* arg) {
   Thread* thread = reinterpret_cast<Thread*>(arg);
   // This is also initialized by the first argument to pthread_create() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
   thread->thread_handle_data()->thread_ = pthread_self();
+  SetThreadName(thread->name());
   ASSERT(thread->IsValid());
   thread->Run();
   return NULL;
 }
 
 
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
 void Thread::Start() {
   pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
 }
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index 72ea0e5..f1b7695 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -335,6 +335,13 @@
 
 
 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
+  set_name("v8:<unknown>");
+  UNIMPLEMENTED();
+}
+
+
+Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
+  set_name(name);
   UNIMPLEMENTED();
 }
 
@@ -344,6 +351,12 @@
 }
 
 
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
 void Thread::Start() {
   UNIMPLEMENTED();
 }
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index b698d16..5de6081 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -387,6 +387,12 @@
 
 
 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
+  set_name("v8:<unknown>");
+}
+
+
+Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
+  set_name(name);
 }
 
 
@@ -406,6 +412,12 @@
 }
 
 
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
 void Thread::Start() {
   pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
   ASSERT(IsValid());
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index f84e80d..04c25a9 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -401,6 +401,12 @@
 
 
 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
+  set_name("v8:<unknown>");
+}
+
+
+Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
+  set_name(name);
 }
 
 
@@ -420,6 +426,12 @@
 }
 
 
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
 void Thread::Start() {
   pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
   ASSERT(IsValid());
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 4438045..81216e1 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1463,6 +1463,19 @@
 
 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) {
   data_ = new PlatformData(kNoThread);
+  set_name("v8:<unknown>");
+}
+
+
+Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) {
+  data_ = new PlatformData(kNoThread);
+  set_name(name);
+}
+
+
+void Thread::set_name(const char* name) {
+  strncpy_s(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
 }
 
 
diff --git a/src/platform.h b/src/platform.h
index 5a3e4a3..7b17067 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -387,6 +387,7 @@
 
   // Create new thread.
   Thread();
+  explicit Thread(const char* name);
   virtual ~Thread();
 
   // Start new thread by calling the Run() method in the new thread.
@@ -395,6 +396,10 @@
   // Wait until thread terminates.
   void Join();
 
+  inline const char* name() const {
+    return name_;
+  }
+
   // Abstract method for run handler.
   virtual void Run() = 0;
 
@@ -416,9 +421,17 @@
   // A hint to the scheduler to let another thread run.
   static void YieldCPU();
 
+  // The thread name length is limited to 16 based on Linux's implementation of
+  // prctl().
+  static const int kMaxThreadNameLength = 16;
  private:
+  void set_name(const char *name);
+
   class PlatformData;
   PlatformData* data_;
+
+  char name_[kMaxThreadNameLength];
+
   DISALLOW_COPY_AND_ASSIGN(Thread);
 };
 
diff --git a/src/preparser-api.cc b/src/preparser-api.cc
index cbec9b7..dba3026 100644
--- a/src/preparser-api.cc
+++ b/src/preparser-api.cc
@@ -155,7 +155,6 @@
  public:
   void Initialize(UC16CharacterStream* source) {
     source_ = source;
-    literal_flags_ = kLiteralString | kLiteralIdentifier;
     Init();
     // Skip initial whitespace allowing HTML comment ends just like
     // after a newline and scan first token.
diff --git a/src/preparser.cc b/src/preparser.cc
index 157fbea..e05f903 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -950,13 +950,17 @@
         ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
         if ((is_getter || is_setter) && peek() != i::Token::COLON) {
             i::Token::Value name = Next();
+            bool is_keyword = i::Token::IsKeyword(name);
             if (name != i::Token::IDENTIFIER &&
                 name != i::Token::NUMBER &&
                 name != i::Token::STRING &&
-                !i::Token::IsKeyword(name)) {
+                !is_keyword) {
               *ok = false;
               return kUnknownExpression;
             }
+            if (!is_keyword) {
+              LogSymbol();
+            }
             ParseFunctionLiteral(CHECK_OK);
             if (peek() != i::Token::RBRACE) {
               Expect(i::Token::COMMA, CHECK_OK);
@@ -1120,24 +1124,24 @@
 }
 
 
-PreParser::Identifier PreParser::GetIdentifierSymbol() {
+void PreParser::LogSymbol() {
   int identifier_pos = scanner_->location().beg_pos;
   if (scanner_->is_literal_ascii()) {
     log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string());
   } else {
     log_->LogUC16Symbol(identifier_pos, scanner_->literal_uc16_string());
   }
+}
+
+
+PreParser::Identifier PreParser::GetIdentifierSymbol() {
+  LogSymbol();
   return kUnknownIdentifier;
 }
 
 
 PreParser::Expression PreParser::GetStringSymbol() {
-  int identifier_pos = scanner_->location().beg_pos;
-  if (scanner_->is_literal_ascii()) {
-    log_->LogAsciiSymbol(identifier_pos, scanner_->literal_ascii_string());
-  } else {
-    log_->LogUC16Symbol(identifier_pos, scanner_->literal_uc16_string());
-  }
+  LogSymbol();
   return kUnknownExpression;
 }
 
diff --git a/src/preparser.h b/src/preparser.h
index 893b575..536e6d4 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -216,8 +216,11 @@
   Identifier ParseIdentifierName(bool* ok);
   Identifier ParseIdentifierOrGetOrSet(bool* is_get, bool* is_set, bool* ok);
 
+  // Logs the currently parsed literal as a symbol in the preparser data.
+  void LogSymbol();
+  // Log the currently parsed identifier.
   Identifier GetIdentifierSymbol();
-  unsigned int HexDigitValue(char digit);
+  // Log the currently parsed string literal.
   Expression GetStringSymbol();
 
   i::Token::Value peek() {
diff --git a/src/scanner-base.h b/src/scanner-base.h
index e773586..b668df5 100644
--- a/src/scanner-base.h
+++ b/src/scanner-base.h
@@ -214,7 +214,9 @@
     ASSERT(is_ascii_);
     Vector<byte> new_store;
     int new_content_size = position_ * kUC16Size;
-    if (new_content_size > backing_store_.length()) {
+    if (new_content_size >= backing_store_.length()) {
+      // Ensure room for all currently read characters as UC16 as well
+      // as the character about to be stored.
       new_store = Vector<byte>::New(NewCapacity(new_content_size));
     } else {
       new_store = backing_store_;
diff --git a/src/scanner.cc b/src/scanner.cc
index 38d0b1c..7fd6ef2 100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -457,7 +457,7 @@
   ASSERT_EQ('"', c0_);
   Advance();
   LiteralScope literal(this);
-  while (c0_ != '"' && c0_ > 0) {
+  while (c0_ != '"') {
     // Check for control character (0x00-0x1f) or unterminated string (<0).
     if (c0_ < 0x20) return Token::ILLEGAL;
     if (c0_ != '\\') {
@@ -504,9 +504,6 @@
       Advance();
     }
   }
-  if (c0_ != '"') {
-    return Token::ILLEGAL;
-  }
   literal.Complete();
   Advance();
   return Token::STRING;
diff --git a/src/top.cc b/src/top.cc
index 3d86d11..98c673c 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -170,7 +170,9 @@
 // into for use by a stacks only core dump (aka minidump).
 class PreallocatedMemoryThread: public Thread {
  public:
-  PreallocatedMemoryThread() : keep_running_(true) {
+  PreallocatedMemoryThread()
+    : Thread("v8:PreallocMem"),
+      keep_running_(true) {
     wait_for_ever_semaphore_ = OS::CreateSemaphore(0);
     data_ready_semaphore_ = OS::CreateSemaphore(0);
   }
diff --git a/src/unicode.cc b/src/unicode.cc
index 35a66c6..346f673 100644
--- a/src/unicode.cc
+++ b/src/unicode.cc
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-// This file was generated at 2010-07-30 14:07:24.988557
+// This file was generated at 2011-01-03 10:57:02.088925
 
 #include "unicode-inl.h"
 #include <stdlib.h>
@@ -35,6 +35,7 @@
 
 static const int kStartBit = (1 << 30);
 static const int kChunkBits = (1 << 13);
+static const uchar kSentinel = static_cast<uchar>(-1);
 
 /**
  * \file
@@ -96,12 +97,12 @@
   int32_t field = TableGet<kEntryDist>(table, low);
   uchar entry = GetEntry(field);
   bool is_start = IsStart(field);
-  return (entry == value) ||
-          (entry < value && is_start);
+  return (entry == value) || (entry < value && is_start);
 }
 
 template <int kW>
 struct MultiCharacterSpecialCase {
+  static const uchar kEndOfEncoding = kSentinel;
   uchar chars[kW];
 };
 
@@ -172,7 +173,7 @@
       int length = 0;
       for (length = 0; length < kW; length++) {
         uchar mapped = mapping.chars[length];
-        if (mapped == static_cast<uchar>(-1)) break;
+        if (mapped == MultiCharacterSpecialCase<kW>::kEndOfEncoding) break;
         if (ranges_are_linear) {
           result[length] = mapped + (key - entry);
         } else {
@@ -225,13 +226,13 @@
       *cursor += 1;
       return kBadChar;
     }
-    uchar l = ((first << 6) | second) & kMaxTwoByteChar;
-    if (l <= kMaxOneByteChar) {
+    uchar code_point = ((first << 6) | second) & kMaxTwoByteChar;
+    if (code_point <= kMaxOneByteChar) {
       *cursor += 1;
       return kBadChar;
     }
     *cursor += 2;
-    return l;
+    return code_point;
   }
   if (length == 2) {
     *cursor += 1;
@@ -243,13 +244,14 @@
     return kBadChar;
   }
   if (first < 0xF0) {
-    uchar l = ((((first << 6) | second) << 6) | third) & kMaxThreeByteChar;
-    if (l <= kMaxTwoByteChar) {
+    uchar code_point = ((((first << 6) | second) << 6) | third)
+        & kMaxThreeByteChar;
+    if (code_point <= kMaxTwoByteChar) {
       *cursor += 1;
       return kBadChar;
     }
     *cursor += 3;
-    return l;
+    return code_point;
   }
   if (length == 3) {
     *cursor += 1;
@@ -261,14 +263,14 @@
     return kBadChar;
   }
   if (first < 0xF8) {
-    uchar l = (((((first << 6 | second) << 6) | third) << 6) | fourth) &
-              kMaxFourByteChar;
-    if (l <= kMaxThreeByteChar) {
+    uchar code_point = (((((first << 6 | second) << 6) | third) << 6) | fourth)
+        & kMaxFourByteChar;
+    if (code_point <= kMaxThreeByteChar) {
       *cursor += 1;
       return kBadChar;
     }
     *cursor += 4;
-    return l;
+    return code_point;
   }
   *cursor += 1;
   return kBadChar;
@@ -823,7 +825,7 @@
 }
 
 static const MultiCharacterSpecialCase<2> kToLowercaseMultiStrings0[2] = {  // NOLINT
-  {{105, 775}}, {{-1}} }; // NOLINT
+  {{105, 775}}, {{kSentinel}} }; // NOLINT
 static const uint16_t kToLowercaseTable0Size = 463;  // NOLINT
 static const int32_t kToLowercaseTable0[926] = {
   1073741889, 128, 90, 128, 1073742016, 128, 214, 128, 1073742040, 128, 222, 128, 256, 4, 258, 4,  // NOLINT
@@ -886,7 +888,7 @@
   8171, -448, 8172, -28, 1073750008, -512, 8185, -512, 1073750010, -504, 8187, -504, 8188, -36 };  // NOLINT
 static const uint16_t kToLowercaseMultiStrings0Size = 2;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings1[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kToLowercaseTable1Size = 69;  // NOLINT
 static const int32_t kToLowercaseTable1[138] = {
   294, -30068, 298, -33532, 299, -33048, 306, 112, 1073742176, 64, 367, 64, 387, 4, 1073743030, 104,  // NOLINT
@@ -900,7 +902,7 @@
   3290, 4, 3292, 4, 3294, 4, 3296, 4, 3298, 4 };  // NOLINT
 static const uint16_t kToLowercaseMultiStrings1Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings7[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kToLowercaseTable7Size = 2;  // NOLINT
 static const int32_t kToLowercaseTable7[4] = {
   1073749793, 128, 7994, 128 };  // NOLINT
@@ -937,22 +939,22 @@
 }
 
 static const MultiCharacterSpecialCase<3> kToUppercaseMultiStrings0[62] = {  // NOLINT
-  {{83, 83, -1}}, {{700, 78, -1}}, {{74, 780, -1}}, {{921, 776, 769}},  // NOLINT
-  {{933, 776, 769}}, {{1333, 1362, -1}}, {{72, 817, -1}}, {{84, 776, -1}},  // NOLINT
-  {{87, 778, -1}}, {{89, 778, -1}}, {{65, 702, -1}}, {{933, 787, -1}},  // NOLINT
-  {{933, 787, 768}}, {{933, 787, 769}}, {{933, 787, 834}}, {{7944, 921, -1}},  // NOLINT
-  {{7945, 921, -1}}, {{7946, 921, -1}}, {{7947, 921, -1}}, {{7948, 921, -1}},  // NOLINT
-  {{7949, 921, -1}}, {{7950, 921, -1}}, {{7951, 921, -1}}, {{7976, 921, -1}},  // NOLINT
-  {{7977, 921, -1}}, {{7978, 921, -1}}, {{7979, 921, -1}}, {{7980, 921, -1}},  // NOLINT
-  {{7981, 921, -1}}, {{7982, 921, -1}}, {{7983, 921, -1}}, {{8040, 921, -1}},  // NOLINT
-  {{8041, 921, -1}}, {{8042, 921, -1}}, {{8043, 921, -1}}, {{8044, 921, -1}},  // NOLINT
-  {{8045, 921, -1}}, {{8046, 921, -1}}, {{8047, 921, -1}}, {{8122, 921, -1}},  // NOLINT
-  {{913, 921, -1}}, {{902, 921, -1}}, {{913, 834, -1}}, {{913, 834, 921}},  // NOLINT
-  {{8138, 921, -1}}, {{919, 921, -1}}, {{905, 921, -1}}, {{919, 834, -1}},  // NOLINT
-  {{919, 834, 921}}, {{921, 776, 768}}, {{921, 834, -1}}, {{921, 776, 834}},  // NOLINT
-  {{933, 776, 768}}, {{929, 787, -1}}, {{933, 834, -1}}, {{933, 776, 834}},  // NOLINT
-  {{8186, 921, -1}}, {{937, 921, -1}}, {{911, 921, -1}}, {{937, 834, -1}},  // NOLINT
-  {{937, 834, 921}}, {{-1}} }; // NOLINT
+  {{83, 83, kSentinel}}, {{700, 78, kSentinel}}, {{74, 780, kSentinel}}, {{921, 776, 769}},  // NOLINT
+  {{933, 776, 769}}, {{1333, 1362, kSentinel}}, {{72, 817, kSentinel}}, {{84, 776, kSentinel}},  // NOLINT
+  {{87, 778, kSentinel}}, {{89, 778, kSentinel}}, {{65, 702, kSentinel}}, {{933, 787, kSentinel}},  // NOLINT
+  {{933, 787, 768}}, {{933, 787, 769}}, {{933, 787, 834}}, {{7944, 921, kSentinel}},  // NOLINT
+  {{7945, 921, kSentinel}}, {{7946, 921, kSentinel}}, {{7947, 921, kSentinel}}, {{7948, 921, kSentinel}},  // NOLINT
+  {{7949, 921, kSentinel}}, {{7950, 921, kSentinel}}, {{7951, 921, kSentinel}}, {{7976, 921, kSentinel}},  // NOLINT
+  {{7977, 921, kSentinel}}, {{7978, 921, kSentinel}}, {{7979, 921, kSentinel}}, {{7980, 921, kSentinel}},  // NOLINT
+  {{7981, 921, kSentinel}}, {{7982, 921, kSentinel}}, {{7983, 921, kSentinel}}, {{8040, 921, kSentinel}},  // NOLINT
+  {{8041, 921, kSentinel}}, {{8042, 921, kSentinel}}, {{8043, 921, kSentinel}}, {{8044, 921, kSentinel}},  // NOLINT
+  {{8045, 921, kSentinel}}, {{8046, 921, kSentinel}}, {{8047, 921, kSentinel}}, {{8122, 921, kSentinel}},  // NOLINT
+  {{913, 921, kSentinel}}, {{902, 921, kSentinel}}, {{913, 834, kSentinel}}, {{913, 834, 921}},  // NOLINT
+  {{8138, 921, kSentinel}}, {{919, 921, kSentinel}}, {{905, 921, kSentinel}}, {{919, 834, kSentinel}},  // NOLINT
+  {{919, 834, 921}}, {{921, 776, 768}}, {{921, 834, kSentinel}}, {{921, 776, 834}},  // NOLINT
+  {{933, 776, 768}}, {{929, 787, kSentinel}}, {{933, 834, kSentinel}}, {{933, 776, 834}},  // NOLINT
+  {{8186, 921, kSentinel}}, {{937, 921, kSentinel}}, {{911, 921, kSentinel}}, {{937, 834, kSentinel}},  // NOLINT
+  {{937, 834, 921}}, {{kSentinel}} }; // NOLINT
 static const uint16_t kToUppercaseTable0Size = 554;  // NOLINT
 static const int32_t kToUppercaseTable0[1108] = {
   1073741921, -128, 122, -128, 181, 2972, 223, 1, 1073742048, -128, 246, -128, 1073742072, -128, 254, -128,  // NOLINT
@@ -1027,7 +1029,7 @@
   8183, 241, 8188, 229 };  // NOLINT
 static const uint16_t kToUppercaseMultiStrings0Size = 62;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToUppercaseMultiStrings1[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kToUppercaseTable1Size = 67;  // NOLINT
 static const int32_t kToUppercaseTable1[134] = {
   334, -112, 1073742192, -64, 383, -64, 388, -4, 1073743056, -104, 1257, -104, 1073744944, -192, 3166, -192,  // NOLINT
@@ -1041,9 +1043,9 @@
   3299, -4, 1073745152, -29056, 3365, -29056 };  // NOLINT
 static const uint16_t kToUppercaseMultiStrings1Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<3> kToUppercaseMultiStrings7[12] = {  // NOLINT
-  {{70, 70, -1}}, {{70, 73, -1}}, {{70, 76, -1}}, {{70, 70, 73}},  // NOLINT
-  {{70, 70, 76}}, {{83, 84, -1}}, {{1348, 1350, -1}}, {{1348, 1333, -1}},  // NOLINT
-  {{1348, 1339, -1}}, {{1358, 1350, -1}}, {{1348, 1341, -1}}, {{-1}} }; // NOLINT
+  {{70, 70, kSentinel}}, {{70, 73, kSentinel}}, {{70, 76, kSentinel}}, {{70, 70, 73}},  // NOLINT
+  {{70, 70, 76}}, {{83, 84, kSentinel}}, {{1348, 1350, kSentinel}}, {{1348, 1333, kSentinel}},  // NOLINT
+  {{1348, 1339, kSentinel}}, {{1358, 1350, kSentinel}}, {{1348, 1341, kSentinel}}, {{kSentinel}} }; // NOLINT
 static const uint16_t kToUppercaseTable7Size = 14;  // NOLINT
 static const int32_t kToUppercaseTable7[28] = {
   6912, 1, 6913, 5, 6914, 9, 6915, 13, 6916, 17, 6917, 21, 6918, 21, 6931, 25,  // NOLINT
@@ -1081,7 +1083,7 @@
 }
 
 static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings0[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kEcma262CanonicalizeTable0Size = 462;  // NOLINT
 static const int32_t kEcma262CanonicalizeTable0[924] = {
   1073741921, -128, 122, -128, 181, 2972, 1073742048, -128, 246, -128, 1073742072, -128, 254, -128, 255, 484,  // NOLINT
@@ -1144,7 +1146,7 @@
   8126, -28820, 1073749968, 32, 8145, 32, 1073749984, 32, 8161, 32, 8165, 28 };  // NOLINT
 static const uint16_t kEcma262CanonicalizeMultiStrings0Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings1[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kEcma262CanonicalizeTable1Size = 67;  // NOLINT
 static const int32_t kEcma262CanonicalizeTable1[134] = {
   334, -112, 1073742192, -64, 383, -64, 388, -4, 1073743056, -104, 1257, -104, 1073744944, -192, 3166, -192,  // NOLINT
@@ -1158,7 +1160,7 @@
   3299, -4, 1073745152, -29056, 3365, -29056 };  // NOLINT
 static const uint16_t kEcma262CanonicalizeMultiStrings1Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings7[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kEcma262CanonicalizeTable7Size = 2;  // NOLINT
 static const int32_t kEcma262CanonicalizeTable7[4] = {
   1073749825, -128, 8026, -128 };  // NOLINT
@@ -1195,124 +1197,124 @@
 }
 
 static const MultiCharacterSpecialCase<4> kEcma262UnCanonicalizeMultiStrings0[469] = {  // NOLINT
-  {{65, 97, -1}}, {{90, 122, -1}}, {{181, 924, 956, -1}}, {{192, 224, -1}},  // NOLINT
-  {{214, 246, -1}}, {{216, 248, -1}}, {{222, 254, -1}}, {{255, 376, -1}},  // NOLINT
-  {{256, 257, -1}}, {{258, 259, -1}}, {{260, 261, -1}}, {{262, 263, -1}},  // NOLINT
-  {{264, 265, -1}}, {{266, 267, -1}}, {{268, 269, -1}}, {{270, 271, -1}},  // NOLINT
-  {{272, 273, -1}}, {{274, 275, -1}}, {{276, 277, -1}}, {{278, 279, -1}},  // NOLINT
-  {{280, 281, -1}}, {{282, 283, -1}}, {{284, 285, -1}}, {{286, 287, -1}},  // NOLINT
-  {{288, 289, -1}}, {{290, 291, -1}}, {{292, 293, -1}}, {{294, 295, -1}},  // NOLINT
-  {{296, 297, -1}}, {{298, 299, -1}}, {{300, 301, -1}}, {{302, 303, -1}},  // NOLINT
-  {{306, 307, -1}}, {{308, 309, -1}}, {{310, 311, -1}}, {{313, 314, -1}},  // NOLINT
-  {{315, 316, -1}}, {{317, 318, -1}}, {{319, 320, -1}}, {{321, 322, -1}},  // NOLINT
-  {{323, 324, -1}}, {{325, 326, -1}}, {{327, 328, -1}}, {{330, 331, -1}},  // NOLINT
-  {{332, 333, -1}}, {{334, 335, -1}}, {{336, 337, -1}}, {{338, 339, -1}},  // NOLINT
-  {{340, 341, -1}}, {{342, 343, -1}}, {{344, 345, -1}}, {{346, 347, -1}},  // NOLINT
-  {{348, 349, -1}}, {{350, 351, -1}}, {{352, 353, -1}}, {{354, 355, -1}},  // NOLINT
-  {{356, 357, -1}}, {{358, 359, -1}}, {{360, 361, -1}}, {{362, 363, -1}},  // NOLINT
-  {{364, 365, -1}}, {{366, 367, -1}}, {{368, 369, -1}}, {{370, 371, -1}},  // NOLINT
-  {{372, 373, -1}}, {{374, 375, -1}}, {{377, 378, -1}}, {{379, 380, -1}},  // NOLINT
-  {{381, 382, -1}}, {{384, 579, -1}}, {{385, 595, -1}}, {{386, 387, -1}},  // NOLINT
-  {{388, 389, -1}}, {{390, 596, -1}}, {{391, 392, -1}}, {{393, 598, -1}},  // NOLINT
-  {{394, 599, -1}}, {{395, 396, -1}}, {{398, 477, -1}}, {{399, 601, -1}},  // NOLINT
-  {{400, 603, -1}}, {{401, 402, -1}}, {{403, 608, -1}}, {{404, 611, -1}},  // NOLINT
-  {{405, 502, -1}}, {{406, 617, -1}}, {{407, 616, -1}}, {{408, 409, -1}},  // NOLINT
-  {{410, 573, -1}}, {{412, 623, -1}}, {{413, 626, -1}}, {{414, 544, -1}},  // NOLINT
-  {{415, 629, -1}}, {{416, 417, -1}}, {{418, 419, -1}}, {{420, 421, -1}},  // NOLINT
-  {{422, 640, -1}}, {{423, 424, -1}}, {{425, 643, -1}}, {{428, 429, -1}},  // NOLINT
-  {{430, 648, -1}}, {{431, 432, -1}}, {{433, 650, -1}}, {{434, 651, -1}},  // NOLINT
-  {{435, 436, -1}}, {{437, 438, -1}}, {{439, 658, -1}}, {{440, 441, -1}},  // NOLINT
-  {{444, 445, -1}}, {{447, 503, -1}}, {{452, 453, 454, -1}}, {{455, 456, 457, -1}},  // NOLINT
-  {{458, 459, 460, -1}}, {{461, 462, -1}}, {{463, 464, -1}}, {{465, 466, -1}},  // NOLINT
-  {{467, 468, -1}}, {{469, 470, -1}}, {{471, 472, -1}}, {{473, 474, -1}},  // NOLINT
-  {{475, 476, -1}}, {{478, 479, -1}}, {{480, 481, -1}}, {{482, 483, -1}},  // NOLINT
-  {{484, 485, -1}}, {{486, 487, -1}}, {{488, 489, -1}}, {{490, 491, -1}},  // NOLINT
-  {{492, 493, -1}}, {{494, 495, -1}}, {{497, 498, 499, -1}}, {{500, 501, -1}},  // NOLINT
-  {{504, 505, -1}}, {{506, 507, -1}}, {{508, 509, -1}}, {{510, 511, -1}},  // NOLINT
-  {{512, 513, -1}}, {{514, 515, -1}}, {{516, 517, -1}}, {{518, 519, -1}},  // NOLINT
-  {{520, 521, -1}}, {{522, 523, -1}}, {{524, 525, -1}}, {{526, 527, -1}},  // NOLINT
-  {{528, 529, -1}}, {{530, 531, -1}}, {{532, 533, -1}}, {{534, 535, -1}},  // NOLINT
-  {{536, 537, -1}}, {{538, 539, -1}}, {{540, 541, -1}}, {{542, 543, -1}},  // NOLINT
-  {{546, 547, -1}}, {{548, 549, -1}}, {{550, 551, -1}}, {{552, 553, -1}},  // NOLINT
-  {{554, 555, -1}}, {{556, 557, -1}}, {{558, 559, -1}}, {{560, 561, -1}},  // NOLINT
-  {{562, 563, -1}}, {{570, 11365, -1}}, {{571, 572, -1}}, {{574, 11366, -1}},  // NOLINT
-  {{577, 578, -1}}, {{580, 649, -1}}, {{581, 652, -1}}, {{582, 583, -1}},  // NOLINT
-  {{584, 585, -1}}, {{586, 587, -1}}, {{588, 589, -1}}, {{590, 591, -1}},  // NOLINT
-  {{619, 11362, -1}}, {{637, 11364, -1}}, {{837, 921, 953, 8126}}, {{891, 1021, -1}},  // NOLINT
-  {{893, 1023, -1}}, {{902, 940, -1}}, {{904, 941, -1}}, {{906, 943, -1}},  // NOLINT
-  {{908, 972, -1}}, {{910, 973, -1}}, {{911, 974, -1}}, {{913, 945, -1}},  // NOLINT
-  {{914, 946, 976, -1}}, {{915, 947, -1}}, {{916, 948, -1}}, {{917, 949, 1013, -1}},  // NOLINT
-  {{918, 950, -1}}, {{919, 951, -1}}, {{920, 952, 977, -1}}, {{922, 954, 1008, -1}},  // NOLINT
-  {{923, 955, -1}}, {{925, 957, -1}}, {{927, 959, -1}}, {{928, 960, 982, -1}},  // NOLINT
-  {{929, 961, 1009, -1}}, {{931, 962, 963, -1}}, {{932, 964, -1}}, {{933, 965, -1}},  // NOLINT
-  {{934, 966, 981, -1}}, {{935, 967, -1}}, {{939, 971, -1}}, {{984, 985, -1}},  // NOLINT
-  {{986, 987, -1}}, {{988, 989, -1}}, {{990, 991, -1}}, {{992, 993, -1}},  // NOLINT
-  {{994, 995, -1}}, {{996, 997, -1}}, {{998, 999, -1}}, {{1000, 1001, -1}},  // NOLINT
-  {{1002, 1003, -1}}, {{1004, 1005, -1}}, {{1006, 1007, -1}}, {{1010, 1017, -1}},  // NOLINT
-  {{1015, 1016, -1}}, {{1018, 1019, -1}}, {{1024, 1104, -1}}, {{1039, 1119, -1}},  // NOLINT
-  {{1040, 1072, -1}}, {{1071, 1103, -1}}, {{1120, 1121, -1}}, {{1122, 1123, -1}},  // NOLINT
-  {{1124, 1125, -1}}, {{1126, 1127, -1}}, {{1128, 1129, -1}}, {{1130, 1131, -1}},  // NOLINT
-  {{1132, 1133, -1}}, {{1134, 1135, -1}}, {{1136, 1137, -1}}, {{1138, 1139, -1}},  // NOLINT
-  {{1140, 1141, -1}}, {{1142, 1143, -1}}, {{1144, 1145, -1}}, {{1146, 1147, -1}},  // NOLINT
-  {{1148, 1149, -1}}, {{1150, 1151, -1}}, {{1152, 1153, -1}}, {{1162, 1163, -1}},  // NOLINT
-  {{1164, 1165, -1}}, {{1166, 1167, -1}}, {{1168, 1169, -1}}, {{1170, 1171, -1}},  // NOLINT
-  {{1172, 1173, -1}}, {{1174, 1175, -1}}, {{1176, 1177, -1}}, {{1178, 1179, -1}},  // NOLINT
-  {{1180, 1181, -1}}, {{1182, 1183, -1}}, {{1184, 1185, -1}}, {{1186, 1187, -1}},  // NOLINT
-  {{1188, 1189, -1}}, {{1190, 1191, -1}}, {{1192, 1193, -1}}, {{1194, 1195, -1}},  // NOLINT
-  {{1196, 1197, -1}}, {{1198, 1199, -1}}, {{1200, 1201, -1}}, {{1202, 1203, -1}},  // NOLINT
-  {{1204, 1205, -1}}, {{1206, 1207, -1}}, {{1208, 1209, -1}}, {{1210, 1211, -1}},  // NOLINT
-  {{1212, 1213, -1}}, {{1214, 1215, -1}}, {{1216, 1231, -1}}, {{1217, 1218, -1}},  // NOLINT
-  {{1219, 1220, -1}}, {{1221, 1222, -1}}, {{1223, 1224, -1}}, {{1225, 1226, -1}},  // NOLINT
-  {{1227, 1228, -1}}, {{1229, 1230, -1}}, {{1232, 1233, -1}}, {{1234, 1235, -1}},  // NOLINT
-  {{1236, 1237, -1}}, {{1238, 1239, -1}}, {{1240, 1241, -1}}, {{1242, 1243, -1}},  // NOLINT
-  {{1244, 1245, -1}}, {{1246, 1247, -1}}, {{1248, 1249, -1}}, {{1250, 1251, -1}},  // NOLINT
-  {{1252, 1253, -1}}, {{1254, 1255, -1}}, {{1256, 1257, -1}}, {{1258, 1259, -1}},  // NOLINT
-  {{1260, 1261, -1}}, {{1262, 1263, -1}}, {{1264, 1265, -1}}, {{1266, 1267, -1}},  // NOLINT
-  {{1268, 1269, -1}}, {{1270, 1271, -1}}, {{1272, 1273, -1}}, {{1274, 1275, -1}},  // NOLINT
-  {{1276, 1277, -1}}, {{1278, 1279, -1}}, {{1280, 1281, -1}}, {{1282, 1283, -1}},  // NOLINT
-  {{1284, 1285, -1}}, {{1286, 1287, -1}}, {{1288, 1289, -1}}, {{1290, 1291, -1}},  // NOLINT
-  {{1292, 1293, -1}}, {{1294, 1295, -1}}, {{1296, 1297, -1}}, {{1298, 1299, -1}},  // NOLINT
-  {{1329, 1377, -1}}, {{1366, 1414, -1}}, {{4256, 11520, -1}}, {{4293, 11557, -1}},  // NOLINT
-  {{7549, 11363, -1}}, {{7680, 7681, -1}}, {{7682, 7683, -1}}, {{7684, 7685, -1}},  // NOLINT
-  {{7686, 7687, -1}}, {{7688, 7689, -1}}, {{7690, 7691, -1}}, {{7692, 7693, -1}},  // NOLINT
-  {{7694, 7695, -1}}, {{7696, 7697, -1}}, {{7698, 7699, -1}}, {{7700, 7701, -1}},  // NOLINT
-  {{7702, 7703, -1}}, {{7704, 7705, -1}}, {{7706, 7707, -1}}, {{7708, 7709, -1}},  // NOLINT
-  {{7710, 7711, -1}}, {{7712, 7713, -1}}, {{7714, 7715, -1}}, {{7716, 7717, -1}},  // NOLINT
-  {{7718, 7719, -1}}, {{7720, 7721, -1}}, {{7722, 7723, -1}}, {{7724, 7725, -1}},  // NOLINT
-  {{7726, 7727, -1}}, {{7728, 7729, -1}}, {{7730, 7731, -1}}, {{7732, 7733, -1}},  // NOLINT
-  {{7734, 7735, -1}}, {{7736, 7737, -1}}, {{7738, 7739, -1}}, {{7740, 7741, -1}},  // NOLINT
-  {{7742, 7743, -1}}, {{7744, 7745, -1}}, {{7746, 7747, -1}}, {{7748, 7749, -1}},  // NOLINT
-  {{7750, 7751, -1}}, {{7752, 7753, -1}}, {{7754, 7755, -1}}, {{7756, 7757, -1}},  // NOLINT
-  {{7758, 7759, -1}}, {{7760, 7761, -1}}, {{7762, 7763, -1}}, {{7764, 7765, -1}},  // NOLINT
-  {{7766, 7767, -1}}, {{7768, 7769, -1}}, {{7770, 7771, -1}}, {{7772, 7773, -1}},  // NOLINT
-  {{7774, 7775, -1}}, {{7776, 7777, 7835, -1}}, {{7778, 7779, -1}}, {{7780, 7781, -1}},  // NOLINT
-  {{7782, 7783, -1}}, {{7784, 7785, -1}}, {{7786, 7787, -1}}, {{7788, 7789, -1}},  // NOLINT
-  {{7790, 7791, -1}}, {{7792, 7793, -1}}, {{7794, 7795, -1}}, {{7796, 7797, -1}},  // NOLINT
-  {{7798, 7799, -1}}, {{7800, 7801, -1}}, {{7802, 7803, -1}}, {{7804, 7805, -1}},  // NOLINT
-  {{7806, 7807, -1}}, {{7808, 7809, -1}}, {{7810, 7811, -1}}, {{7812, 7813, -1}},  // NOLINT
-  {{7814, 7815, -1}}, {{7816, 7817, -1}}, {{7818, 7819, -1}}, {{7820, 7821, -1}},  // NOLINT
-  {{7822, 7823, -1}}, {{7824, 7825, -1}}, {{7826, 7827, -1}}, {{7828, 7829, -1}},  // NOLINT
-  {{7840, 7841, -1}}, {{7842, 7843, -1}}, {{7844, 7845, -1}}, {{7846, 7847, -1}},  // NOLINT
-  {{7848, 7849, -1}}, {{7850, 7851, -1}}, {{7852, 7853, -1}}, {{7854, 7855, -1}},  // NOLINT
-  {{7856, 7857, -1}}, {{7858, 7859, -1}}, {{7860, 7861, -1}}, {{7862, 7863, -1}},  // NOLINT
-  {{7864, 7865, -1}}, {{7866, 7867, -1}}, {{7868, 7869, -1}}, {{7870, 7871, -1}},  // NOLINT
-  {{7872, 7873, -1}}, {{7874, 7875, -1}}, {{7876, 7877, -1}}, {{7878, 7879, -1}},  // NOLINT
-  {{7880, 7881, -1}}, {{7882, 7883, -1}}, {{7884, 7885, -1}}, {{7886, 7887, -1}},  // NOLINT
-  {{7888, 7889, -1}}, {{7890, 7891, -1}}, {{7892, 7893, -1}}, {{7894, 7895, -1}},  // NOLINT
-  {{7896, 7897, -1}}, {{7898, 7899, -1}}, {{7900, 7901, -1}}, {{7902, 7903, -1}},  // NOLINT
-  {{7904, 7905, -1}}, {{7906, 7907, -1}}, {{7908, 7909, -1}}, {{7910, 7911, -1}},  // NOLINT
-  {{7912, 7913, -1}}, {{7914, 7915, -1}}, {{7916, 7917, -1}}, {{7918, 7919, -1}},  // NOLINT
-  {{7920, 7921, -1}}, {{7922, 7923, -1}}, {{7924, 7925, -1}}, {{7926, 7927, -1}},  // NOLINT
-  {{7928, 7929, -1}}, {{7936, 7944, -1}}, {{7943, 7951, -1}}, {{7952, 7960, -1}},  // NOLINT
-  {{7957, 7965, -1}}, {{7968, 7976, -1}}, {{7975, 7983, -1}}, {{7984, 7992, -1}},  // NOLINT
-  {{7991, 7999, -1}}, {{8000, 8008, -1}}, {{8005, 8013, -1}}, {{8017, 8025, -1}},  // NOLINT
-  {{8019, 8027, -1}}, {{8021, 8029, -1}}, {{8023, 8031, -1}}, {{8032, 8040, -1}},  // NOLINT
-  {{8039, 8047, -1}}, {{8048, 8122, -1}}, {{8049, 8123, -1}}, {{8050, 8136, -1}},  // NOLINT
-  {{8053, 8139, -1}}, {{8054, 8154, -1}}, {{8055, 8155, -1}}, {{8056, 8184, -1}},  // NOLINT
-  {{8057, 8185, -1}}, {{8058, 8170, -1}}, {{8059, 8171, -1}}, {{8060, 8186, -1}},  // NOLINT
-  {{8061, 8187, -1}}, {{8112, 8120, -1}}, {{8113, 8121, -1}}, {{8144, 8152, -1}},  // NOLINT
-  {{8145, 8153, -1}}, {{8160, 8168, -1}}, {{8161, 8169, -1}}, {{8165, 8172, -1}},  // NOLINT
-  {{-1}} }; // NOLINT
+  {{65, 97, kSentinel}}, {{90, 122, kSentinel}}, {{181, 924, 956, kSentinel}}, {{192, 224, kSentinel}},  // NOLINT
+  {{214, 246, kSentinel}}, {{216, 248, kSentinel}}, {{222, 254, kSentinel}}, {{255, 376, kSentinel}},  // NOLINT
+  {{256, 257, kSentinel}}, {{258, 259, kSentinel}}, {{260, 261, kSentinel}}, {{262, 263, kSentinel}},  // NOLINT
+  {{264, 265, kSentinel}}, {{266, 267, kSentinel}}, {{268, 269, kSentinel}}, {{270, 271, kSentinel}},  // NOLINT
+  {{272, 273, kSentinel}}, {{274, 275, kSentinel}}, {{276, 277, kSentinel}}, {{278, 279, kSentinel}},  // NOLINT
+  {{280, 281, kSentinel}}, {{282, 283, kSentinel}}, {{284, 285, kSentinel}}, {{286, 287, kSentinel}},  // NOLINT
+  {{288, 289, kSentinel}}, {{290, 291, kSentinel}}, {{292, 293, kSentinel}}, {{294, 295, kSentinel}},  // NOLINT
+  {{296, 297, kSentinel}}, {{298, 299, kSentinel}}, {{300, 301, kSentinel}}, {{302, 303, kSentinel}},  // NOLINT
+  {{306, 307, kSentinel}}, {{308, 309, kSentinel}}, {{310, 311, kSentinel}}, {{313, 314, kSentinel}},  // NOLINT
+  {{315, 316, kSentinel}}, {{317, 318, kSentinel}}, {{319, 320, kSentinel}}, {{321, 322, kSentinel}},  // NOLINT
+  {{323, 324, kSentinel}}, {{325, 326, kSentinel}}, {{327, 328, kSentinel}}, {{330, 331, kSentinel}},  // NOLINT
+  {{332, 333, kSentinel}}, {{334, 335, kSentinel}}, {{336, 337, kSentinel}}, {{338, 339, kSentinel}},  // NOLINT
+  {{340, 341, kSentinel}}, {{342, 343, kSentinel}}, {{344, 345, kSentinel}}, {{346, 347, kSentinel}},  // NOLINT
+  {{348, 349, kSentinel}}, {{350, 351, kSentinel}}, {{352, 353, kSentinel}}, {{354, 355, kSentinel}},  // NOLINT
+  {{356, 357, kSentinel}}, {{358, 359, kSentinel}}, {{360, 361, kSentinel}}, {{362, 363, kSentinel}},  // NOLINT
+  {{364, 365, kSentinel}}, {{366, 367, kSentinel}}, {{368, 369, kSentinel}}, {{370, 371, kSentinel}},  // NOLINT
+  {{372, 373, kSentinel}}, {{374, 375, kSentinel}}, {{377, 378, kSentinel}}, {{379, 380, kSentinel}},  // NOLINT
+  {{381, 382, kSentinel}}, {{384, 579, kSentinel}}, {{385, 595, kSentinel}}, {{386, 387, kSentinel}},  // NOLINT
+  {{388, 389, kSentinel}}, {{390, 596, kSentinel}}, {{391, 392, kSentinel}}, {{393, 598, kSentinel}},  // NOLINT
+  {{394, 599, kSentinel}}, {{395, 396, kSentinel}}, {{398, 477, kSentinel}}, {{399, 601, kSentinel}},  // NOLINT
+  {{400, 603, kSentinel}}, {{401, 402, kSentinel}}, {{403, 608, kSentinel}}, {{404, 611, kSentinel}},  // NOLINT
+  {{405, 502, kSentinel}}, {{406, 617, kSentinel}}, {{407, 616, kSentinel}}, {{408, 409, kSentinel}},  // NOLINT
+  {{410, 573, kSentinel}}, {{412, 623, kSentinel}}, {{413, 626, kSentinel}}, {{414, 544, kSentinel}},  // NOLINT
+  {{415, 629, kSentinel}}, {{416, 417, kSentinel}}, {{418, 419, kSentinel}}, {{420, 421, kSentinel}},  // NOLINT
+  {{422, 640, kSentinel}}, {{423, 424, kSentinel}}, {{425, 643, kSentinel}}, {{428, 429, kSentinel}},  // NOLINT
+  {{430, 648, kSentinel}}, {{431, 432, kSentinel}}, {{433, 650, kSentinel}}, {{434, 651, kSentinel}},  // NOLINT
+  {{435, 436, kSentinel}}, {{437, 438, kSentinel}}, {{439, 658, kSentinel}}, {{440, 441, kSentinel}},  // NOLINT
+  {{444, 445, kSentinel}}, {{447, 503, kSentinel}}, {{452, 453, 454, kSentinel}}, {{455, 456, 457, kSentinel}},  // NOLINT
+  {{458, 459, 460, kSentinel}}, {{461, 462, kSentinel}}, {{463, 464, kSentinel}}, {{465, 466, kSentinel}},  // NOLINT
+  {{467, 468, kSentinel}}, {{469, 470, kSentinel}}, {{471, 472, kSentinel}}, {{473, 474, kSentinel}},  // NOLINT
+  {{475, 476, kSentinel}}, {{478, 479, kSentinel}}, {{480, 481, kSentinel}}, {{482, 483, kSentinel}},  // NOLINT
+  {{484, 485, kSentinel}}, {{486, 487, kSentinel}}, {{488, 489, kSentinel}}, {{490, 491, kSentinel}},  // NOLINT
+  {{492, 493, kSentinel}}, {{494, 495, kSentinel}}, {{497, 498, 499, kSentinel}}, {{500, 501, kSentinel}},  // NOLINT
+  {{504, 505, kSentinel}}, {{506, 507, kSentinel}}, {{508, 509, kSentinel}}, {{510, 511, kSentinel}},  // NOLINT
+  {{512, 513, kSentinel}}, {{514, 515, kSentinel}}, {{516, 517, kSentinel}}, {{518, 519, kSentinel}},  // NOLINT
+  {{520, 521, kSentinel}}, {{522, 523, kSentinel}}, {{524, 525, kSentinel}}, {{526, 527, kSentinel}},  // NOLINT
+  {{528, 529, kSentinel}}, {{530, 531, kSentinel}}, {{532, 533, kSentinel}}, {{534, 535, kSentinel}},  // NOLINT
+  {{536, 537, kSentinel}}, {{538, 539, kSentinel}}, {{540, 541, kSentinel}}, {{542, 543, kSentinel}},  // NOLINT
+  {{546, 547, kSentinel}}, {{548, 549, kSentinel}}, {{550, 551, kSentinel}}, {{552, 553, kSentinel}},  // NOLINT
+  {{554, 555, kSentinel}}, {{556, 557, kSentinel}}, {{558, 559, kSentinel}}, {{560, 561, kSentinel}},  // NOLINT
+  {{562, 563, kSentinel}}, {{570, 11365, kSentinel}}, {{571, 572, kSentinel}}, {{574, 11366, kSentinel}},  // NOLINT
+  {{577, 578, kSentinel}}, {{580, 649, kSentinel}}, {{581, 652, kSentinel}}, {{582, 583, kSentinel}},  // NOLINT
+  {{584, 585, kSentinel}}, {{586, 587, kSentinel}}, {{588, 589, kSentinel}}, {{590, 591, kSentinel}},  // NOLINT
+  {{619, 11362, kSentinel}}, {{637, 11364, kSentinel}}, {{837, 921, 953, 8126}}, {{891, 1021, kSentinel}},  // NOLINT
+  {{893, 1023, kSentinel}}, {{902, 940, kSentinel}}, {{904, 941, kSentinel}}, {{906, 943, kSentinel}},  // NOLINT
+  {{908, 972, kSentinel}}, {{910, 973, kSentinel}}, {{911, 974, kSentinel}}, {{913, 945, kSentinel}},  // NOLINT
+  {{914, 946, 976, kSentinel}}, {{915, 947, kSentinel}}, {{916, 948, kSentinel}}, {{917, 949, 1013, kSentinel}},  // NOLINT
+  {{918, 950, kSentinel}}, {{919, 951, kSentinel}}, {{920, 952, 977, kSentinel}}, {{922, 954, 1008, kSentinel}},  // NOLINT
+  {{923, 955, kSentinel}}, {{925, 957, kSentinel}}, {{927, 959, kSentinel}}, {{928, 960, 982, kSentinel}},  // NOLINT
+  {{929, 961, 1009, kSentinel}}, {{931, 962, 963, kSentinel}}, {{932, 964, kSentinel}}, {{933, 965, kSentinel}},  // NOLINT
+  {{934, 966, 981, kSentinel}}, {{935, 967, kSentinel}}, {{939, 971, kSentinel}}, {{984, 985, kSentinel}},  // NOLINT
+  {{986, 987, kSentinel}}, {{988, 989, kSentinel}}, {{990, 991, kSentinel}}, {{992, 993, kSentinel}},  // NOLINT
+  {{994, 995, kSentinel}}, {{996, 997, kSentinel}}, {{998, 999, kSentinel}}, {{1000, 1001, kSentinel}},  // NOLINT
+  {{1002, 1003, kSentinel}}, {{1004, 1005, kSentinel}}, {{1006, 1007, kSentinel}}, {{1010, 1017, kSentinel}},  // NOLINT
+  {{1015, 1016, kSentinel}}, {{1018, 1019, kSentinel}}, {{1024, 1104, kSentinel}}, {{1039, 1119, kSentinel}},  // NOLINT
+  {{1040, 1072, kSentinel}}, {{1071, 1103, kSentinel}}, {{1120, 1121, kSentinel}}, {{1122, 1123, kSentinel}},  // NOLINT
+  {{1124, 1125, kSentinel}}, {{1126, 1127, kSentinel}}, {{1128, 1129, kSentinel}}, {{1130, 1131, kSentinel}},  // NOLINT
+  {{1132, 1133, kSentinel}}, {{1134, 1135, kSentinel}}, {{1136, 1137, kSentinel}}, {{1138, 1139, kSentinel}},  // NOLINT
+  {{1140, 1141, kSentinel}}, {{1142, 1143, kSentinel}}, {{1144, 1145, kSentinel}}, {{1146, 1147, kSentinel}},  // NOLINT
+  {{1148, 1149, kSentinel}}, {{1150, 1151, kSentinel}}, {{1152, 1153, kSentinel}}, {{1162, 1163, kSentinel}},  // NOLINT
+  {{1164, 1165, kSentinel}}, {{1166, 1167, kSentinel}}, {{1168, 1169, kSentinel}}, {{1170, 1171, kSentinel}},  // NOLINT
+  {{1172, 1173, kSentinel}}, {{1174, 1175, kSentinel}}, {{1176, 1177, kSentinel}}, {{1178, 1179, kSentinel}},  // NOLINT
+  {{1180, 1181, kSentinel}}, {{1182, 1183, kSentinel}}, {{1184, 1185, kSentinel}}, {{1186, 1187, kSentinel}},  // NOLINT
+  {{1188, 1189, kSentinel}}, {{1190, 1191, kSentinel}}, {{1192, 1193, kSentinel}}, {{1194, 1195, kSentinel}},  // NOLINT
+  {{1196, 1197, kSentinel}}, {{1198, 1199, kSentinel}}, {{1200, 1201, kSentinel}}, {{1202, 1203, kSentinel}},  // NOLINT
+  {{1204, 1205, kSentinel}}, {{1206, 1207, kSentinel}}, {{1208, 1209, kSentinel}}, {{1210, 1211, kSentinel}},  // NOLINT
+  {{1212, 1213, kSentinel}}, {{1214, 1215, kSentinel}}, {{1216, 1231, kSentinel}}, {{1217, 1218, kSentinel}},  // NOLINT
+  {{1219, 1220, kSentinel}}, {{1221, 1222, kSentinel}}, {{1223, 1224, kSentinel}}, {{1225, 1226, kSentinel}},  // NOLINT
+  {{1227, 1228, kSentinel}}, {{1229, 1230, kSentinel}}, {{1232, 1233, kSentinel}}, {{1234, 1235, kSentinel}},  // NOLINT
+  {{1236, 1237, kSentinel}}, {{1238, 1239, kSentinel}}, {{1240, 1241, kSentinel}}, {{1242, 1243, kSentinel}},  // NOLINT
+  {{1244, 1245, kSentinel}}, {{1246, 1247, kSentinel}}, {{1248, 1249, kSentinel}}, {{1250, 1251, kSentinel}},  // NOLINT
+  {{1252, 1253, kSentinel}}, {{1254, 1255, kSentinel}}, {{1256, 1257, kSentinel}}, {{1258, 1259, kSentinel}},  // NOLINT
+  {{1260, 1261, kSentinel}}, {{1262, 1263, kSentinel}}, {{1264, 1265, kSentinel}}, {{1266, 1267, kSentinel}},  // NOLINT
+  {{1268, 1269, kSentinel}}, {{1270, 1271, kSentinel}}, {{1272, 1273, kSentinel}}, {{1274, 1275, kSentinel}},  // NOLINT
+  {{1276, 1277, kSentinel}}, {{1278, 1279, kSentinel}}, {{1280, 1281, kSentinel}}, {{1282, 1283, kSentinel}},  // NOLINT
+  {{1284, 1285, kSentinel}}, {{1286, 1287, kSentinel}}, {{1288, 1289, kSentinel}}, {{1290, 1291, kSentinel}},  // NOLINT
+  {{1292, 1293, kSentinel}}, {{1294, 1295, kSentinel}}, {{1296, 1297, kSentinel}}, {{1298, 1299, kSentinel}},  // NOLINT
+  {{1329, 1377, kSentinel}}, {{1366, 1414, kSentinel}}, {{4256, 11520, kSentinel}}, {{4293, 11557, kSentinel}},  // NOLINT
+  {{7549, 11363, kSentinel}}, {{7680, 7681, kSentinel}}, {{7682, 7683, kSentinel}}, {{7684, 7685, kSentinel}},  // NOLINT
+  {{7686, 7687, kSentinel}}, {{7688, 7689, kSentinel}}, {{7690, 7691, kSentinel}}, {{7692, 7693, kSentinel}},  // NOLINT
+  {{7694, 7695, kSentinel}}, {{7696, 7697, kSentinel}}, {{7698, 7699, kSentinel}}, {{7700, 7701, kSentinel}},  // NOLINT
+  {{7702, 7703, kSentinel}}, {{7704, 7705, kSentinel}}, {{7706, 7707, kSentinel}}, {{7708, 7709, kSentinel}},  // NOLINT
+  {{7710, 7711, kSentinel}}, {{7712, 7713, kSentinel}}, {{7714, 7715, kSentinel}}, {{7716, 7717, kSentinel}},  // NOLINT
+  {{7718, 7719, kSentinel}}, {{7720, 7721, kSentinel}}, {{7722, 7723, kSentinel}}, {{7724, 7725, kSentinel}},  // NOLINT
+  {{7726, 7727, kSentinel}}, {{7728, 7729, kSentinel}}, {{7730, 7731, kSentinel}}, {{7732, 7733, kSentinel}},  // NOLINT
+  {{7734, 7735, kSentinel}}, {{7736, 7737, kSentinel}}, {{7738, 7739, kSentinel}}, {{7740, 7741, kSentinel}},  // NOLINT
+  {{7742, 7743, kSentinel}}, {{7744, 7745, kSentinel}}, {{7746, 7747, kSentinel}}, {{7748, 7749, kSentinel}},  // NOLINT
+  {{7750, 7751, kSentinel}}, {{7752, 7753, kSentinel}}, {{7754, 7755, kSentinel}}, {{7756, 7757, kSentinel}},  // NOLINT
+  {{7758, 7759, kSentinel}}, {{7760, 7761, kSentinel}}, {{7762, 7763, kSentinel}}, {{7764, 7765, kSentinel}},  // NOLINT
+  {{7766, 7767, kSentinel}}, {{7768, 7769, kSentinel}}, {{7770, 7771, kSentinel}}, {{7772, 7773, kSentinel}},  // NOLINT
+  {{7774, 7775, kSentinel}}, {{7776, 7777, 7835, kSentinel}}, {{7778, 7779, kSentinel}}, {{7780, 7781, kSentinel}},  // NOLINT
+  {{7782, 7783, kSentinel}}, {{7784, 7785, kSentinel}}, {{7786, 7787, kSentinel}}, {{7788, 7789, kSentinel}},  // NOLINT
+  {{7790, 7791, kSentinel}}, {{7792, 7793, kSentinel}}, {{7794, 7795, kSentinel}}, {{7796, 7797, kSentinel}},  // NOLINT
+  {{7798, 7799, kSentinel}}, {{7800, 7801, kSentinel}}, {{7802, 7803, kSentinel}}, {{7804, 7805, kSentinel}},  // NOLINT
+  {{7806, 7807, kSentinel}}, {{7808, 7809, kSentinel}}, {{7810, 7811, kSentinel}}, {{7812, 7813, kSentinel}},  // NOLINT
+  {{7814, 7815, kSentinel}}, {{7816, 7817, kSentinel}}, {{7818, 7819, kSentinel}}, {{7820, 7821, kSentinel}},  // NOLINT
+  {{7822, 7823, kSentinel}}, {{7824, 7825, kSentinel}}, {{7826, 7827, kSentinel}}, {{7828, 7829, kSentinel}},  // NOLINT
+  {{7840, 7841, kSentinel}}, {{7842, 7843, kSentinel}}, {{7844, 7845, kSentinel}}, {{7846, 7847, kSentinel}},  // NOLINT
+  {{7848, 7849, kSentinel}}, {{7850, 7851, kSentinel}}, {{7852, 7853, kSentinel}}, {{7854, 7855, kSentinel}},  // NOLINT
+  {{7856, 7857, kSentinel}}, {{7858, 7859, kSentinel}}, {{7860, 7861, kSentinel}}, {{7862, 7863, kSentinel}},  // NOLINT
+  {{7864, 7865, kSentinel}}, {{7866, 7867, kSentinel}}, {{7868, 7869, kSentinel}}, {{7870, 7871, kSentinel}},  // NOLINT
+  {{7872, 7873, kSentinel}}, {{7874, 7875, kSentinel}}, {{7876, 7877, kSentinel}}, {{7878, 7879, kSentinel}},  // NOLINT
+  {{7880, 7881, kSentinel}}, {{7882, 7883, kSentinel}}, {{7884, 7885, kSentinel}}, {{7886, 7887, kSentinel}},  // NOLINT
+  {{7888, 7889, kSentinel}}, {{7890, 7891, kSentinel}}, {{7892, 7893, kSentinel}}, {{7894, 7895, kSentinel}},  // NOLINT
+  {{7896, 7897, kSentinel}}, {{7898, 7899, kSentinel}}, {{7900, 7901, kSentinel}}, {{7902, 7903, kSentinel}},  // NOLINT
+  {{7904, 7905, kSentinel}}, {{7906, 7907, kSentinel}}, {{7908, 7909, kSentinel}}, {{7910, 7911, kSentinel}},  // NOLINT
+  {{7912, 7913, kSentinel}}, {{7914, 7915, kSentinel}}, {{7916, 7917, kSentinel}}, {{7918, 7919, kSentinel}},  // NOLINT
+  {{7920, 7921, kSentinel}}, {{7922, 7923, kSentinel}}, {{7924, 7925, kSentinel}}, {{7926, 7927, kSentinel}},  // NOLINT
+  {{7928, 7929, kSentinel}}, {{7936, 7944, kSentinel}}, {{7943, 7951, kSentinel}}, {{7952, 7960, kSentinel}},  // NOLINT
+  {{7957, 7965, kSentinel}}, {{7968, 7976, kSentinel}}, {{7975, 7983, kSentinel}}, {{7984, 7992, kSentinel}},  // NOLINT
+  {{7991, 7999, kSentinel}}, {{8000, 8008, kSentinel}}, {{8005, 8013, kSentinel}}, {{8017, 8025, kSentinel}},  // NOLINT
+  {{8019, 8027, kSentinel}}, {{8021, 8029, kSentinel}}, {{8023, 8031, kSentinel}}, {{8032, 8040, kSentinel}},  // NOLINT
+  {{8039, 8047, kSentinel}}, {{8048, 8122, kSentinel}}, {{8049, 8123, kSentinel}}, {{8050, 8136, kSentinel}},  // NOLINT
+  {{8053, 8139, kSentinel}}, {{8054, 8154, kSentinel}}, {{8055, 8155, kSentinel}}, {{8056, 8184, kSentinel}},  // NOLINT
+  {{8057, 8185, kSentinel}}, {{8058, 8170, kSentinel}}, {{8059, 8171, kSentinel}}, {{8060, 8186, kSentinel}},  // NOLINT
+  {{8061, 8187, kSentinel}}, {{8112, 8120, kSentinel}}, {{8113, 8121, kSentinel}}, {{8144, 8152, kSentinel}},  // NOLINT
+  {{8145, 8153, kSentinel}}, {{8160, 8168, kSentinel}}, {{8161, 8169, kSentinel}}, {{8165, 8172, kSentinel}},  // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kEcma262UnCanonicalizeTable0Size = 945;  // NOLINT
 static const int32_t kEcma262UnCanonicalizeTable0[1890] = {
   1073741889, 1, 90, 5, 1073741921, 1, 122, 5, 181, 9, 1073742016, 13, 214, 17, 1073742040, 21,  // NOLINT
@@ -1453,7 +1455,7 @@
   {{11468, 11469}}, {{11470, 11471}}, {{11472, 11473}}, {{11474, 11475}},  // NOLINT
   {{11476, 11477}}, {{11478, 11479}}, {{11480, 11481}}, {{11482, 11483}},  // NOLINT
   {{11484, 11485}}, {{11486, 11487}}, {{11488, 11489}}, {{11490, 11491}},  // NOLINT
-  {{4256, 11520}}, {{4293, 11557}}, {{-1}} }; // NOLINT
+  {{4256, 11520}}, {{4293, 11557}}, {{kSentinel}} }; // NOLINT
 static const uint16_t kEcma262UnCanonicalizeTable1Size = 133;  // NOLINT
 static const int32_t kEcma262UnCanonicalizeTable1[266] = {
   306, 1, 334, 1, 1073742176, 5, 367, 9, 1073742192, 5, 383, 9, 387, 13, 388, 13,  // NOLINT
@@ -1475,7 +1477,7 @@
   3297, 265, 3298, 269, 3299, 269, 1073745152, 273, 3365, 277 };  // NOLINT
 static const uint16_t kEcma262UnCanonicalizeMultiStrings1Size = 71;  // NOLINT
 static const MultiCharacterSpecialCase<2> kEcma262UnCanonicalizeMultiStrings7[3] = {  // NOLINT
-  {{65313, 65345}}, {{65338, 65370}}, {{-1}} }; // NOLINT
+  {{65313, 65345}}, {{65338, 65370}}, {{kSentinel}} }; // NOLINT
 static const uint16_t kEcma262UnCanonicalizeTable7Size = 4;  // NOLINT
 static const int32_t kEcma262UnCanonicalizeTable7[8] = {
   1073749793, 1, 7994, 5, 1073749825, 1, 8026, 5 };  // NOLINT
@@ -1512,7 +1514,7 @@
 }
 
 static const MultiCharacterSpecialCase<1> kCanonicalizationRangeMultiStrings0[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kCanonicalizationRangeTable0Size = 70;  // NOLINT
 static const int32_t kCanonicalizationRangeTable0[140] = {
   1073741889, 100, 90, 0, 1073741921, 100, 122, 0, 1073742016, 88, 214, 0, 1073742040, 24, 222, 0,  // NOLINT
@@ -1526,14 +1528,14 @@
   1073749864, 28, 8047, 0, 1073749874, 12, 8053, 0, 1073749960, 12, 8139, 0 };  // NOLINT
 static const uint16_t kCanonicalizationRangeMultiStrings0Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kCanonicalizationRangeMultiStrings1[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kCanonicalizationRangeTable1Size = 14;  // NOLINT
 static const int32_t kCanonicalizationRangeTable1[28] = {
   1073742176, 60, 367, 0, 1073742192, 60, 383, 0, 1073743030, 100, 1231, 0, 1073743056, 100, 1257, 0,  // NOLINT
   1073744896, 184, 3118, 0, 1073744944, 184, 3166, 0, 1073745152, 148, 3365, 0 };  // NOLINT
 static const uint16_t kCanonicalizationRangeMultiStrings1Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kCanonicalizationRangeMultiStrings7[1] = {  // NOLINT
-  {{-1}} }; // NOLINT
+  {{kSentinel}} }; // NOLINT
 static const uint16_t kCanonicalizationRangeTable7Size = 4;  // NOLINT
 static const int32_t kCanonicalizationRangeTable7[8] = {
   1073749793, 100, 7994, 0, 1073749825, 100, 8026, 0 };  // NOLINT
diff --git a/src/v8threads.cc b/src/v8threads.cc
index b6e656d..8a5fe69 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -380,7 +380,8 @@
 
 
 ContextSwitcher::ContextSwitcher(int every_n_ms)
-  : keep_going_(true),
+  : Thread("v8:CtxtSwitcher"),
+    keep_going_(true),
     sleep_ms_(every_n_ms) {
 }
 
diff --git a/src/version.cc b/src/version.cc
index e362148..c434e34 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     0
-#define BUILD_NUMBER      5
+#define BUILD_NUMBER      6
 #define PATCH_LEVEL       0
 #define CANDIDATE_VERSION false
 
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 8f15f23..3629967 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -74,7 +74,7 @@
   __ xor_(rax, rdx);  // Different if CPUID is supported.
   __ j(not_zero, &cpuid);
 
-  // CPUID not supported. Clear the supported features in edx:eax.
+  // CPUID not supported. Clear the supported features in rax.
   __ xor_(rax, rax);
   __ jmp(&done);
 
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index fde88df..7bcc7c5 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -536,6 +536,8 @@
   // The debug break slot must be able to contain a call instruction.
   static const int kDebugBreakSlotLength = kCallInstructionLength;
 
+  // One byte opcode for test eax,0xXXXXXXXX.
+  static const byte kTestEaxByte = 0xA9;
 
   // ---------------------------------------------------------------------------
   // Code generation
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 456d076..d738261 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -422,7 +422,7 @@
   // [rsp+0x20] : argv
 
   // Clear the context before we push it when entering the JS frame.
-  __ xor_(rsi, rsi);
+  __ Set(rsi, 0);
   __ EnterInternalFrame();
 
   // Load the function context into rsi.
@@ -451,7 +451,7 @@
   // rdi : function
 
   // Clear the context before we push it when entering the JS frame.
-  __ xor_(rsi, rsi);
+  __ Set(rsi, 0);
   // Enter an internal frame.
   __ EnterInternalFrame();
 
@@ -479,7 +479,7 @@
   // Register rbx points to array of pointers to handle locations.
   // Push the values of these handles.
   Label loop, entry;
-  __ xor_(rcx, rcx);  // Set loop variable to 0.
+  __ Set(rcx, 0);  // Set loop variable to 0.
   __ jmp(&entry);
   __ bind(&loop);
   __ movq(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0));
@@ -668,7 +668,7 @@
   //     become the receiver.
   __ bind(&non_function);
   __ movq(Operand(rsp, rax, times_pointer_size, 0), rdi);
-  __ xor_(rdi, rdi);
+  __ Set(rdi, 0);
 
   // 4. Shift arguments and return address one slot down on the stack
   //    (overwriting the original receiver).  Adjust argument count to make
@@ -689,7 +689,7 @@
   { Label function;
     __ testq(rdi, rdi);
     __ j(not_zero, &function);
-    __ xor_(rbx, rbx);
+    __ Set(rbx, 0);
     __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
     __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
             RelocInfo::CODE_TARGET);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index c3eb5bf..60ec35d 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -104,7 +104,7 @@
   __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length));
 
   // Setup the fixed slots.
-  __ xor_(rbx, rbx);  // Set to NULL.
+  __ Set(rbx, 0);  // Set to NULL.
   __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
   __ movq(Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)), rax);
   __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rbx);
@@ -250,7 +250,7 @@
   __ movq(rax, Immediate(1));
   __ ret(1 * kPointerSize);
   __ bind(&false_result);
-  __ xor_(rax, rax);
+  __ Set(rax, 0);
   __ ret(1 * kPointerSize);
 }
 
@@ -2572,7 +2572,7 @@
 
   // Before returning we restore the context from the frame pointer if not NULL.
   // The frame pointer is NULL in the exception handler of a JS entry frame.
-  __ xor_(rsi, rsi);  // tentatively set context pointer to NULL
+  __ Set(rsi, 0);  // Tentatively set context pointer to NULL
   NearLabel skip;
   __ cmpq(rbp, Immediate(0));
   __ j(equal, &skip);
@@ -2756,7 +2756,7 @@
   }
 
   // Clear the context pointer.
-  __ xor_(rsi, rsi);
+  __ Set(rsi, 0);
 
   // Restore registers from handler.
   STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize ==
diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h
index eb7ad26..0fe4f8a 100644
--- a/src/x64/code-stubs-x64.h
+++ b/src/x64/code-stubs-x64.h
@@ -87,7 +87,7 @@
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
 
-  GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info)
+  GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo runtime_operands_type)
       : op_(OpBits::decode(key)),
         mode_(ModeBits::decode(key)),
         flags_(FlagBits::decode(key)),
@@ -95,7 +95,7 @@
         args_reversed_(ArgsReversedBits::decode(key)),
         static_operands_type_(TypeInfo::ExpandedRepresentation(
             StaticTypeInfoBits::decode(key))),
-        runtime_operands_type_(type_info),
+        runtime_operands_type_(runtime_operands_type),
         name_(NULL) {
   }
 
@@ -348,42 +348,6 @@
 };
 
 
-class RecordWriteStub : public CodeStub {
- public:
-  RecordWriteStub(Register object, Register addr, Register scratch)
-      : object_(object), addr_(addr), scratch_(scratch) { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  Register object_;
-  Register addr_;
-  Register scratch_;
-
-#ifdef DEBUG
-  void Print() {
-    PrintF("RecordWriteStub (object reg %d), (addr reg %d), (scratch reg %d)\n",
-           object_.code(), addr_.code(), scratch_.code());
-  }
-#endif
-
-  // Minor key encoding in 12 bits. 4 bits for each of the three
-  // registers (object, address and scratch) OOOOAAAASSSS.
-  class ScratchBits : public BitField<uint32_t, 0, 4> {};
-  class AddressBits : public BitField<uint32_t, 4, 4> {};
-  class ObjectBits : public BitField<uint32_t, 8, 4> {};
-
-  Major MajorKey() { return RecordWrite; }
-
-  int MinorKey() {
-    // Encode the registers.
-    return ObjectBits::encode(object_.code()) |
-           AddressBits::encode(addr_.code()) |
-           ScratchBits::encode(scratch_.code());
-  }
-};
-
-
 } }  // namespace v8::internal
 
 #endif  // V8_X64_CODE_STUBS_X64_H_
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 9a25572..aa5d335 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -6813,12 +6813,8 @@
   // (or them and test against Smi mask.)
 
   __ movq(tmp2.reg(), tmp1.reg());
-  RecordWriteStub recordWrite1(tmp2.reg(), index1.reg(), object.reg());
-  __ CallStub(&recordWrite1);
-
-  RecordWriteStub recordWrite2(tmp1.reg(), index2.reg(), object.reg());
-  __ CallStub(&recordWrite2);
-
+  __ RecordWriteHelper(tmp1.reg(), index1.reg(), object.reg());
+  __ RecordWriteHelper(tmp2.reg(), index2.reg(), object.reg());
   __ bind(&done);
 
   deferred->BindExit();
@@ -8812,11 +8808,6 @@
 
 #undef __
 
-void RecordWriteStub::Generate(MacroAssembler* masm) {
-  masm->RecordWriteHelper(object_, addr_, scratch_);
-  masm->ret(0);
-}
-
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X64
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
index 2c1056f..4218647 100644
--- a/src/x64/debug-x64.cc
+++ b/src/x64/debug-x64.cc
@@ -25,7 +25,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
 #include "v8.h"
 
 #if defined(V8_TARGET_ARCH_X64)
@@ -39,13 +38,61 @@
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
 
+bool BreakLocationIterator::IsDebugBreakAtReturn()  {
+  return Debug::IsDebugBreakAtReturn(rinfo());
+}
+
+
+// Patch the JS frame exit code with a debug break call. See
+// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x64.cc
+// for the precise return instructions sequence.
+void BreakLocationIterator::SetDebugBreakAtReturn()  {
+  ASSERT(Assembler::kJSReturnSequenceLength >=
+         Assembler::kCallInstructionLength);
+  rinfo()->PatchCodeWithCall(Debug::debug_break_return()->entry(),
+      Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
+}
+
+
+// Restore the JS frame exit code.
+void BreakLocationIterator::ClearDebugBreakAtReturn() {
+  rinfo()->PatchCode(original_rinfo()->pc(),
+                     Assembler::kJSReturnSequenceLength);
+}
+
+
+// A debug break in the frame exit code is identified by the JS frame exit code
+// having been patched with a call instruction.
 bool Debug::IsDebugBreakAtReturn(v8::internal::RelocInfo* rinfo) {
   ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
   return rinfo->IsPatchedReturnSequence();
 }
 
+
+bool BreakLocationIterator::IsDebugBreakAtSlot() {
+  ASSERT(IsDebugBreakSlot());
+  // Check whether the debug break slot instructions have been patched.
+  return !Assembler::IsNop(rinfo()->pc());
+}
+
+
+void BreakLocationIterator::SetDebugBreakAtSlot() {
+  ASSERT(IsDebugBreakSlot());
+  rinfo()->PatchCodeWithCall(
+      Debug::debug_break_slot()->entry(),
+      Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
+}
+
+
+void BreakLocationIterator::ClearDebugBreakAtSlot() {
+  ASSERT(IsDebugBreakSlot());
+  rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
+}
+
+
 #define __ ACCESS_MASM(masm)
 
+
 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
                                           RegList object_regs,
                                           RegList non_object_regs,
@@ -55,7 +102,7 @@
 
   // Store the registers containing live values on the expression stack to
   // make sure that these are correctly updated during GC. Non object values
-  // are stored as as two smi causing it to be untouched by GC.
+  // are stored as as two smis causing it to be untouched by GC.
   ASSERT((object_regs & ~kJSCallerSaved) == 0);
   ASSERT((non_object_regs & ~kJSCallerSaved) == 0);
   ASSERT((object_regs & non_object_regs) == 0);
@@ -80,7 +127,7 @@
 #ifdef DEBUG
   __ RecordComment("// Calling from debug break to runtime - come in - over");
 #endif
-  __ xor_(rax, rax);  // No arguments (argc == 0).
+  __ Set(rax, 0);  // No arguments (argc == 0).
   __ movq(rbx, ExternalReference::debug_break());
 
   CEntryStub ceb(1);
@@ -126,24 +173,25 @@
 }
 
 
-void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
-  // Register state for IC call call (from ic-x64.cc)
+void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
+  // Register state for IC load call (from ic-x64.cc).
   // ----------- S t a t e -------------
-  //  -- rcx: function name
+  //  -- rax    : receiver
+  //  -- rcx    : name
   // -----------------------------------
-  Generate_DebugBreakCallHelper(masm, rcx.bit(), 0, false);
+  Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), 0, false);
 }
 
 
-void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
-  // Register state just before return from JS function (from codegen-x64.cc).
-  // rax is the actual number of arguments not encoded as a smi, see comment
-  // above IC call.
+void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
+  // Register state for IC store call (from ic-x64.cc).
   // ----------- S t a t e -------------
-  //  -- rax: number of arguments
+  //  -- rax    : value
+  //  -- rcx    : name
+  //  -- rdx    : receiver
   // -----------------------------------
-  // The number of arguments in rax is not smi encoded.
-  Generate_DebugBreakCallHelper(masm, rdi.bit(), rax.bit(), false);
+  Generate_DebugBreakCallHelper(
+      masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false);
 }
 
 
@@ -169,13 +217,24 @@
 }
 
 
-void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
-  // Register state for IC load call (from ic-x64.cc).
+void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
+  // Register state for IC call call (from ic-x64.cc)
   // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
+  //  -- rcx: function name
   // -----------------------------------
-  Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), 0, false);
+  Generate_DebugBreakCallHelper(masm, rcx.bit(), 0, false);
+}
+
+
+void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
+  // Register state just before return from JS function (from codegen-x64.cc).
+  // rax is the actual number of arguments not encoded as a smi, see comment
+  // above IC call.
+  // ----------- S t a t e -------------
+  //  -- rax: number of arguments
+  // -----------------------------------
+  // The number of arguments in rax is not smi encoded.
+  Generate_DebugBreakCallHelper(masm, rdi.bit(), rax.bit(), false);
 }
 
 
@@ -188,18 +247,6 @@
 }
 
 
-void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
-  // Register state for IC store call (from ic-x64.cc).
-  // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : name
-  //  -- rdx    : receiver
-  // -----------------------------------
-  Generate_DebugBreakCallHelper(
-      masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false);
-}
-
-
 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) {
   // Register state for stub CallFunction (from CallFunctionStub in ic-x64.cc).
   // ----------- S t a t e -------------
@@ -262,49 +309,6 @@
 
 #undef __
 
-
-
-
-void BreakLocationIterator::ClearDebugBreakAtReturn() {
-  rinfo()->PatchCode(original_rinfo()->pc(),
-                     Assembler::kJSReturnSequenceLength);
-}
-
-
-bool BreakLocationIterator::IsDebugBreakAtReturn()  {
-  return Debug::IsDebugBreakAtReturn(rinfo());
-}
-
-
-void BreakLocationIterator::SetDebugBreakAtReturn()  {
-  ASSERT(Assembler::kJSReturnSequenceLength >=
-         Assembler::kCallInstructionLength);
-  rinfo()->PatchCodeWithCall(Debug::debug_break_return()->entry(),
-      Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
-}
-
-
-bool BreakLocationIterator::IsDebugBreakAtSlot() {
-  ASSERT(IsDebugBreakSlot());
-  // Check whether the debug break slot instructions have been patched.
-  return !Assembler::IsNop(rinfo()->pc());
-}
-
-
-void BreakLocationIterator::SetDebugBreakAtSlot() {
-  ASSERT(IsDebugBreakSlot());
-  rinfo()->PatchCodeWithCall(
-      Debug::debug_break_slot()->entry(),
-      Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
-}
-
-
-void BreakLocationIterator::ClearDebugBreakAtSlot() {
-  ASSERT(IsDebugBreakSlot());
-  rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
-}
-
-
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 } }  // namespace v8::internal
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index dd28d4d..66bc4ed 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -199,7 +199,7 @@
 
 
 void FullCodeGenerator::ClearAccumulator() {
-  __ xor_(rax, rax);
+  __ Set(rax, 0);
 }
 
 
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index aff778a..29cbed0 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -378,81 +378,50 @@
 }
 
 
-// One byte opcode for test rax,0xXXXXXXXX.
-static const byte kTestEaxByte = 0xA9;
+// The offset from the inlined patch site to the start of the inlined
+// load instruction.
+const int LoadIC::kOffsetToLoadInstruction = 20;
 
 
-static bool PatchInlinedMapCheck(Address address, Object* map) {
-  if (V8::UseCrankshaft()) return false;
-
-  // Arguments are address of start of call sequence that called
-  // the IC,
-  Address test_instruction_address =
-      address + Assembler::kCallTargetAddressOffset;
-  // The keyed load has a fast inlined case if the IC call instruction
-  // is immediately followed by a test instruction.
-  if (*test_instruction_address != kTestEaxByte) return false;
-
-  // Fetch the offset from the test instruction to the map compare
-  // instructions (starting with the 64-bit immediate mov of the map
-  // address). This offset is stored in the last 4 bytes of the 5
-  // byte test instruction.
-  Address delta_address = test_instruction_address + 1;
-  int delta = *reinterpret_cast<int*>(delta_address);
-  // Compute the map address.  The map address is in the last 8 bytes
-  // of the 10-byte immediate mov instruction (incl. REX prefix), so we add 2
-  // to the offset to get the map address.
-  Address map_address = test_instruction_address + delta + 2;
-  // Patch the map check.
-  *(reinterpret_cast<Object**>(map_address)) = map;
-  return true;
-}
-
-
-bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
-  return PatchInlinedMapCheck(address, map);
-}
-
-
-bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
-  return PatchInlinedMapCheck(address, map);
-}
-
-
-void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
+void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0]  : return address
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
   // -----------------------------------
+  Label miss;
 
-  __ IncrementCounter(&Counters::keyed_load_miss, 1);
-
-  __ pop(rbx);
-  __ push(rdx);  // receiver
-  __ push(rax);  // name
-  __ push(rbx);  // return address
-
-  // Perform tail call to the entry.
-  ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
-  __ TailCallExternalReference(ref, 2, 1);
+  StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
+  __ bind(&miss);
+  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
 }
 
 
-void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+void LoadIC::GenerateStringLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0]  : return address
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
   // -----------------------------------
+  Label miss;
 
-  __ pop(rbx);
-  __ push(rdx);  // receiver
-  __ push(rax);  // name
-  __ push(rbx);  // return address
+  StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
+  __ bind(&miss);
+  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
+}
 
-  // Perform tail call to the entry.
-  __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
+
+void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  StubCompiler::GenerateLoadFunctionPrototype(masm, rax, rdx, rbx, &miss);
+  __ bind(&miss);
+  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
 }
 
 
@@ -923,45 +892,6 @@
 }
 
 
-void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rax     : value
-  //  -- rcx     : key
-  //  -- rdx     : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-
-  __ pop(rbx);
-  __ push(rdx);  // receiver
-  __ push(rcx);  // key
-  __ push(rax);  // value
-  __ push(rbx);  // return address
-
-  // Do tail-call to runtime routine.
-  ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
-  __ TailCallExternalReference(ref, 3, 1);
-}
-
-
-void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rax     : value
-  //  -- rcx     : key
-  //  -- rdx     : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-
-  __ pop(rbx);
-  __ push(rdx);  // receiver
-  __ push(rcx);  // key
-  __ push(rax);  // value
-  __ push(rbx);  // return address
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
-}
-
-
 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax     : value
@@ -1236,71 +1166,6 @@
 }
 
 
-// Defined in ic.cc.
-Object* CallIC_Miss(Arguments args);
-
-
-static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
-  // ----------- S t a t e -------------
-  // rcx                      : function name
-  // rsp[0]                   : return address
-  // rsp[8]                   : argument argc
-  // rsp[16]                  : argument argc - 1
-  // ...
-  // rsp[argc * 8]            : argument 1
-  // rsp[(argc + 1) * 8]      : argument 0 = receiver
-  // -----------------------------------
-
-  if (id == IC::kCallIC_Miss) {
-    __ IncrementCounter(&Counters::call_miss, 1);
-  } else {
-    __ IncrementCounter(&Counters::keyed_call_miss, 1);
-  }
-
-  // Get the receiver of the function from the stack; 1 ~ return address.
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
-
-  // Enter an internal frame.
-  __ EnterInternalFrame();
-
-  // Push the receiver and the name of the function.
-  __ push(rdx);
-  __ push(rcx);
-
-  // Call the entry.
-  CEntryStub stub(1);
-  __ movq(rax, Immediate(2));
-  __ movq(rbx, ExternalReference(IC_Utility(id)));
-  __ CallStub(&stub);
-
-  // Move result to rdi and exit the internal frame.
-  __ movq(rdi, rax);
-  __ LeaveInternalFrame();
-
-  // Check if the receiver is a global object of some sort.
-  // This can happen only for regular CallIC but not KeyedCallIC.
-  if (id == IC::kCallIC_Miss) {
-    Label invoke, global;
-    __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));  // receiver
-    __ JumpIfSmi(rdx, &invoke);
-    __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
-    __ j(equal, &global);
-    __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE);
-    __ j(not_equal, &invoke);
-
-    // Patch the receiver on the stack.
-    __ bind(&global);
-    __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-    __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
-    __ bind(&invoke);
-  }
-
-  // Invoke the function.
-  ParameterCount actual(argc);
-  __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
-}
-
-
 // The generated code does not accept smi keys.
 // The generated code falls through if both probes miss.
 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
@@ -1409,7 +1274,7 @@
 }
 
 
-void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
+static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
   // ----------- S t a t e -------------
   // rcx                      : function name
   // rsp[0]                   : return address
@@ -1419,7 +1284,54 @@
   // rsp[argc * 8]            : argument 1
   // rsp[(argc + 1) * 8]      : argument 0 = receiver
   // -----------------------------------
-  GenerateCallMiss(masm, argc, IC::kCallIC_Miss);
+
+  if (id == IC::kCallIC_Miss) {
+    __ IncrementCounter(&Counters::call_miss, 1);
+  } else {
+    __ IncrementCounter(&Counters::keyed_call_miss, 1);
+  }
+
+  // Get the receiver of the function from the stack; 1 ~ return address.
+  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+
+  // Enter an internal frame.
+  __ EnterInternalFrame();
+
+  // Push the receiver and the name of the function.
+  __ push(rdx);
+  __ push(rcx);
+
+  // Call the entry.
+  CEntryStub stub(1);
+  __ movq(rax, Immediate(2));
+  __ movq(rbx, ExternalReference(IC_Utility(id)));
+  __ CallStub(&stub);
+
+  // Move result to rdi and exit the internal frame.
+  __ movq(rdi, rax);
+  __ LeaveInternalFrame();
+
+  // Check if the receiver is a global object of some sort.
+  // This can happen only for regular CallIC but not KeyedCallIC.
+  if (id == IC::kCallIC_Miss) {
+    Label invoke, global;
+    __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));  // receiver
+    __ JumpIfSmi(rdx, &invoke);
+    __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
+    __ j(equal, &global);
+    __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE);
+    __ j(not_equal, &invoke);
+
+    // Patch the receiver on the stack.
+    __ bind(&global);
+    __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
+    __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+    __ bind(&invoke);
+  }
+
+  // Invoke the function.
+  ParameterCount actual(argc);
+  __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
 }
 
 
@@ -1457,7 +1369,7 @@
 }
 
 
-void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) {
+void CallIC::GenerateMiss(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
   // rcx                      : function name
   // rsp[0]                   : return address
@@ -1468,7 +1380,7 @@
   // rsp[(argc + 1) * 8]      : argument 0 = receiver
   // -----------------------------------
 
-  GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss);
+  GenerateCallMiss(masm, argc, IC::kCallIC_Miss);
 }
 
 
@@ -1594,56 +1506,18 @@
 }
 
 
-// The offset from the inlined patch site to the start of the inlined
-// load instruction.
-const int LoadIC::kOffsetToLoadInstruction = 20;
-
-
-void LoadIC::GenerateMiss(MacroAssembler* masm) {
+void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) {
   // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
+  // rcx                      : function name
+  // rsp[0]                   : return address
+  // rsp[8]                   : argument argc
+  // rsp[16]                  : argument argc - 1
+  // ...
+  // rsp[argc * 8]            : argument 1
+  // rsp[(argc + 1) * 8]      : argument 0 = receiver
   // -----------------------------------
 
-  __ IncrementCounter(&Counters::load_miss, 1);
-
-  __ pop(rbx);
-  __ push(rax);  // receiver
-  __ push(rcx);  // name
-  __ push(rbx);  // return address
-
-  // Perform tail call to the entry.
-  ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
-  __ TailCallExternalReference(ref, 2, 1);
-}
-
-
-void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
-  __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
-}
-
-
-void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  StubCompiler::GenerateLoadFunctionPrototype(masm, rax, rdx, rbx, &miss);
-  __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
+  GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss);
 }
 
 
@@ -1686,17 +1560,23 @@
 }
 
 
-void LoadIC::GenerateStringLength(MacroAssembler* masm) {
+void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : receiver
   //  -- rcx    : name
   //  -- rsp[0] : return address
   // -----------------------------------
-  Label miss;
 
-  StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
-  __ bind(&miss);
-  StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
+  __ IncrementCounter(&Counters::load_miss, 1);
+
+  __ pop(rbx);
+  __ push(rax);  // receiver
+  __ push(rcx);  // name
+  __ push(rbx);  // return address
+
+  // Perform tail call to the entry.
+  ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
+  __ TailCallExternalReference(ref, 2, 1);
 }
 
 
@@ -1708,7 +1588,7 @@
       address + Assembler::kCallTargetAddressOffset;
   // If the instruction following the call is not a test rax, nothing
   // was inlined.
-  if (*test_instruction_address != kTestEaxByte) return false;
+  if (*test_instruction_address != Assembler::kTestEaxByte) return false;
 
   Address delta_address = test_instruction_address + 1;
   // The delta to the start of the map check instruction.
@@ -1739,11 +1619,6 @@
 }
 
 
-// The offset from the inlined patch site to the start of the inlined
-// store instruction.
-const int StoreIC::kOffsetToStoreInstruction = 20;
-
-
 bool StoreIC::PatchInlinedStore(Address address, Object* map, int offset) {
   if (V8::UseCrankshaft()) return false;
 
@@ -1753,7 +1628,7 @@
 
   // If the instruction following the call is not a test rax, nothing
   // was inlined.
-  if (*test_instruction_address != kTestEaxByte) return false;
+  if (*test_instruction_address != Assembler::kTestEaxByte) return false;
 
   // Extract the encoded deltas from the test rax instruction.
   Address encoded_offsets_address = test_instruction_address + 1;
@@ -1792,23 +1667,77 @@
 }
 
 
-void StoreIC::GenerateMiss(MacroAssembler* masm) {
+static bool PatchInlinedMapCheck(Address address, Object* map) {
+  if (V8::UseCrankshaft()) return false;
+
+  // Arguments are address of start of call sequence that called
+  // the IC,
+  Address test_instruction_address =
+      address + Assembler::kCallTargetAddressOffset;
+  // The keyed load has a fast inlined case if the IC call instruction
+  // is immediately followed by a test instruction.
+  if (*test_instruction_address != Assembler::kTestEaxByte) return false;
+
+  // Fetch the offset from the test instruction to the map compare
+  // instructions (starting with the 64-bit immediate mov of the map
+  // address). This offset is stored in the last 4 bytes of the 5
+  // byte test instruction.
+  Address delta_address = test_instruction_address + 1;
+  int delta = *reinterpret_cast<int*>(delta_address);
+  // Compute the map address.  The map address is in the last 8 bytes
+  // of the 10-byte immediate mov instruction (incl. REX prefix), so we add 2
+  // to the offset to get the map address.
+  Address map_address = test_instruction_address + delta + 2;
+  // Patch the map check.
+  *(reinterpret_cast<Object**>(map_address)) = map;
+  return true;
+}
+
+
+bool KeyedLoadIC::PatchInlinedLoad(Address address, Object* map) {
+  return PatchInlinedMapCheck(address, map);
+}
+
+
+bool KeyedStoreIC::PatchInlinedStore(Address address, Object* map) {
+  return PatchInlinedMapCheck(address, map);
+}
+
+
+void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
   // ----------- S t a t e -------------
-  //  -- rax    : value
-  //  -- rcx    : name
+  //  -- rax    : key
   //  -- rdx    : receiver
-  //  -- rsp[0] : return address
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+
+  __ IncrementCounter(&Counters::keyed_load_miss, 1);
+
+  __ pop(rbx);
+  __ push(rdx);  // receiver
+  __ push(rax);  // name
+  __ push(rbx);  // return address
+
+  // Perform tail call to the entry.
+  ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
+  __ TailCallExternalReference(ref, 2, 1);
+}
+
+
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0]  : return address
   // -----------------------------------
 
   __ pop(rbx);
   __ push(rdx);  // receiver
-  __ push(rcx);  // name
-  __ push(rax);  // value
+  __ push(rax);  // name
   __ push(rbx);  // return address
 
   // Perform tail call to the entry.
-  ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
-  __ TailCallExternalReference(ref, 3, 1);
+  __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
 }
 
 
@@ -1831,6 +1760,31 @@
 }
 
 
+void StoreIC::GenerateMiss(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax    : value
+  //  -- rcx    : name
+  //  -- rdx    : receiver
+  //  -- rsp[0] : return address
+  // -----------------------------------
+
+  __ pop(rbx);
+  __ push(rdx);  // receiver
+  __ push(rcx);  // name
+  __ push(rax);  // value
+  __ push(rbx);  // return address
+
+  // Perform tail call to the entry.
+  ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss));
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+// The offset from the inlined patch site to the start of the inlined
+// store instruction.
+const int StoreIC::kOffsetToStoreInstruction = 20;
+
+
 void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- rax    : value
@@ -1923,6 +1877,45 @@
 }
 
 
+void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax     : value
+  //  -- rcx     : key
+  //  -- rdx     : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+
+  __ pop(rbx);
+  __ push(rdx);  // receiver
+  __ push(rcx);  // key
+  __ push(rax);  // value
+  __ push(rbx);  // return address
+
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 3, 1);
+}
+
+
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- rax     : value
+  //  -- rcx     : key
+  //  -- rdx     : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+
+  __ pop(rbx);
+  __ push(rdx);  // receiver
+  __ push(rcx);  // key
+  __ push(rax);  // value
+  __ push(rbx);  // return address
+
+  // Do tail-call to runtime routine.
+  ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
 #undef __
 
 
@@ -1976,6 +1969,7 @@
   UNIMPLEMENTED();
 }
 
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X64
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 1df9b47..70a3dab 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -1110,7 +1110,7 @@
 
 void MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) {
   if (constant->value() == 0) {
-    xor_(dst, dst);
+    Set(dst, 0);
   } else if (dst.is(src)) {
     ASSERT(!dst.is(kScratchRegister));
     Register constant_reg = GetSmiConstant(constant);
@@ -1605,7 +1605,7 @@
 #ifdef ENABLE_DEBUGGER_SUPPORT
 void MacroAssembler::DebugBreak() {
   ASSERT(allow_stub_calls());
-  xor_(rax, rax);  // no arguments
+  Set(rax, 0);  // No arguments.
   movq(rbx, ExternalReference(Runtime::kDebugBreak));
   CEntryStub ces(1);
   Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index d8f2fba..30b9ba5 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -1176,7 +1176,7 @@
     jmp(on_not_smi_result);
 
     bind(&zero_correct_result);
-    xor_(dst, dst);
+    Set(dst, 0);
 
     bind(&correct_result);
   } else {
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 0838ddd..27f3482 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -688,7 +688,7 @@
 
 void RegExpMacroAssemblerX64::Fail() {
   ASSERT(FAILURE == 0);  // Return value for failure is zero.
-  __ xor_(rax, rax);  // zero rax.
+  __ Set(rax, 0);
   __ jmp(&exit_label_);
 }
 
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 63e9769..57cba14 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -25,23 +25,17 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
 #include "v8.h"
 
 #if defined(V8_TARGET_ARCH_X64)
 
 #include "ic-inl.h"
-#include "code-stubs.h"
 #include "codegen-inl.h"
 #include "stub-cache.h"
-#include "macro-assembler.h"
 
 namespace v8 {
 namespace internal {
 
-//-----------------------------------------------------------------------------
-// StubCompiler static helper functions
-
 #define __ ACCESS_MASM(masm)
 
 
@@ -182,92 +176,6 @@
 }
 
 
-void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
-  ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
-  Code* code = NULL;
-  if (kind == Code::LOAD_IC) {
-    code = Builtins::builtin(Builtins::LoadIC_Miss);
-  } else {
-    code = Builtins::builtin(Builtins::KeyedLoadIC_Miss);
-  }
-
-  Handle<Code> ic(code);
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-}
-
-
-void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
-                                                       int index,
-                                                       Register prototype) {
-  // Load the global or builtins object from the current context.
-  __ movq(prototype,
-             Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
-  // Load the global context from the global or builtins object.
-  __ movq(prototype,
-             FieldOperand(prototype, GlobalObject::kGlobalContextOffset));
-  // Load the function from the global context.
-  __ movq(prototype, Operand(prototype, Context::SlotOffset(index)));
-  // Load the initial map.  The global functions all have initial maps.
-  __ movq(prototype,
-             FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
-  // Load the prototype from the initial map.
-  __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
-}
-
-
-void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  // Check we're still in the same context.
-  __ Move(prototype, Top::global());
-  __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)),
-          prototype);
-  __ j(not_equal, miss);
-  // Get the global function with the given index.
-  JSFunction* function = JSFunction::cast(Top::global_context()->get(index));
-  // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Handle<Map>(function->initial_map()));
-  // Load the prototype from the initial map.
-  __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
-}
-
-
-// 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,
-                                            JSObject* holder, int index) {
-  // Adjust for the number of properties stored in the holder.
-  index -= holder->map()->inobject_properties();
-  if (index < 0) {
-    // Get the property straight out of the holder.
-    int offset = holder->map()->instance_size() + (index * kPointerSize);
-    __ movq(dst, FieldOperand(src, offset));
-  } else {
-    // Calculate the offset into the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
-    __ movq(dst, FieldOperand(dst, offset));
-  }
-}
-
-
-static void PushInterceptorArguments(MacroAssembler* masm,
-                                     Register receiver,
-                                     Register holder,
-                                     Register name,
-                                     JSObject* holder_obj) {
-  __ push(name);
-  InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
-  ASSERT(!Heap::InNewSpace(interceptor));
-  __ Move(kScratchRegister, Handle<Object>(interceptor));
-  __ push(kScratchRegister);
-  __ push(receiver);
-  __ push(holder);
-  __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
-}
-
-
 void StubCache::GenerateProbe(MacroAssembler* masm,
                               Code::Flags flags,
                               Register receiver,
@@ -324,83 +232,38 @@
 }
 
 
-// Both name_reg and receiver_reg are preserved on jumps to miss_label,
-// but may be destroyed if store is successful.
-void StubCompiler::GenerateStoreField(MacroAssembler* masm,
-                                      JSObject* object,
-                                      int index,
-                                      Map* transition,
-                                      Register receiver_reg,
-                                      Register name_reg,
-                                      Register scratch,
-                                      Label* miss_label) {
-  // Check that the object isn't a smi.
-  __ JumpIfSmi(receiver_reg, miss_label);
+void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
+                                                       int index,
+                                                       Register prototype) {
+  // Load the global or builtins object from the current context.
+  __ movq(prototype,
+             Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
+  // Load the global context from the global or builtins object.
+  __ movq(prototype,
+             FieldOperand(prototype, GlobalObject::kGlobalContextOffset));
+  // Load the function from the global context.
+  __ movq(prototype, Operand(prototype, Context::SlotOffset(index)));
+  // Load the initial map.  The global functions all have initial maps.
+  __ movq(prototype,
+             FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
+  // Load the prototype from the initial map.
+  __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
+}
 
-  // Check that the map of the object hasn't changed.
-  __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
-         Handle<Map>(object->map()));
-  __ j(not_equal, miss_label);
 
-  // Perform global security token check if needed.
-  if (object->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
-  }
-
-  // Stub never generated for non-global objects that require access
-  // checks.
-  ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
-
-  // Perform map transition for the receiver if necessary.
-  if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ pop(scratch);  // Return address.
-    __ push(receiver_reg);
-    __ Push(Handle<Map>(transition));
-    __ push(rax);
-    __ push(scratch);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1);
-    return;
-  }
-
-  if (transition != NULL) {
-    // Update the map of the object; no write barrier updating is
-    // needed because the map is never in new space.
-    __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset),
-            Handle<Map>(transition));
-  }
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= object->map()->inobject_properties();
-
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = object->map()->instance_size() + (index * kPointerSize);
-    __ movq(FieldOperand(receiver_reg, offset), rax);
-
-    // Update the write barrier for the array address.
-    // Pass the value being stored in the now unused name_reg.
-    __ movq(name_reg, rax);
-    __ RecordWrite(receiver_reg, offset, name_reg, scratch);
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array (optimistically).
-    __ movq(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
-    __ movq(FieldOperand(scratch, offset), rax);
-
-    // Update the write barrier for the array address.
-    // Pass the value being stored in the now unused name_reg.
-    __ movq(name_reg, rax);
-    __ RecordWrite(scratch, offset, name_reg, receiver_reg);
-  }
-
-  // Return the value (register rax).
-  __ ret(0);
+void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
+    MacroAssembler* masm, int index, Register prototype, Label* miss) {
+  // Check we're still in the same context.
+  __ Move(prototype, Top::global());
+  __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)),
+          prototype);
+  __ j(not_equal, miss);
+  // Get the global function with the given index.
+  JSFunction* function = JSFunction::cast(Top::global_context()->get(index));
+  // Load its initial map. The global functions all have initial maps.
+  __ Move(prototype, Handle<Map>(function->initial_map()));
+  // Load the prototype from the initial map.
+  __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
 }
 
 
@@ -469,6 +332,54 @@
 }
 
 
+void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
+                                                 Register receiver,
+                                                 Register result,
+                                                 Register scratch,
+                                                 Label* miss_label) {
+  __ TryGetFunctionPrototype(receiver, result, miss_label);
+  if (!result.is(rax)) __ movq(rax, result);
+  __ ret(0);
+}
+
+
+// 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,
+                                            JSObject* holder, int index) {
+  // Adjust for the number of properties stored in the holder.
+  index -= holder->map()->inobject_properties();
+  if (index < 0) {
+    // Get the property straight out of the holder.
+    int offset = holder->map()->instance_size() + (index * kPointerSize);
+    __ movq(dst, FieldOperand(src, offset));
+  } else {
+    // Calculate the offset into the properties array.
+    int offset = index * kPointerSize + FixedArray::kHeaderSize;
+    __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
+    __ movq(dst, FieldOperand(dst, offset));
+  }
+}
+
+
+static void PushInterceptorArguments(MacroAssembler* masm,
+                                     Register receiver,
+                                     Register holder,
+                                     Register name,
+                                     JSObject* holder_obj) {
+  __ push(name);
+  InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
+  ASSERT(!Heap::InNewSpace(interceptor));
+  __ Move(kScratchRegister, Handle<Object>(interceptor));
+  __ push(kScratchRegister);
+  __ push(receiver);
+  __ push(holder);
+  __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
+}
+
+
 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
                                                    Register receiver,
                                                    Register holder,
@@ -486,20 +397,10 @@
 }
 
 
-
-void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
-                                                 Register receiver,
-                                                 Register result,
-                                                 Register scratch,
-                                                 Label* miss_label) {
-  __ TryGetFunctionPrototype(receiver, result, miss_label);
-  if (!result.is(rax)) __ movq(rax, result);
-  __ ret(0);
-}
-
 // Number of pointers to be reserved on stack for fast API call.
 static const int kFastApiCallArguments = 3;
 
+
 // Reserves space for the extra arguments to API function in the
 // caller's frame.
 //
@@ -553,7 +454,6 @@
   //  -- rsp[(argc + 3) * 8] : first argument
   //  -- rsp[(argc + 4) * 8] : receiver
   // -----------------------------------
-
   // Get the function and setup the context.
   JSFunction* function = optimization.constant_function();
   __ Move(rdi, Handle<JSFunction>(function));
@@ -833,6 +733,100 @@
 };
 
 
+void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
+  ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
+  Code* code = NULL;
+  if (kind == Code::LOAD_IC) {
+    code = Builtins::builtin(Builtins::LoadIC_Miss);
+  } else {
+    code = Builtins::builtin(Builtins::KeyedLoadIC_Miss);
+  }
+
+  Handle<Code> ic(code);
+  __ Jump(ic, RelocInfo::CODE_TARGET);
+}
+
+
+// Both name_reg and receiver_reg are preserved on jumps to miss_label,
+// but may be destroyed if store is successful.
+void StubCompiler::GenerateStoreField(MacroAssembler* masm,
+                                      JSObject* object,
+                                      int index,
+                                      Map* transition,
+                                      Register receiver_reg,
+                                      Register name_reg,
+                                      Register scratch,
+                                      Label* miss_label) {
+  // Check that the object isn't a smi.
+  __ JumpIfSmi(receiver_reg, miss_label);
+
+  // Check that the map of the object hasn't changed.
+  __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
+         Handle<Map>(object->map()));
+  __ j(not_equal, miss_label);
+
+  // Perform global security token check if needed.
+  if (object->IsJSGlobalProxy()) {
+    __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
+  }
+
+  // Stub never generated for non-global objects that require access
+  // checks.
+  ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
+
+  // Perform map transition for the receiver if necessary.
+  if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) {
+    // The properties must be extended before we can store the value.
+    // We jump to a runtime call that extends the properties array.
+    __ pop(scratch);  // Return address.
+    __ push(receiver_reg);
+    __ Push(Handle<Map>(transition));
+    __ push(rax);
+    __ push(scratch);
+    __ TailCallExternalReference(
+        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1);
+    return;
+  }
+
+  if (transition != NULL) {
+    // Update the map of the object; no write barrier updating is
+    // needed because the map is never in new space.
+    __ Move(FieldOperand(receiver_reg, HeapObject::kMapOffset),
+            Handle<Map>(transition));
+  }
+
+  // Adjust for the number of properties stored in the object. Even in the
+  // face of a transition we can use the old map here because the size of the
+  // object and the number of in-object properties is not going to change.
+  index -= object->map()->inobject_properties();
+
+  if (index < 0) {
+    // Set the property straight into the object.
+    int offset = object->map()->instance_size() + (index * kPointerSize);
+    __ movq(FieldOperand(receiver_reg, offset), rax);
+
+    // Update the write barrier for the array address.
+    // Pass the value being stored in the now unused name_reg.
+    __ movq(name_reg, rax);
+    __ RecordWrite(receiver_reg, offset, name_reg, scratch);
+  } else {
+    // Write to the properties array.
+    int offset = index * kPointerSize + FixedArray::kHeaderSize;
+    // Get the properties array (optimistically).
+    __ movq(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
+    __ movq(FieldOperand(scratch, offset), rax);
+
+    // Update the write barrier for the array address.
+    // Pass the value being stored in the now unused name_reg.
+    __ movq(name_reg, rax);
+    __ RecordWrite(scratch, offset, name_reg, receiver_reg);
+  }
+
+  // Return the value (register rax).
+  __ ret(0);
+}
+
+
 // Generate code to check that a global property cell is empty. Create
 // the property cell at compilation time if no cell exists for the
 // property.
@@ -857,10 +851,420 @@
 
 
 #undef __
-
 #define __ ACCESS_MASM((masm()))
 
 
+Register StubCompiler::CheckPrototypes(JSObject* object,
+                                       Register object_reg,
+                                       JSObject* holder,
+                                       Register holder_reg,
+                                       Register scratch1,
+                                       Register scratch2,
+                                       String* name,
+                                       int save_at_depth,
+                                       Label* miss) {
+  // Make sure there's no overlap between holder and object registers.
+  ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
+  ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
+         && !scratch2.is(scratch1));
+
+  // Keep track of the current object in register reg.  On the first
+  // iteration, reg is an alias for object_reg, on later iterations,
+  // it is an alias for holder_reg.
+  Register reg = object_reg;
+  int depth = 0;
+
+  if (save_at_depth == depth) {
+    __ movq(Operand(rsp, kPointerSize), object_reg);
+  }
+
+  // Check the maps in the prototype chain.
+  // Traverse the prototype chain from the object and do map checks.
+  JSObject* current = object;
+  while (current != holder) {
+    depth++;
+
+    // Only global objects and objects that do not require access
+    // checks are allowed in stubs.
+    ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
+
+    JSObject* prototype = JSObject::cast(current->GetPrototype());
+    if (!current->HasFastProperties() &&
+        !current->IsJSGlobalObject() &&
+        !current->IsJSGlobalProxy()) {
+      if (!name->IsSymbol()) {
+        MaybeObject* lookup_result = Heap::LookupSymbol(name);
+        if (lookup_result->IsFailure()) {
+          set_failure(Failure::cast(lookup_result));
+          return reg;
+        } else {
+          name = String::cast(lookup_result->ToObjectUnchecked());
+        }
+      }
+      ASSERT(current->property_dictionary()->FindEntry(name) ==
+             StringDictionary::kNotFound);
+
+      GenerateDictionaryNegativeLookup(masm(),
+                                       miss,
+                                       reg,
+                                       name,
+                                       scratch1,
+                                       scratch2);
+      __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+      reg = holder_reg;  // from now the object is in holder_reg
+      __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
+    } else if (Heap::InNewSpace(prototype)) {
+      // Get the map of the current object.
+      __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+      __ Cmp(scratch1, Handle<Map>(current->map()));
+      // Branch on the result of the map check.
+      __ j(not_equal, miss);
+      // Check access rights to the global object.  This has to happen
+      // after the map check so that we know that the object is
+      // actually a global object.
+      if (current->IsJSGlobalProxy()) {
+        __ CheckAccessGlobalProxy(reg, scratch1, miss);
+
+        // Restore scratch register to be the map of the object.
+        // We load the prototype from the map in the scratch register.
+        __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+      }
+      // The prototype is in new space; we cannot store a reference
+      // to it in the code. Load it from the map.
+      reg = holder_reg;  // from now the object is in holder_reg
+      __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
+
+    } else {
+      // Check the map of the current object.
+      __ Cmp(FieldOperand(reg, HeapObject::kMapOffset),
+          Handle<Map>(current->map()));
+      // Branch on the result of the map check.
+      __ j(not_equal, miss);
+      // Check access rights to the global object.  This has to happen
+      // after the map check so that we know that the object is
+      // actually a global object.
+      if (current->IsJSGlobalProxy()) {
+        __ CheckAccessGlobalProxy(reg, scratch1, miss);
+      }
+      // The prototype is in old space; load it directly.
+      reg = holder_reg;  // from now the object is in holder_reg
+      __ Move(reg, Handle<JSObject>(prototype));
+    }
+
+    if (save_at_depth == depth) {
+      __ movq(Operand(rsp, kPointerSize), reg);
+    }
+
+    // Go to the next object in the prototype chain.
+    current = prototype;
+  }
+
+  // Check the holder map.
+  __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map()));
+  __ j(not_equal, miss);
+
+  // Log the check depth.
+  LOG(IntEvent("check-maps-depth", depth + 1));
+
+  // Perform security check for access to the global object and return
+  // the holder register.
+  ASSERT(current == holder);
+  ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
+  if (current->IsJSGlobalProxy()) {
+    __ CheckAccessGlobalProxy(reg, scratch1, miss);
+  }
+
+  // If we've skipped any global objects, it's not enough to verify
+  // that their maps haven't changed.  We also need to check that the
+  // property cell for the property is still empty.
+  current = object;
+  while (current != holder) {
+    if (current->IsGlobalObject()) {
+      MaybeObject* cell = GenerateCheckPropertyCell(masm(),
+                                                    GlobalObject::cast(current),
+                                                    name,
+                                                    scratch1,
+                                                    miss);
+      if (cell->IsFailure()) {
+        set_failure(Failure::cast(cell));
+        return reg;
+      }
+    }
+    current = JSObject::cast(current->GetPrototype());
+  }
+
+  // Return the register containing the holder.
+  return reg;
+}
+
+
+void StubCompiler::GenerateLoadField(JSObject* object,
+                                     JSObject* holder,
+                                     Register receiver,
+                                     Register scratch1,
+                                     Register scratch2,
+                                     Register scratch3,
+                                     int index,
+                                     String* name,
+                                     Label* miss) {
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, miss);
+
+  // Check the prototype chain.
+  Register reg =
+      CheckPrototypes(object, receiver, holder,
+                      scratch1, scratch2, scratch3, name, miss);
+
+  // Get the value from the properties.
+  GenerateFastPropertyLoad(masm(), rax, reg, holder, index);
+  __ ret(0);
+}
+
+
+bool StubCompiler::GenerateLoadCallback(JSObject* object,
+                                        JSObject* holder,
+                                        Register receiver,
+                                        Register name_reg,
+                                        Register scratch1,
+                                        Register scratch2,
+                                        Register scratch3,
+                                        AccessorInfo* callback,
+                                        String* name,
+                                        Label* miss,
+                                        Failure** failure) {
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, miss);
+
+  // Check that the maps haven't changed.
+  Register reg =
+      CheckPrototypes(object, receiver, holder, scratch1,
+                      scratch2, scratch3, name, miss);
+
+  Handle<AccessorInfo> callback_handle(callback);
+
+  // Insert additional parameters into the stack frame above return address.
+  ASSERT(!scratch2.is(reg));
+  __ pop(scratch2);  // Get return address to place it below.
+
+  __ push(receiver);  // receiver
+  __ push(reg);  // holder
+  if (Heap::InNewSpace(callback_handle->data())) {
+    __ Move(scratch1, callback_handle);
+    __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));  // data
+  } else {
+    __ Push(Handle<Object>(callback_handle->data()));
+  }
+  __ push(name_reg);  // name
+  // Save a pointer to where we pushed the arguments pointer.
+  // This will be passed as the const AccessorInfo& to the C++ callback.
+
+#ifdef _WIN64
+  // Win64 uses first register--rcx--for returned value.
+  Register accessor_info_arg = r8;
+  Register name_arg = rdx;
+#else
+  Register accessor_info_arg = rsi;
+  Register name_arg = rdi;
+#endif
+
+  ASSERT(!name_arg.is(scratch2));
+  __ movq(name_arg, rsp);
+  __ push(scratch2);  // Restore return address.
+
+  // Do call through the api.
+  Address getter_address = v8::ToCData<Address>(callback->getter());
+  ApiFunction fun(getter_address);
+
+  // 3 elements array for v8::Agruments::values_ and handler for name.
+  const int kStackSpace = 4;
+
+  // Allocate v8::AccessorInfo in non-GCed stack space.
+  const int kArgStackSpace = 1;
+
+  __ PrepareCallApiFunction(kArgStackSpace);
+  __ lea(rax, Operand(name_arg, 3 * kPointerSize));
+
+  // v8::AccessorInfo::args_.
+  __ movq(StackSpaceOperand(0), rax);
+
+  // The context register (rsi) has been saved in PrepareCallApiFunction and
+  // could be used to pass arguments.
+  __ lea(accessor_info_arg, StackSpaceOperand(0));
+
+  // Emitting a stub call may try to allocate (if the code is not
+  // already generated).  Do not allow the assembler to perform a
+  // garbage collection but instead return the allocation failure
+  // object.
+  MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
+  if (result->IsFailure()) {
+    *failure = Failure::cast(result);
+    return false;
+  }
+  return true;
+}
+
+
+void StubCompiler::GenerateLoadConstant(JSObject* object,
+                                        JSObject* holder,
+                                        Register receiver,
+                                        Register scratch1,
+                                        Register scratch2,
+                                        Register scratch3,
+                                        Object* value,
+                                        String* name,
+                                        Label* miss) {
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, miss);
+
+  // Check that the maps haven't changed.
+  Register reg =
+      CheckPrototypes(object, receiver, holder,
+                      scratch1, scratch2, scratch3, name, miss);
+
+  // Return the constant value.
+  __ Move(rax, Handle<Object>(value));
+  __ ret(0);
+}
+
+
+void StubCompiler::GenerateLoadInterceptor(JSObject* object,
+                                           JSObject* interceptor_holder,
+                                           LookupResult* lookup,
+                                           Register receiver,
+                                           Register name_reg,
+                                           Register scratch1,
+                                           Register scratch2,
+                                           Register scratch3,
+                                           String* name,
+                                           Label* miss) {
+  ASSERT(interceptor_holder->HasNamedInterceptor());
+  ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
+
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, miss);
+
+  // So far the most popular follow ups for interceptor loads are FIELD
+  // and CALLBACKS, so inline only them, other cases may be added
+  // later.
+  bool compile_followup_inline = false;
+  if (lookup->IsProperty() && lookup->IsCacheable()) {
+    if (lookup->type() == FIELD) {
+      compile_followup_inline = true;
+    } else if (lookup->type() == CALLBACKS &&
+        lookup->GetCallbackObject()->IsAccessorInfo() &&
+        AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) {
+      compile_followup_inline = true;
+    }
+  }
+
+  if (compile_followup_inline) {
+    // Compile the interceptor call, followed by inline code to load the
+    // property from further up the prototype chain if the call fails.
+    // Check that the maps haven't changed.
+    Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder,
+                                          scratch1, scratch2, scratch3,
+                                          name, miss);
+    ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
+
+    // Save necessary data before invoking an interceptor.
+    // Requires a frame to make GC aware of pushed pointers.
+    __ EnterInternalFrame();
+
+    if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
+      // CALLBACKS case needs a receiver to be passed into C++ callback.
+      __ push(receiver);
+    }
+    __ push(holder_reg);
+    __ push(name_reg);
+
+    // Invoke an interceptor.  Note: map checks from receiver to
+    // interceptor's holder has been compiled before (see a caller
+    // of this method.)
+    CompileCallLoadPropertyWithInterceptor(masm(),
+                                           receiver,
+                                           holder_reg,
+                                           name_reg,
+                                           interceptor_holder);
+
+    // Check if interceptor provided a value for property.  If it's
+    // the case, return immediately.
+    Label interceptor_failed;
+    __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
+    __ j(equal, &interceptor_failed);
+    __ LeaveInternalFrame();
+    __ ret(0);
+
+    __ bind(&interceptor_failed);
+    __ pop(name_reg);
+    __ pop(holder_reg);
+    if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
+      __ pop(receiver);
+    }
+
+    __ LeaveInternalFrame();
+
+    // Check that the maps from interceptor's holder to lookup's holder
+    // haven't changed.  And load lookup's holder into |holder| register.
+    if (interceptor_holder != lookup->holder()) {
+      holder_reg = CheckPrototypes(interceptor_holder,
+                                   holder_reg,
+                                   lookup->holder(),
+                                   scratch1,
+                                   scratch2,
+                                   scratch3,
+                                   name,
+                                   miss);
+    }
+
+    if (lookup->type() == FIELD) {
+      // We found FIELD property in prototype chain of interceptor's holder.
+      // Retrieve a field from field's holder.
+      GenerateFastPropertyLoad(masm(), rax, holder_reg,
+                               lookup->holder(), lookup->GetFieldIndex());
+      __ ret(0);
+    } else {
+      // We found CALLBACKS property in prototype chain of interceptor's
+      // holder.
+      ASSERT(lookup->type() == CALLBACKS);
+      ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
+      AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
+      ASSERT(callback != NULL);
+      ASSERT(callback->getter() != NULL);
+
+      // Tail call to runtime.
+      // Important invariant in CALLBACKS case: the code above must be
+      // structured to never clobber |receiver| register.
+      __ pop(scratch2);  // return address
+      __ push(receiver);
+      __ push(holder_reg);
+      __ Move(holder_reg, Handle<AccessorInfo>(callback));
+      __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset));
+      __ push(holder_reg);
+      __ push(name_reg);
+      __ push(scratch2);  // restore return address
+
+      ExternalReference ref =
+          ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
+      __ TailCallExternalReference(ref, 5, 1);
+    }
+  } else {  // !compile_followup_inline
+    // Call the runtime system to load the interceptor.
+    // Check that the maps haven't changed.
+    Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder,
+                                          scratch1, scratch2, scratch3,
+                                          name, miss);
+    __ pop(scratch2);  // save old return address
+    PushInterceptorArguments(masm(), receiver, holder_reg,
+                             name_reg, interceptor_holder);
+    __ push(scratch2);  // restore old return address
+
+    ExternalReference ref = ExternalReference(
+        IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
+    __ TailCallExternalReference(ref, 5, 1);
+  }
+}
+
+
 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) {
   if (kind_ == Code::KEYED_CALL_IC) {
     __ Cmp(rcx, Handle<String>(name));
@@ -932,177 +1336,6 @@
 }
 
 
-MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
-                                                   JSObject* holder,
-                                                   JSFunction* function,
-                                                   String* name,
-                                                   CheckType check) {
-  // ----------- S t a t e -------------
-  // rcx                 : function name
-  // rsp[0]              : return address
-  // rsp[8]              : argument argc
-  // rsp[16]             : argument argc - 1
-  // ...
-  // rsp[argc * 8]       : argument 1
-  // rsp[(argc + 1) * 8] : argument 0 = receiver
-  // -----------------------------------
-
-  SharedFunctionInfo* function_info = function->shared();
-  if (function_info->HasBuiltinFunctionId()) {
-    BuiltinFunctionId id = function_info->builtin_function_id();
-    MaybeObject* maybe_result = CompileCustomCall(
-        id, object, holder,  NULL, function, name);
-    Object* result;
-    if (!maybe_result->ToObject(&result)) return maybe_result;
-    // undefined means bail out to regular compiler.
-    if (!result->IsUndefined()) return result;
-  }
-
-  Label miss_in_smi_check;
-
-  GenerateNameCheck(name, &miss_in_smi_check);
-
-  // Get the receiver from the stack.
-  const int argc = arguments().immediate();
-  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
-
-  // Check that the receiver isn't a smi.
-  if (check != NUMBER_CHECK) {
-    __ JumpIfSmi(rdx, &miss_in_smi_check);
-  }
-
-  // Make sure that it's okay not to patch the on stack receiver
-  // unless we're doing a receiver map check.
-  ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
-
-  CallOptimization optimization(function);
-  int depth = kInvalidProtoDepth;
-  Label miss;
-
-  switch (check) {
-    case RECEIVER_MAP_CHECK:
-      __ IncrementCounter(&Counters::call_const, 1);
-
-      if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
-        depth = optimization.GetPrototypeDepthOfExpectedType(
-            JSObject::cast(object), holder);
-      }
-
-      if (depth != kInvalidProtoDepth) {
-        __ IncrementCounter(&Counters::call_const_fast_api, 1);
-        // Allocate space for v8::Arguments implicit values. Must be initialized
-        // before to call any runtime function.
-        __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
-      }
-
-      // Check that the maps haven't changed.
-      CheckPrototypes(JSObject::cast(object), rdx, holder,
-                      rbx, rax, rdi, name, depth, &miss);
-
-      // Patch the receiver on the stack with the global proxy if
-      // necessary.
-      if (object->IsGlobalObject()) {
-        ASSERT(depth == kInvalidProtoDepth);
-        __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
-        __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
-      }
-      break;
-
-    case STRING_CHECK:
-      if (!function->IsBuiltin()) {
-        // Calling non-builtins with a value as receiver requires boxing.
-        __ jmp(&miss);
-      } else {
-        // Check that the object is a two-byte string or a symbol.
-        __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
-        __ j(above_equal, &miss);
-        // Check that the maps starting from the prototype haven't changed.
-        GenerateDirectLoadGlobalFunctionPrototype(
-            masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
-                        rbx, rdx, rdi, name, &miss);
-      }
-      break;
-
-    case NUMBER_CHECK: {
-      if (!function->IsBuiltin()) {
-        // Calling non-builtins with a value as receiver requires boxing.
-        __ jmp(&miss);
-      } else {
-        Label fast;
-        // Check that the object is a smi or a heap number.
-        __ JumpIfSmi(rdx, &fast);
-        __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
-        __ j(not_equal, &miss);
-        __ bind(&fast);
-        // Check that the maps starting from the prototype haven't changed.
-        GenerateDirectLoadGlobalFunctionPrototype(
-            masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
-                        rbx, rdx, rdi, name, &miss);
-      }
-      break;
-    }
-
-    case BOOLEAN_CHECK: {
-      if (!function->IsBuiltin()) {
-        // Calling non-builtins with a value as receiver requires boxing.
-        __ jmp(&miss);
-      } else {
-        Label fast;
-        // Check that the object is a boolean.
-        __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
-        __ j(equal, &fast);
-        __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
-        __ j(not_equal, &miss);
-        __ bind(&fast);
-        // Check that the maps starting from the prototype haven't changed.
-        GenerateDirectLoadGlobalFunctionPrototype(
-            masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
-        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
-                        rbx, rdx, rdi, name, &miss);
-      }
-      break;
-    }
-
-    default:
-      UNREACHABLE();
-  }
-
-  if (depth != kInvalidProtoDepth) {
-    Failure* failure;
-    // Move the return address on top of the stack.
-    __ movq(rax, Operand(rsp, 3 * kPointerSize));
-    __ movq(Operand(rsp, 0 * kPointerSize), rax);
-
-    // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains
-    // duplicate of return address and will be overwritten.
-    bool success = GenerateFastApiCall(masm(), optimization, argc, &failure);
-    if (!success) {
-      return failure;
-    }
-  } else {
-    __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
-  }
-
-  // Handle call cache miss.
-  __ bind(&miss);
-  if (depth != kInvalidProtoDepth) {
-    __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
-  }
-
-  // Handle call cache miss.
-  __ bind(&miss_in_smi_check);
-  Object* obj;
-  { MaybeObject* maybe_obj = GenerateMissBranch();
-    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-  }
-
-  // Return the generated code.
-  return GetCode(function);
-}
-
-
 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object,
                                                 JSObject* holder,
                                                 int index,
@@ -1248,8 +1481,7 @@
 
       __ InNewSpace(rbx, rcx, equal, &exit);
 
-      RecordWriteStub stub(rbx, rdx, rcx);
-      __ CallStub(&stub);
+      __ RecordWriteHelper(rbx, rdx, rcx);
 
       __ ret((argc + 1) * kPointerSize);
 
@@ -1408,6 +1640,79 @@
 }
 
 
+MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
+    Object* object,
+    JSObject* holder,
+    JSGlobalPropertyCell* cell,
+    JSFunction* function,
+    String* name) {
+  // ----------- S t a t e -------------
+  //  -- rcx                 : function name
+  //  -- rsp[0]              : return address
+  //  -- rsp[(argc - n) * 8] : arg[n] (zero-based)
+  //  -- ...
+  //  -- rsp[(argc + 1) * 8] : receiver
+  // -----------------------------------
+
+  // If object is not a string, bail out to regular call.
+  if (!object->IsString() || cell != NULL) return Heap::undefined_value();
+
+  const int argc = arguments().immediate();
+
+  Label miss;
+  Label index_out_of_range;
+
+  GenerateNameCheck(name, &miss);
+
+  // Check that the maps starting from the prototype haven't changed.
+  GenerateDirectLoadGlobalFunctionPrototype(masm(),
+                                            Context::STRING_FUNCTION_INDEX,
+                                            rax,
+                                            &miss);
+  ASSERT(object != holder);
+  CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
+                  rbx, rdx, rdi, name, &miss);
+
+  Register receiver = rbx;
+  Register index = rdi;
+  Register scratch = rdx;
+  Register result = rax;
+  __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
+  if (argc > 0) {
+    __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
+  } else {
+    __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
+  }
+
+  StringCharCodeAtGenerator char_code_at_generator(receiver,
+                                                   index,
+                                                   scratch,
+                                                   result,
+                                                   &miss,  // When not a string.
+                                                   &miss,  // When not a number.
+                                                   &index_out_of_range,
+                                                   STRING_INDEX_IS_NUMBER);
+  char_code_at_generator.GenerateFast(masm());
+  __ ret((argc + 1) * kPointerSize);
+
+  StubRuntimeCallHelper call_helper;
+  char_code_at_generator.GenerateSlow(masm(), call_helper);
+
+  __ bind(&index_out_of_range);
+  __ LoadRoot(rax, Heap::kNanValueRootIndex);
+  __ ret((argc + 1) * kPointerSize);
+
+  __ bind(&miss);
+  Object* obj;
+  { MaybeObject* maybe_obj = GenerateMissBranch();
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  }
+
+  // Return the generated code.
+  return GetCode(function);
+}
+
+
 MaybeObject* CallStubCompiler::CompileStringCharAtCall(
     Object* object,
     JSObject* holder,
@@ -1483,78 +1788,6 @@
 }
 
 
-MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
-    Object* object,
-    JSObject* holder,
-    JSGlobalPropertyCell* cell,
-    JSFunction* function,
-    String* name) {
-  // ----------- S t a t e -------------
-  //  -- rcx                 : function name
-  //  -- rsp[0]              : return address
-  //  -- rsp[(argc - n) * 8] : arg[n] (zero-based)
-  //  -- ...
-  //  -- rsp[(argc + 1) * 8] : receiver
-  // -----------------------------------
-
-  // If object is not a string, bail out to regular call.
-  if (!object->IsString() || cell != NULL) return Heap::undefined_value();
-
-  const int argc = arguments().immediate();
-
-  Label miss;
-  Label index_out_of_range;
-  GenerateNameCheck(name, &miss);
-
-  // Check that the maps starting from the prototype haven't changed.
-  GenerateDirectLoadGlobalFunctionPrototype(masm(),
-                                            Context::STRING_FUNCTION_INDEX,
-                                            rax,
-                                            &miss);
-  ASSERT(object != holder);
-  CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
-                  rbx, rdx, rdi, name, &miss);
-
-  Register receiver = rbx;
-  Register index = rdi;
-  Register scratch = rdx;
-  Register result = rax;
-  __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
-  if (argc > 0) {
-    __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
-  } else {
-    __ LoadRoot(index, Heap::kUndefinedValueRootIndex);
-  }
-
-  StringCharCodeAtGenerator char_code_at_generator(receiver,
-                                                   index,
-                                                   scratch,
-                                                   result,
-                                                   &miss,  // When not a string.
-                                                   &miss,  // When not a number.
-                                                   &index_out_of_range,
-                                                   STRING_INDEX_IS_NUMBER);
-  char_code_at_generator.GenerateFast(masm());
-  __ ret((argc + 1) * kPointerSize);
-
-  StubRuntimeCallHelper call_helper;
-  char_code_at_generator.GenerateSlow(masm(), call_helper);
-
-  __ bind(&index_out_of_range);
-  __ LoadRoot(rax, Heap::kNanValueRootIndex);
-  __ ret((argc + 1) * kPointerSize);
-
-  __ bind(&miss);
-  Object* obj;
-  { MaybeObject* maybe_obj = GenerateMissBranch();
-    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
-  }
-
-  // Return the generated code.
-  return GetCode(function);
-}
-
-
 MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
     Object* object,
     JSObject* holder,
@@ -1741,6 +1974,178 @@
 }
 
 
+MaybeObject* CallStubCompiler::CompileCallConstant(Object* object,
+                                                   JSObject* holder,
+                                                   JSFunction* function,
+                                                   String* name,
+                                                   CheckType check) {
+  // ----------- S t a t e -------------
+  // rcx                 : function name
+  // rsp[0]              : return address
+  // rsp[8]              : argument argc
+  // rsp[16]             : argument argc - 1
+  // ...
+  // rsp[argc * 8]       : argument 1
+  // rsp[(argc + 1) * 8] : argument 0 = receiver
+  // -----------------------------------
+
+  SharedFunctionInfo* function_info = function->shared();
+  if (function_info->HasBuiltinFunctionId()) {
+    BuiltinFunctionId id = function_info->builtin_function_id();
+    MaybeObject* maybe_result = CompileCustomCall(
+        id, object, holder,  NULL, function, name);
+    Object* result;
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+    // undefined means bail out to regular compiler.
+    if (!result->IsUndefined()) return result;
+  }
+
+  Label miss_in_smi_check;
+
+  GenerateNameCheck(name, &miss_in_smi_check);
+
+  // Get the receiver from the stack.
+  const int argc = arguments().immediate();
+  __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+
+  // Check that the receiver isn't a smi.
+  if (check != NUMBER_CHECK) {
+    __ JumpIfSmi(rdx, &miss_in_smi_check);
+  }
+
+  // Make sure that it's okay not to patch the on stack receiver
+  // unless we're doing a receiver map check.
+  ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
+
+  CallOptimization optimization(function);
+  int depth = kInvalidProtoDepth;
+  Label miss;
+
+  switch (check) {
+    case RECEIVER_MAP_CHECK:
+      __ IncrementCounter(&Counters::call_const, 1);
+
+      if (optimization.is_simple_api_call() && !object->IsGlobalObject()) {
+        depth = optimization.GetPrototypeDepthOfExpectedType(
+            JSObject::cast(object), holder);
+      }
+
+      if (depth != kInvalidProtoDepth) {
+        __ IncrementCounter(&Counters::call_const_fast_api, 1);
+
+        // Allocate space for v8::Arguments implicit values. Must be initialized
+        // before to call any runtime function.
+        __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
+      }
+
+      // Check that the maps haven't changed.
+      CheckPrototypes(JSObject::cast(object), rdx, holder,
+                      rbx, rax, rdi, name, depth, &miss);
+
+      // Patch the receiver on the stack with the global proxy if
+      // necessary.
+      if (object->IsGlobalObject()) {
+        ASSERT(depth == kInvalidProtoDepth);
+        __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
+        __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+      }
+      break;
+
+    case STRING_CHECK:
+      if (!function->IsBuiltin()) {
+        // Calling non-builtins with a value as receiver requires boxing.
+        __ jmp(&miss);
+      } else {
+        // Check that the object is a two-byte string or a symbol.
+        __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
+        __ j(above_equal, &miss);
+        // Check that the maps starting from the prototype haven't changed.
+        GenerateDirectLoadGlobalFunctionPrototype(
+            masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
+                        rbx, rdx, rdi, name, &miss);
+      }
+      break;
+
+    case NUMBER_CHECK: {
+      if (!function->IsBuiltin()) {
+        // Calling non-builtins with a value as receiver requires boxing.
+        __ jmp(&miss);
+      } else {
+        Label fast;
+        // Check that the object is a smi or a heap number.
+        __ JumpIfSmi(rdx, &fast);
+        __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
+        __ j(not_equal, &miss);
+        __ bind(&fast);
+        // Check that the maps starting from the prototype haven't changed.
+        GenerateDirectLoadGlobalFunctionPrototype(
+            masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
+                        rbx, rdx, rdi, name, &miss);
+      }
+      break;
+    }
+
+    case BOOLEAN_CHECK: {
+      if (!function->IsBuiltin()) {
+        // Calling non-builtins with a value as receiver requires boxing.
+        __ jmp(&miss);
+      } else {
+        Label fast;
+        // Check that the object is a boolean.
+        __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
+        __ j(equal, &fast);
+        __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
+        __ j(not_equal, &miss);
+        __ bind(&fast);
+        // Check that the maps starting from the prototype haven't changed.
+        GenerateDirectLoadGlobalFunctionPrototype(
+            masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
+        CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
+                        rbx, rdx, rdi, name, &miss);
+      }
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+  }
+
+  if (depth != kInvalidProtoDepth) {
+    Failure* failure;
+    // Move the return address on top of the stack.
+    __ movq(rax, Operand(rsp, 3 * kPointerSize));
+    __ movq(Operand(rsp, 0 * kPointerSize), rax);
+
+    // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains
+    // duplicate of return address and will be overwritten.
+    bool success = GenerateFastApiCall(masm(), optimization, argc, &failure);
+    if (!success) {
+      return failure;
+    }
+  } else {
+    __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+  }
+
+  // Handle call cache miss.
+  __ bind(&miss);
+  if (depth != kInvalidProtoDepth) {
+    __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
+  }
+
+  // Handle call cache miss.
+  __ bind(&miss_in_smi_check);
+  Object* obj;
+  { MaybeObject* maybe_obj = GenerateMissBranch();
+    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
+  }
+
+  // Return the generated code.
+  return GetCode(function);
+}
+
+
 MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
                                                       JSObject* holder,
                                                       String* name) {
@@ -1881,415 +2286,33 @@
 }
 
 
-MaybeObject* LoadStubCompiler::CompileLoadCallback(String* name,
-                                                   JSObject* object,
-                                                   JSObject* holder,
-                                                   AccessorInfo* callback) {
+MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object,
+                                                  int index,
+                                                  Map* transition,
+                                                  String* name) {
   // ----------- S t a t e -------------
-  //  -- rax    : receiver
+  //  -- rax    : value
   //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  Failure* failure = Failure::InternalError();
-  bool success = GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx, rdi,
-                                      callback, name, &miss, &failure);
-  if (!success) {
-    miss.Unuse();
-    return failure;
-  }
-
-  __ bind(&miss);
-  GenerateLoadMiss(masm(), Code::LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(CALLBACKS, name);
-}
-
-
-MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object,
-                                                   JSObject* holder,
-                                                   Object* value,
-                                                   String* name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss);
-  __ bind(&miss);
-  GenerateLoadMiss(masm(), Code::LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(CONSTANT_FUNCTION, name);
-}
-
-
-MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
-                                                      JSObject* object,
-                                                      JSObject* last) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  // Chech that receiver is not a smi.
-  __ JumpIfSmi(rax, &miss);
-
-  // Check the maps of the full prototype chain. Also check that
-  // global property cells up to (but not including) the last object
-  // in the prototype chain are empty.
-  CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss);
-
-  // If the last object in the prototype chain is a global object,
-  // check that the global property cell is empty.
-  if (last->IsGlobalObject()) {
-    MaybeObject* cell = GenerateCheckPropertyCell(masm(),
-                                                  GlobalObject::cast(last),
-                                                  name,
-                                                  rdx,
-                                                  &miss);
-    if (cell->IsFailure()) {
-      miss.Unuse();
-      return cell;
-    }
-  }
-
-  // Return undefined if maps of the full prototype chain are still the
-  // same and no global property with this name contains a value.
-  __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
-  __ ret(0);
-
-  __ bind(&miss);
-  GenerateLoadMiss(masm(), Code::LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(NONEXISTENT, Heap::empty_string());
-}
-
-
-MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object,
-                                                JSObject* holder,
-                                                int index,
-                                                String* name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss);
-  __ bind(&miss);
-  GenerateLoadMiss(masm(), Code::LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(FIELD, name);
-}
-
-
-MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
-                                                      JSObject* holder,
-                                                      String* name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  LookupResult lookup;
-  LookupPostInterceptor(holder, name, &lookup);
-
-  // TODO(368): Compile in the whole chain: all the interceptors in
-  // prototypes and ultimate answer.
-  GenerateLoadInterceptor(receiver,
-                          holder,
-                          &lookup,
-                          rax,
-                          rcx,
-                          rdx,
-                          rbx,
-                          rdi,
-                          name,
-                          &miss);
-
-  __ bind(&miss);
-  GenerateLoadMiss(masm(), Code::LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(INTERCEPTOR, name);
-}
-
-
-MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object,
-                                                 GlobalObject* holder,
-                                                 JSGlobalPropertyCell* cell,
-                                                 String* name,
-                                                 bool is_dont_delete) {
-  // ----------- S t a t e -------------
-  //  -- rax    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  // If the object is the holder then we know that it's a global
-  // object which can only happen for contextual loads. In this case,
-  // the receiver cannot be a smi.
-  if (object != holder) {
-    __ JumpIfSmi(rax, &miss);
-  }
-
-  // Check that the maps haven't changed.
-  CheckPrototypes(object, rax, holder, rbx, rdx, rdi, name, &miss);
-
-  // Get the value from the cell.
-  __ Move(rbx, Handle<JSGlobalPropertyCell>(cell));
-  __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset));
-
-  // Check for deleted property if property can actually be deleted.
-  if (!is_dont_delete) {
-    __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
-    __ j(equal, &miss);
-  } else if (FLAG_debug_code) {
-    __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
-    __ Check(not_equal, "DontDelete cells can't contain the hole");
-  }
-
-  __ IncrementCounter(&Counters::named_load_global_stub, 1);
-  __ movq(rax, rbx);
-  __ ret(0);
-
-  __ bind(&miss);
-  __ IncrementCounter(&Counters::named_load_global_stub_miss, 1);
-  GenerateLoadMiss(masm(), Code::LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(NORMAL, name);
-}
-
-
-MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
-    String* name,
-    JSObject* receiver,
-    JSObject* holder,
-    AccessorInfo* callback) {
-  // ----------- S t a t e -------------
-  //  -- rax     : key
-  //  -- rdx     : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  __ IncrementCounter(&Counters::keyed_load_callback, 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rax, Handle<String>(name));
-  __ j(not_equal, &miss);
-
-  Failure* failure = Failure::InternalError();
-  bool success = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, rdi,
-                                      callback, name, &miss, &failure);
-  if (!success) {
-    miss.Unuse();
-    return failure;
-  }
-
-  __ bind(&miss);
-  __ DecrementCounter(&Counters::keyed_load_callback, 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(CALLBACKS, name);
-}
-
-
-MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  __ IncrementCounter(&Counters::keyed_load_array_length, 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rax, Handle<String>(name));
-  __ j(not_equal, &miss);
-
-  GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
-  __ bind(&miss);
-  __ DecrementCounter(&Counters::keyed_load_array_length, 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(CALLBACKS, name);
-}
-
-
-MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
-                                                        JSObject* receiver,
-                                                        JSObject* holder,
-                                                        Object* value) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  __ IncrementCounter(&Counters::keyed_load_constant_function, 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rax, Handle<String>(name));
-  __ j(not_equal, &miss);
-
-  GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi,
-                       value, name, &miss);
-  __ bind(&miss);
-  __ DecrementCounter(&Counters::keyed_load_constant_function, 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(CONSTANT_FUNCTION, name);
-}
-
-
-MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  __ IncrementCounter(&Counters::keyed_load_function_prototype, 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rax, Handle<String>(name));
-  __ j(not_equal, &miss);
-
-  GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss);
-  __ bind(&miss);
-  __ DecrementCounter(&Counters::keyed_load_function_prototype, 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(CALLBACKS, name);
-}
-
-
-MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
-                                                           JSObject* holder,
-                                                           String* name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  __ IncrementCounter(&Counters::keyed_load_interceptor, 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rax, Handle<String>(name));
-  __ j(not_equal, &miss);
-
-  LookupResult lookup;
-  LookupPostInterceptor(holder, name, &lookup);
-  GenerateLoadInterceptor(receiver,
-                          holder,
-                          &lookup,
-                          rdx,
-                          rax,
-                          rcx,
-                          rbx,
-                          rdi,
-                          name,
-                          &miss);
-  __ bind(&miss);
-  __ DecrementCounter(&Counters::keyed_load_interceptor, 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(INTERCEPTOR, name);
-}
-
-
-MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
   //  -- rdx    : receiver
   //  -- rsp[0] : return address
   // -----------------------------------
   Label miss;
 
-  __ IncrementCounter(&Counters::keyed_load_string_length, 1);
+  // Generate store field code.  Preserves receiver and name on jump to miss.
+  GenerateStoreField(masm(),
+                     object,
+                     index,
+                     transition,
+                     rdx, rcx, rbx,
+                     &miss);
 
-  // Check that the name has not changed.
-  __ Cmp(rax, Handle<String>(name));
-  __ j(not_equal, &miss);
-
-  GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss);
+  // Handle store cache miss.
   __ bind(&miss);
-  __ DecrementCounter(&Counters::keyed_load_string_length, 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
+  __ Jump(ic, RelocInfo::CODE_TARGET);
 
   // Return the generated code.
-  return GetCode(CALLBACKS, name);
-}
-
-
-MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
-  // ----------- S t a t e -------------
-  //  -- rax    : key
-  //  -- rdx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  Label miss;
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(rdx, &miss);
-
-  // Check that the map matches.
-  __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
-         Handle<Map>(receiver->map()));
-  __ j(not_equal, &miss);
-
-  // Check that the key is a smi.
-  __ JumpIfNotSmi(rax, &miss);
-
-  // Get the elements array.
-  __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
-  __ AssertFastElements(rcx);
-
-  // Check that the key is within bounds.
-  __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset));
-  __ j(above_equal, &miss);
-
-  // Load the result and make sure it's not the hole.
-  SmiIndex index = masm()->SmiToIndex(rbx, rax, kPointerSizeLog2);
-  __ movq(rbx, FieldOperand(rcx,
-                            index.reg,
-                            index.scale,
-                            FixedArray::kHeaderSize));
-  __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
-  __ j(equal, &miss);
-  __ movq(rax, rbx);
-  __ ret(0);
-
-  __ bind(&miss);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(NORMAL, NULL);
+  return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
 }
 
 
@@ -2343,36 +2366,6 @@
 }
 
 
-MaybeObject* StoreStubCompiler::CompileStoreField(JSObject* object,
-                                                  int index,
-                                                  Map* transition,
-                                                  String* 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,
-                     rdx, rcx, rbx,
-                     &miss);
-
-  // Handle store cache miss.
-  __ bind(&miss);
-  Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss));
-  __ Jump(ic, RelocInfo::CODE_TARGET);
-
-  // Return the generated code.
-  return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
-}
-
-
 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
                                                         String* name) {
   // ----------- S t a t e -------------
@@ -2456,34 +2449,6 @@
 }
 
 
-MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name,
-                                                     JSObject* receiver,
-                                                     JSObject* holder,
-                                                     int index) {
-  // ----------- S t a t e -------------
-  //  -- rax     : key
-  //  -- rdx     : receiver
-  //  -- rsp[0]  : return address
-  // -----------------------------------
-  Label miss;
-
-  __ IncrementCounter(&Counters::keyed_load_field, 1);
-
-  // Check that the name has not changed.
-  __ Cmp(rax, Handle<String>(name));
-  __ j(not_equal, &miss);
-
-  GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss);
-
-  __ bind(&miss);
-  __ DecrementCounter(&Counters::keyed_load_field, 1);
-  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
-
-  // Return the generated code.
-  return GetCode(FIELD, name);
-}
-
-
 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
                                                        int index,
                                                        Map* transition,
@@ -2578,414 +2543,444 @@
 }
 
 
-void StubCompiler::GenerateLoadInterceptor(JSObject* object,
-                                           JSObject* interceptor_holder,
-                                           LookupResult* lookup,
-                                           Register receiver,
-                                           Register name_reg,
-                                           Register scratch1,
-                                           Register scratch2,
-                                           Register scratch3,
-                                           String* name,
-                                           Label* miss) {
-  ASSERT(interceptor_holder->HasNamedInterceptor());
-  ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
+MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
+                                                      JSObject* object,
+                                                      JSObject* last) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
 
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, miss);
+  // Chech that receiver is not a smi.
+  __ JumpIfSmi(rax, &miss);
 
-  // So far the most popular follow ups for interceptor loads are FIELD
-  // and CALLBACKS, so inline only them, other cases may be added
-  // later.
-  bool compile_followup_inline = false;
-  if (lookup->IsProperty() && lookup->IsCacheable()) {
-    if (lookup->type() == FIELD) {
-      compile_followup_inline = true;
-    } else if (lookup->type() == CALLBACKS &&
-        lookup->GetCallbackObject()->IsAccessorInfo() &&
-        AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) {
-      compile_followup_inline = true;
+  // Check the maps of the full prototype chain. Also check that
+  // global property cells up to (but not including) the last object
+  // in the prototype chain are empty.
+  CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss);
+
+  // If the last object in the prototype chain is a global object,
+  // check that the global property cell is empty.
+  if (last->IsGlobalObject()) {
+    MaybeObject* cell = GenerateCheckPropertyCell(masm(),
+                                                  GlobalObject::cast(last),
+                                                  name,
+                                                  rdx,
+                                                  &miss);
+    if (cell->IsFailure()) {
+      miss.Unuse();
+      return cell;
     }
   }
 
-  if (compile_followup_inline) {
-    // Compile the interceptor call, followed by inline code to load the
-    // property from further up the prototype chain if the call fails.
-    // Check that the maps haven't changed.
-    Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder,
-                                          scratch1, scratch2, scratch3,
-                                          name, miss);
-    ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1));
+  // Return undefined if maps of the full prototype chain are still the
+  // same and no global property with this name contains a value.
+  __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
+  __ ret(0);
 
-    // Save necessary data before invoking an interceptor.
-    // Requires a frame to make GC aware of pushed pointers.
-    __ EnterInternalFrame();
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
 
-    if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
-      // CALLBACKS case needs a receiver to be passed into C++ callback.
-      __ push(receiver);
-    }
-    __ push(holder_reg);
-    __ push(name_reg);
-
-    // Invoke an interceptor.  Note: map checks from receiver to
-    // interceptor's holder has been compiled before (see a caller
-    // of this method.)
-    CompileCallLoadPropertyWithInterceptor(masm(),
-                                           receiver,
-                                           holder_reg,
-                                           name_reg,
-                                           interceptor_holder);
-
-    // Check if interceptor provided a value for property.  If it's
-    // the case, return immediately.
-    Label interceptor_failed;
-    __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
-    __ j(equal, &interceptor_failed);
-    __ LeaveInternalFrame();
-    __ ret(0);
-
-    __ bind(&interceptor_failed);
-    __ pop(name_reg);
-    __ pop(holder_reg);
-    if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) {
-      __ pop(receiver);
-    }
-
-    __ LeaveInternalFrame();
-
-    // Check that the maps from interceptor's holder to lookup's holder
-    // haven't changed.  And load lookup's holder into |holder| register.
-    if (interceptor_holder != lookup->holder()) {
-      holder_reg = CheckPrototypes(interceptor_holder,
-                                   holder_reg,
-                                   lookup->holder(),
-                                   scratch1,
-                                   scratch2,
-                                   scratch3,
-                                   name,
-                                   miss);
-    }
-
-    if (lookup->type() == FIELD) {
-      // We found FIELD property in prototype chain of interceptor's holder.
-      // Retrieve a field from field's holder.
-      GenerateFastPropertyLoad(masm(), rax, holder_reg,
-                               lookup->holder(), lookup->GetFieldIndex());
-      __ ret(0);
-    } else {
-      // We found CALLBACKS property in prototype chain of interceptor's
-      // holder.
-      ASSERT(lookup->type() == CALLBACKS);
-      ASSERT(lookup->GetCallbackObject()->IsAccessorInfo());
-      AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
-      ASSERT(callback != NULL);
-      ASSERT(callback->getter() != NULL);
-
-      // Tail call to runtime.
-      // Important invariant in CALLBACKS case: the code above must be
-      // structured to never clobber |receiver| register.
-      __ pop(scratch2);  // return address
-      __ push(receiver);
-      __ push(holder_reg);
-      __ Move(holder_reg, Handle<AccessorInfo>(callback));
-      __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset));
-      __ push(holder_reg);
-      __ push(name_reg);
-      __ push(scratch2);  // restore return address
-
-      ExternalReference ref =
-          ExternalReference(IC_Utility(IC::kLoadCallbackProperty));
-      __ TailCallExternalReference(ref, 5, 1);
-    }
-  } else {  // !compile_followup_inline
-    // Call the runtime system to load the interceptor.
-    // Check that the maps haven't changed.
-    Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder,
-                                          scratch1, scratch2, scratch3,
-                                          name, miss);
-    __ pop(scratch2);  // save old return address
-    PushInterceptorArguments(masm(), receiver, holder_reg,
-                             name_reg, interceptor_holder);
-    __ push(scratch2);  // restore old return address
-
-    ExternalReference ref = ExternalReference(
-        IC_Utility(IC::kLoadPropertyWithInterceptorForLoad));
-    __ TailCallExternalReference(ref, 5, 1);
-  }
+  // Return the generated code.
+  return GetCode(NONEXISTENT, Heap::empty_string());
 }
 
 
-bool StubCompiler::GenerateLoadCallback(JSObject* object,
-                                        JSObject* holder,
-                                        Register receiver,
-                                        Register name_reg,
-                                        Register scratch1,
-                                        Register scratch2,
-                                        Register scratch3,
-                                        AccessorInfo* callback,
-                                        String* name,
-                                        Label* miss,
-                                        Failure** failure) {
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, miss);
+MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object,
+                                                JSObject* holder,
+                                                int index,
+                                                String* name) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss);
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(FIELD, name);
+}
+
+
+MaybeObject* LoadStubCompiler::CompileLoadCallback(String* name,
+                                                   JSObject* object,
+                                                   JSObject* holder,
+                                                   AccessorInfo* callback) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  Failure* failure = Failure::InternalError();
+  bool success = GenerateLoadCallback(object, holder, rax, rcx, rdx, rbx, rdi,
+                                      callback, name, &miss, &failure);
+  if (!success) {
+    miss.Unuse();
+    return failure;
+  }
+
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(CALLBACKS, name);
+}
+
+
+MaybeObject* LoadStubCompiler::CompileLoadConstant(JSObject* object,
+                                                   JSObject* holder,
+                                                   Object* value,
+                                                   String* name) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss);
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(CONSTANT_FUNCTION, name);
+}
+
+
+MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
+                                                      JSObject* holder,
+                                                      String* name) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  LookupResult lookup;
+  LookupPostInterceptor(holder, name, &lookup);
+
+  // TODO(368): Compile in the whole chain: all the interceptors in
+  // prototypes and ultimate answer.
+  GenerateLoadInterceptor(receiver,
+                          holder,
+                          &lookup,
+                          rax,
+                          rcx,
+                          rdx,
+                          rbx,
+                          rdi,
+                          name,
+                          &miss);
+
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(INTERCEPTOR, name);
+}
+
+
+MaybeObject* LoadStubCompiler::CompileLoadGlobal(JSObject* object,
+                                                 GlobalObject* holder,
+                                                 JSGlobalPropertyCell* cell,
+                                                 String* name,
+                                                 bool is_dont_delete) {
+  // ----------- S t a t e -------------
+  //  -- rax    : receiver
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  // If the object is the holder then we know that it's a global
+  // object which can only happen for contextual loads. In this case,
+  // the receiver cannot be a smi.
+  if (object != holder) {
+    __ JumpIfSmi(rax, &miss);
+  }
 
   // Check that the maps haven't changed.
-  Register reg =
-      CheckPrototypes(object, receiver, holder, scratch1,
-                      scratch2, scratch3, name, miss);
+  CheckPrototypes(object, rax, holder, rbx, rdx, rdi, name, &miss);
 
-  Handle<AccessorInfo> callback_handle(callback);
+  // Get the value from the cell.
+  __ Move(rbx, Handle<JSGlobalPropertyCell>(cell));
+  __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset));
 
-  // Insert additional parameters into the stack frame above return address.
-  ASSERT(!scratch2.is(reg));
-  __ pop(scratch2);  // Get return address to place it below.
-
-  __ push(receiver);  // receiver
-  __ push(reg);  // holder
-  if (Heap::InNewSpace(callback_handle->data())) {
-    __ Move(scratch1, callback_handle);
-    __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));  // data
-  } else {
-    __ Push(Handle<Object>(callback_handle->data()));
-  }
-  __ push(name_reg);  // name
-  // Save a pointer to where we pushed the arguments pointer.
-  // This will be passed as the const AccessorInfo& to the C++ callback.
-
-#ifdef _WIN64
-  // Win64 uses first register--rcx--for returned value.
-  Register accessor_info_arg = r8;
-  Register name_arg = rdx;
-#else
-  Register accessor_info_arg = rsi;
-  Register name_arg = rdi;
-#endif
-
-  ASSERT(!name_arg.is(scratch2));
-  __ movq(name_arg, rsp);
-  __ push(scratch2);  // Restore return address.
-
-  // Do call through the api.
-  Address getter_address = v8::ToCData<Address>(callback->getter());
-  ApiFunction fun(getter_address);
-
-  // 3 elements array for v8::Agruments::values_ and handler for name.
-  const int kStackSpace = 4;
-
-  // Allocate v8::AccessorInfo in non-GCed stack space.
-  const int kArgStackSpace = 1;
-
-  __ PrepareCallApiFunction(kArgStackSpace);
-  __ lea(rax, Operand(name_arg, 3 * kPointerSize));
-
-  // v8::AccessorInfo::args_.
-  __ movq(StackSpaceOperand(0), rax);
-
-  // The context register (rsi) has been saved in PrepareCallApiFunction and
-  // could be used to pass arguments.
-  __ lea(accessor_info_arg, StackSpaceOperand(0));
-
-  // Emitting a stub call may try to allocate (if the code is not
-  // already generated).  Do not allow the assembler to perform a
-  // garbage collection but instead return the allocation failure
-  // object.
-  MaybeObject* result = masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
-  if (result->IsFailure()) {
-    *failure = Failure::cast(result);
-    return false;
-  }
-  return true;
-}
-
-
-Register StubCompiler::CheckPrototypes(JSObject* object,
-                                       Register object_reg,
-                                       JSObject* holder,
-                                       Register holder_reg,
-                                       Register scratch1,
-                                       Register scratch2,
-                                       String* name,
-                                       int save_at_depth,
-                                       Label* miss) {
-  // Make sure there's no overlap between holder and object registers.
-  ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
-  ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
-         && !scratch2.is(scratch1));
-
-  // Keep track of the current object in register reg.  On the first
-  // iteration, reg is an alias for object_reg, on later iterations,
-  // it is an alias for holder_reg.
-  Register reg = object_reg;
-  int depth = 0;
-
-  if (save_at_depth == depth) {
-    __ movq(Operand(rsp, kPointerSize), object_reg);
+  // Check for deleted property if property can actually be deleted.
+  if (!is_dont_delete) {
+    __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
+    __ j(equal, &miss);
+  } else if (FLAG_debug_code) {
+    __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
+    __ Check(not_equal, "DontDelete cells can't contain the hole");
   }
 
-  // Check the maps in the prototype chain.
-  // Traverse the prototype chain from the object and do map checks.
-  JSObject* current = object;
-  while (current != holder) {
-    depth++;
-
-    // Only global objects and objects that do not require access
-    // checks are allowed in stubs.
-    ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
-
-    JSObject* prototype = JSObject::cast(current->GetPrototype());
-    if (!current->HasFastProperties() &&
-        !current->IsJSGlobalObject() &&
-        !current->IsJSGlobalProxy()) {
-      if (!name->IsSymbol()) {
-        MaybeObject* lookup_result = Heap::LookupSymbol(name);
-        if (lookup_result->IsFailure()) {
-          set_failure(Failure::cast(lookup_result));
-          return reg;
-        } else {
-          name = String::cast(lookup_result->ToObjectUnchecked());
-        }
-      }
-      ASSERT(current->property_dictionary()->FindEntry(name) ==
-             StringDictionary::kNotFound);
-
-      GenerateDictionaryNegativeLookup(masm(),
-                                       miss,
-                                       reg,
-                                       name,
-                                       scratch1,
-                                       scratch2);
-      __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      reg = holder_reg;  // from now the object is in holder_reg
-      __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-    } else if (Heap::InNewSpace(prototype)) {
-      // Get the map of the current object.
-      __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      __ Cmp(scratch1, Handle<Map>(current->map()));
-      // Branch on the result of the map check.
-      __ j(not_equal, miss);
-      // Check access rights to the global object.  This has to happen
-      // after the map check so that we know that the object is
-      // actually a global object.
-      if (current->IsJSGlobalProxy()) {
-        __ CheckAccessGlobalProxy(reg, scratch1, miss);
-
-        // Restore scratch register to be the map of the object.
-        // We load the prototype from the map in the scratch register.
-        __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      }
-      // The prototype is in new space; we cannot store a reference
-      // to it in the code. Load it from the map.
-      reg = holder_reg;  // from now the object is in holder_reg
-      __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-
-    } else {
-      // Check the map of the current object.
-      __ Cmp(FieldOperand(reg, HeapObject::kMapOffset),
-          Handle<Map>(current->map()));
-      // Branch on the result of the map check.
-      __ j(not_equal, miss);
-      // Check access rights to the global object.  This has to happen
-      // after the map check so that we know that the object is
-      // actually a global object.
-      if (current->IsJSGlobalProxy()) {
-        __ CheckAccessGlobalProxy(reg, scratch1, miss);
-      }
-      // The prototype is in old space; load it directly.
-      reg = holder_reg;  // from now the object is in holder_reg
-      __ Move(reg, Handle<JSObject>(prototype));
-    }
-
-    if (save_at_depth == depth) {
-      __ movq(Operand(rsp, kPointerSize), reg);
-    }
-
-    // Go to the next object in the prototype chain.
-    current = prototype;
-  }
-
-  // Check the holder map.
-  __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map()));
-  __ j(not_equal, miss);
-
-  // Log the check depth.
-  LOG(IntEvent("check-maps-depth", depth + 1));
-
-  // Perform security check for access to the global object and return
-  // the holder register.
-  ASSERT(current == holder);
-  ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
-  if (current->IsJSGlobalProxy()) {
-    __ CheckAccessGlobalProxy(reg, scratch1, miss);
-  }
-
-  // If we've skipped any global objects, it's not enough to verify
-  // that their maps haven't changed.  We also need to check that the
-  // property cell for the property is still empty.
-  current = object;
-  while (current != holder) {
-    if (current->IsGlobalObject()) {
-      MaybeObject* cell = GenerateCheckPropertyCell(masm(),
-                                                    GlobalObject::cast(current),
-                                                    name,
-                                                    scratch1,
-                                                    miss);
-      if (cell->IsFailure()) {
-        set_failure(Failure::cast(cell));
-        return reg;
-      }
-    }
-    current = JSObject::cast(current->GetPrototype());
-  }
-
-  // Return the register containing the holder.
-  return reg;
-}
-
-
-void StubCompiler::GenerateLoadField(JSObject* object,
-                                     JSObject* holder,
-                                     Register receiver,
-                                     Register scratch1,
-                                     Register scratch2,
-                                     Register scratch3,
-                                     int index,
-                                     String* name,
-                                     Label* miss) {
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, miss);
-
-  // Check the prototype chain.
-  Register reg =
-      CheckPrototypes(object, receiver, holder,
-                      scratch1, scratch2, scratch3, name, miss);
-
-  // Get the value from the properties.
-  GenerateFastPropertyLoad(masm(), rax, reg, holder, index);
+  __ IncrementCounter(&Counters::named_load_global_stub, 1);
+  __ movq(rax, rbx);
   __ ret(0);
+
+  __ bind(&miss);
+  __ IncrementCounter(&Counters::named_load_global_stub_miss, 1);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(NORMAL, name);
 }
 
 
-void StubCompiler::GenerateLoadConstant(JSObject* object,
-                                        JSObject* holder,
-                                        Register receiver,
-                                        Register scratch1,
-                                        Register scratch2,
-                                        Register scratch3,
-                                        Object* value,
-                                        String* name,
-                                        Label* miss) {
+MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name,
+                                                     JSObject* receiver,
+                                                     JSObject* holder,
+                                                     int index) {
+  // ----------- S t a t e -------------
+  //  -- rax     : key
+  //  -- rdx     : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label miss;
+
+  __ IncrementCounter(&Counters::keyed_load_field, 1);
+
+  // Check that the name has not changed.
+  __ Cmp(rax, Handle<String>(name));
+  __ j(not_equal, &miss);
+
+  GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss);
+
+  __ bind(&miss);
+  __ DecrementCounter(&Counters::keyed_load_field, 1);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(FIELD, name);
+}
+
+
+MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
+    String* name,
+    JSObject* receiver,
+    JSObject* holder,
+    AccessorInfo* callback) {
+  // ----------- S t a t e -------------
+  //  -- rax     : key
+  //  -- rdx     : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label miss;
+
+  __ IncrementCounter(&Counters::keyed_load_callback, 1);
+
+  // Check that the name has not changed.
+  __ Cmp(rax, Handle<String>(name));
+  __ j(not_equal, &miss);
+
+  Failure* failure = Failure::InternalError();
+  bool success = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, rdi,
+                                      callback, name, &miss, &failure);
+  if (!success) {
+    miss.Unuse();
+    return failure;
+  }
+
+  __ bind(&miss);
+
+  __ DecrementCounter(&Counters::keyed_load_callback, 1);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(CALLBACKS, name);
+}
+
+
+MaybeObject* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
+                                                        JSObject* receiver,
+                                                        JSObject* holder,
+                                                        Object* value) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label miss;
+
+  __ IncrementCounter(&Counters::keyed_load_constant_function, 1);
+
+  // Check that the name has not changed.
+  __ Cmp(rax, Handle<String>(name));
+  __ j(not_equal, &miss);
+
+  GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi,
+                       value, name, &miss);
+  __ bind(&miss);
+  __ DecrementCounter(&Counters::keyed_load_constant_function, 1);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(CONSTANT_FUNCTION, name);
+}
+
+
+MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
+                                                           JSObject* holder,
+                                                           String* name) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label miss;
+
+  __ IncrementCounter(&Counters::keyed_load_interceptor, 1);
+
+  // Check that the name has not changed.
+  __ Cmp(rax, Handle<String>(name));
+  __ j(not_equal, &miss);
+
+  LookupResult lookup;
+  LookupPostInterceptor(holder, name, &lookup);
+  GenerateLoadInterceptor(receiver,
+                          holder,
+                          &lookup,
+                          rdx,
+                          rax,
+                          rcx,
+                          rbx,
+                          rdi,
+                          name,
+                          &miss);
+  __ bind(&miss);
+  __ DecrementCounter(&Counters::keyed_load_interceptor, 1);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(INTERCEPTOR, name);
+}
+
+
+MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label miss;
+
+  __ IncrementCounter(&Counters::keyed_load_array_length, 1);
+
+  // Check that the name has not changed.
+  __ Cmp(rax, Handle<String>(name));
+  __ j(not_equal, &miss);
+
+  GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
+  __ bind(&miss);
+  __ DecrementCounter(&Counters::keyed_load_array_length, 1);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(CALLBACKS, name);
+}
+
+
+MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  __ IncrementCounter(&Counters::keyed_load_string_length, 1);
+
+  // Check that the name has not changed.
+  __ Cmp(rax, Handle<String>(name));
+  __ j(not_equal, &miss);
+
+  GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss);
+  __ bind(&miss);
+  __ DecrementCounter(&Counters::keyed_load_string_length, 1);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(CALLBACKS, name);
+}
+
+
+MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- rsp[0]  : return address
+  // -----------------------------------
+  Label miss;
+
+  __ IncrementCounter(&Counters::keyed_load_function_prototype, 1);
+
+  // Check that the name has not changed.
+  __ Cmp(rax, Handle<String>(name));
+  __ j(not_equal, &miss);
+
+  GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss);
+  __ bind(&miss);
+  __ DecrementCounter(&Counters::keyed_load_function_prototype, 1);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(CALLBACKS, name);
+}
+
+
+MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) {
+  // ----------- S t a t e -------------
+  //  -- rax    : key
+  //  -- rdx    : receiver
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label miss;
+
   // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, miss);
+  __ JumpIfSmi(rdx, &miss);
 
-  // Check that the maps haven't changed.
-  Register reg =
-      CheckPrototypes(object, receiver, holder,
-                      scratch1, scratch2, scratch3, name, miss);
+  // Check that the map matches.
+  __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
+         Handle<Map>(receiver->map()));
+  __ j(not_equal, &miss);
 
-  // Return the constant value.
-  __ Move(rax, Handle<Object>(value));
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(rax, &miss);
+
+  // Get the elements array.
+  __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
+  __ AssertFastElements(rcx);
+
+  // Check that the key is within bounds.
+  __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset));
+  __ j(above_equal, &miss);
+
+  // Load the result and make sure it's not the hole.
+  SmiIndex index = masm()->SmiToIndex(rbx, rax, kPointerSizeLog2);
+  __ movq(rbx, FieldOperand(rcx,
+                            index.reg,
+                            index.scale,
+                            FixedArray::kHeaderSize));
+  __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
+  __ j(equal, &miss);
+  __ movq(rax, rbx);
   __ ret(0);
+
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(NORMAL, NULL);
 }