Update V8 to r6190 as required by WebKit r75315

Change-Id: I0b2f598e4d8748df417ad350fc47a1c465ad1fef
diff --git a/ChangeLog b/ChangeLog
index c81d7a7..c89ec31 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2010-01-05: 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).
+
+
+2011-01-03: Version 3.0.5
+
+        Fixed a couple of cast errors for gcc-3.4.3.
+
+        Performance improvements in GC and IA32 code generator.
+
+
 2010-12-21: Version 3.0.4
 
         Added Date::ResetCache() to the API so that the cached values in the
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index afd88f3..e9ea659 100644
--- a/V8_MERGE_REVISION
+++ b/V8_MERGE_REVISION
@@ -1,5 +1,7 @@
 We use a V8 revision that has been used for a Chromium release.
 
-http://src.chromium.org/svn/releases/10.0.621.0/DEPS
-http://v8.googlecode.com/svn/trunk@6101 (+ 1 cherry pick from r6346 in src/v8utils.h to fix compile on Android)
+http://src.chromium.org/svn/releases/10.0.634.0/DEPS
+http://v8.googlecode.com/svn/trunk@6190 plus two partial cherry-picks to fix Android build ...
+- r6346 - include platform.h in src/v8utils.h
+- r7077 - CreateThread() in src/platform-linux.cc
 
diff --git a/include/v8.h b/include/v8.h
index 2c0f350..883bfad 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -1651,9 +1651,9 @@
    *       the backing store is preserved while V8 has a reference.
    */
   V8EXPORT void SetIndexedPropertiesToPixelData(uint8_t* data, int length);
-  bool HasIndexedPropertiesInPixelData();
-  uint8_t* GetIndexedPropertiesPixelData();
-  int GetIndexedPropertiesPixelDataLength();
+  V8EXPORT bool HasIndexedPropertiesInPixelData();
+  V8EXPORT uint8_t* GetIndexedPropertiesPixelData();
+  V8EXPORT int GetIndexedPropertiesPixelDataLength();
 
   /**
    * Set the backing store of the indexed properties to be managed by the
@@ -1666,10 +1666,10 @@
       void* data,
       ExternalArrayType array_type,
       int number_of_elements);
-  bool HasIndexedPropertiesInExternalArrayData();
-  void* GetIndexedPropertiesExternalArrayData();
-  ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
-  int GetIndexedPropertiesExternalArrayDataLength();
+  V8EXPORT bool HasIndexedPropertiesInExternalArrayData();
+  V8EXPORT void* GetIndexedPropertiesExternalArrayData();
+  V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType();
+  V8EXPORT int GetIndexedPropertiesExternalArrayDataLength();
 
   V8EXPORT static Local<Object> New();
   static inline Object* Cast(Value* obj);
@@ -3076,6 +3076,18 @@
    * Returns a persistent handle to the newly allocated context. This
    * persistent handle has to be disposed when the context is no
    * longer used so the context can be garbage collected.
+   *
+   * \param extensions An optional extension configuration containing
+   * the extensions to be installed in the newly created context.
+   *
+   * \param global_template An optional object template from which the
+   * global object for the newly created context will be created.
+   *
+   * \param global_object An optional global object to be reused for
+   * the newly created context. This global object must have been
+   * created by a previous call to Context::New with the same global
+   * template. The state of the global object will be completely reset
+   * and only object identify will remain.
    */
   static Persistent<Context> New(
       ExtensionConfiguration* extensions = NULL,
diff --git a/src/SConscript b/src/SConscript
index dfa099c..b1f9bb6 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -229,9 +229,10 @@
   'os:win32':   ['platform-win32.cc'],
   'mode:release': [],
   'mode:debug': [
-    'objects-debug.cc', 'prettyprinter.cc', 'regexp-macro-assembler-tracer.cc'
+    'objects-debug.cc', 'objects-printer.cc', 'prettyprinter.cc',
+    'regexp-macro-assembler-tracer.cc'
   ],
-  'objectprint:on': ['objects-debug.cc']
+  'objectprint:on': ['objects-printer.cc']
 }
 
 
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 36f7507..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 5ec8584..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.
@@ -2894,45 +2894,45 @@
 
 
 // Uses registers r0 to r4. Expected input is
-// function in r0 (or at sp+1*ptrsz) and object in
+// object in r0 (or at sp+1*kPointerSize) and function in
 // r1 (or at sp), depending on whether or not
 // args_in_registers() is true.
 void InstanceofStub::Generate(MacroAssembler* masm) {
   // Fixed register usage throughout the stub:
-  const Register object = r1;  // Object (lhs).
+  const Register object = r0;  // Object (lhs).
   const Register map = r3;  // Map of the object.
-  const Register function = r0;  // Function (rhs).
+  const Register function = r1;  // Function (rhs).
   const Register prototype = r4;  // Prototype of the function.
   const Register scratch = r2;
   Label slow, loop, is_instance, is_not_instance, not_js_object;
   if (!args_in_registers()) {
-    __ ldr(function, MemOperand(sp, 1 * kPointerSize));
-    __ ldr(object, MemOperand(sp, 0));
+    __ ldr(object, MemOperand(sp, 1 * kPointerSize));
+    __ ldr(function, MemOperand(sp, 0));
   }
 
   // Check that the left hand is a JS object and load map.
-  __ BranchOnSmi(object, &slow);
-  __ IsObjectJSObjectType(object, map, scratch, &slow);
+  __ BranchOnSmi(object, &not_js_object);
+  __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
 
   // Look up the function and the map in the instanceof cache.
   Label miss;
   __ LoadRoot(ip, Heap::kInstanceofCacheFunctionRootIndex);
-  __ cmp(object, ip);
+  __ cmp(function, ip);
   __ b(ne, &miss);
   __ LoadRoot(ip, Heap::kInstanceofCacheMapRootIndex);
   __ cmp(map, ip);
   __ b(ne, &miss);
-  __ LoadRoot(function, Heap::kInstanceofCacheAnswerRootIndex);
+  __ LoadRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
   __ Ret(args_in_registers() ? 0 : 2);
 
   __ bind(&miss);
-  __ TryGetFunctionPrototype(object, prototype, scratch, &slow);
+  __ TryGetFunctionPrototype(function, prototype, scratch, &slow);
 
   // Check that the function prototype is a JS object.
   __ BranchOnSmi(prototype, &slow);
   __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
 
-  __ StoreRoot(object, Heap::kInstanceofCacheFunctionRootIndex);
+  __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
   __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex);
 
   // Register mapping: r3 is object map and r4 is function prototype.
@@ -2957,6 +2957,7 @@
 
   __ bind(&is_not_instance);
   __ mov(r0, Operand(Smi::FromInt(1)));
+  __ StoreRoot(r0, Heap::kInstanceofCacheAnswerRootIndex);
   __ Ret(args_in_registers() ? 0 : 2);
 
   Label object_not_null, object_not_null_or_smi;
@@ -2986,6 +2987,9 @@
   __ Ret(args_in_registers() ? 0 : 2);
 
   // Slow-case.  Tail call builtin.
+  if (args_in_registers()) {
+    __ Push(r0, r1);
+  }
   __ bind(&slow);
   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_JS);
 }
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 e31d2e1..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);
 }
 
 
@@ -1316,8 +1300,8 @@
 
 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
   LInstruction* result =
-      new LInstanceOf(UseFixed(instr->left(), r1),
-                      UseFixed(instr->right(), r0));
+      new LInstanceOf(UseFixed(instr->left(), r0),
+                      UseFixed(instr->right(), r1));
   return MarkAsCall(DefineFixed(result, r0), instr);
 }
 
@@ -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;
@@ -1666,19 +1653,15 @@
 }
 
 
-LInstruction* LChunkBuilder::DoArrayLength(HArrayLength* instr) {
-  LOperand* array = NULL;
-  LOperand* temporary = NULL;
+LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
+  LOperand* array = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LJSArrayLength(array));
+}
 
-  if (instr->value()->IsLoadElements()) {
-    array = UseRegisterAtStart(instr->value());
-  } else {
-    array = UseRegister(instr->value());
-    temporary = TempRegister();
-  }
 
-  LInstruction* result = new LArrayLength(array, temporary);
-  return AssignEnvironment(DefineAsRegister(result));
+LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
+  LOperand* array = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LFixedArrayLength(array));
 }
 
 
@@ -1778,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);
@@ -1854,6 +1839,13 @@
 }
 
 
+LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
+    HLoadFunctionPrototype* instr) {
+  return AssignEnvironment(DefineAsRegister(
+      new LLoadFunctionPrototype(UseRegister(instr->function()))));
+}
+
+
 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
   LOperand* input = UseRegisterAtStart(instr->value());
   return DefineSameAsFirst(new LLoadElements(input));
@@ -2054,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 41209c6..2f8cc1c 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -101,7 +101,8 @@
 //     LStoreNamedField
 //     LStoreNamedGeneric
 //   LUnaryOperation
-//     LArrayLength
+//     LJSArrayLength
+//     LFixedArrayLength
 //     LBitNotI
 //     LBranch
 //     LCallNew
@@ -127,6 +128,7 @@
 //     LIsSmiAndBranch
 //     LLoadNamedField
 //     LLoadNamedGeneric
+//     LLoadFunctionPrototype
 //     LNumberTagD
 //     LNumberTagI
 //     LPushArgument
@@ -161,7 +163,6 @@
   V(ArgumentsLength)                            \
   V(ArithmeticD)                                \
   V(ArithmeticT)                                \
-  V(ArrayLength)                                \
   V(ArrayLiteral)                               \
   V(BitI)                                       \
   V(BitNotI)                                    \
@@ -195,6 +196,7 @@
   V(Deoptimize)                                 \
   V(DivI)                                       \
   V(DoubleToI)                                  \
+  V(FixedArrayLength)                           \
   V(FunctionLiteral)                            \
   V(Gap)                                        \
   V(GlobalObject)                               \
@@ -209,6 +211,7 @@
   V(IsObjectAndBranch)                          \
   V(IsSmi)                                      \
   V(IsSmiAndBranch)                             \
+  V(JSArrayLength)                              \
   V(HasInstanceType)                            \
   V(HasInstanceTypeAndBranch)                   \
   V(HasCachedArrayIndex)                        \
@@ -223,6 +226,7 @@
   V(LoadKeyedGeneric)                           \
   V(LoadNamedField)                             \
   V(LoadNamedGeneric)                           \
+  V(LoadFunctionPrototype)                      \
   V(ModI)                                       \
   V(MulI)                                       \
   V(NumberTagD)                                 \
@@ -722,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) { }
 
@@ -737,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_;
 };
@@ -835,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) { }
 
@@ -851,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_;
 };
@@ -1117,42 +1111,43 @@
 
 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_;
 };
 
 
-class LArrayLength: public LUnaryOperation {
+class LJSArrayLength: public LUnaryOperation {
  public:
-  LArrayLength(LOperand* input, LOperand* temporary)
-      : LUnaryOperation(input), temporary_(temporary) { }
+  explicit LJSArrayLength(LOperand* input) : LUnaryOperation(input) { }
 
-  LOperand* temporary() const { return temporary_; }
+  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
+  DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
+};
 
-  DECLARE_CONCRETE_INSTRUCTION(ArrayLength, "array-length")
-  DECLARE_HYDROGEN_ACCESSOR(ArrayLength)
 
- private:
-  LOperand* temporary_;
+class LFixedArrayLength: public LUnaryOperation {
+ public:
+  explicit LFixedArrayLength(LOperand* input) : LUnaryOperation(input) { }
+
+  DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
+  DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
 };
 
 
@@ -1256,6 +1251,18 @@
 };
 
 
+class LLoadFunctionPrototype: public LUnaryOperation {
+ public:
+  explicit LLoadFunctionPrototype(LOperand* function)
+      : LUnaryOperation(function) { }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
+  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
+
+  LOperand* function() const { return input(); }
+};
+
+
 class LLoadElements: public LUnaryOperation {
  public:
   explicit LLoadElements(LOperand* obj) : LUnaryOperation(obj) { }
@@ -1655,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_;
 };
@@ -2051,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 dfc4891..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();
@@ -898,24 +945,18 @@
 }
 
 
-void LCodeGen::DoArrayLength(LArrayLength* instr) {
+void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
   Register result = ToRegister(instr->result());
+  Register array = ToRegister(instr->input());
+  __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
+}
 
-  if (instr->hydrogen()->value()->IsLoadElements()) {
-    // We load the length directly from the elements array.
-    Register elements = ToRegister(instr->input());
-    __ ldr(result, FieldMemOperand(elements, FixedArray::kLengthOffset));
-  } else {
-    // Check that the receiver really is an array.
-    Register array = ToRegister(instr->input());
-    Register temporary = ToRegister(instr->temporary());
-    __ CompareObjectType(array, temporary, temporary, JS_ARRAY_TYPE);
-    DeoptimizeIf(ne, instr->environment());
 
-    // Load length directly from the array.
-    __ ldr(result, FieldMemOperand(array, JSArray::kLengthOffset));
-  }
-  Abort("DoArrayLength untested.");
+void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
+  Register result = ToRegister(instr->result());
+  Register array = ToRegister(instr->input());
+  __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset));
+  Abort("DoFixedArrayLength untested.");
 }
 
 
@@ -1065,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);
@@ -1176,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
@@ -1204,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));
@@ -1282,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());
@@ -1293,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());
 }
 
@@ -1332,19 +1401,28 @@
 
 
 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);
 }
 
 
 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
-  // We expect object and function in registers r1 and r0.
+  ASSERT(ToRegister(instr->left()).is(r0));  // Object is in r0.
+  ASSERT(ToRegister(instr->right()).is(r1));  // Function is in r1.
+
   InstanceofStub stub(InstanceofStub::kArgsInRegisters);
   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 
   Label true_value, done;
   __ tst(r0, r0);
-  __ mov(r0, Operand(Factory::false_value()), LeaveCC, eq);
-  __ mov(r0, Operand(Factory::true_value()), LeaveCC, ne);
+  __ mov(r0, Operand(Factory::false_value()), LeaveCC, ne);
+  __ mov(r0, Operand(Factory::true_value()), LeaveCC, eq);
 }
 
 
@@ -1432,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()));
+  }
 }
 
 
@@ -1447,6 +1532,50 @@
 }
 
 
+void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
+  Register scratch = scratch0();
+  Register function = ToRegister(instr->function());
+  Register result = ToRegister(instr->result());
+
+  // Check that the function really is a function. Load map into the
+  // result register.
+  __ CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE);
+  DeoptimizeIf(ne, instr->environment());
+
+  // Make sure that the function has an instance prototype.
+  Label non_instance;
+  __ 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.
+  __ ldr(result,
+         FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
+
+  // Check that the function has a prototype or an initial map.
+  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+  __ cmp(result, ip);
+  DeoptimizeIf(eq, instr->environment());
+
+  // If the function does not have an initial map, we're done.
+  Label done;
+  __ CompareObjectType(result, scratch, scratch, MAP_TYPE);
+  __ b(ne, &done);
+
+  // Get the prototype from the initial map.
+  __ ldr(result, FieldMemOperand(result, Map::kPrototypeOffset));
+  __ jmp(&done);
+
+  // Non-instance prototype: Fetch prototype from constructor field
+  // in initial map.
+  __ bind(&non_instance);
+  __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset));
+
+  // All done.
+  __ bind(&done);
+}
+
+
 void LCodeGen::DoLoadElements(LLoadElements* instr) {
   Abort("DoLoadElements unimplemented.");
 }
@@ -1544,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);
 }
 
 
@@ -1604,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));
 }
 
 
@@ -1652,7 +1789,8 @@
 
 
 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
-  Abort("DoBoundsCheck unimplemented.");
+  __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
+  DeoptimizeIf(hs, instr->environment());
 }
 
 
@@ -1757,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) {
@@ -1808,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));
 
@@ -1820,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);
@@ -1864,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;
@@ -1985,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);
+  }
 }
 
 
@@ -2056,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);
@@ -2073,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())) {
@@ -2099,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())) {
@@ -2112,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/ast.cc b/src/ast.cc
index 895ab67..1a6e768 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -517,6 +517,9 @@
   if (key()->IsPropertyName()) {
     if (oracle->LoadIsBuiltin(this, Builtins::LoadIC_ArrayLength)) {
       is_array_length_ = true;
+    } else if (oracle->LoadIsBuiltin(this,
+                                     Builtins::LoadIC_FunctionPrototype)) {
+      is_function_prototype_ = true;
     } else {
       Literal* lit_key = key()->AsLiteral();
       ASSERT(lit_key != NULL && lit_key->handle()->IsString());
diff --git a/src/ast.h b/src/ast.h
index ed447e3..ba422fd 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -1208,6 +1208,7 @@
         is_monomorphic_(false),
         receiver_types_(NULL),
         is_array_length_(false),
+        is_function_prototype_(false),
         is_arguments_access_(false) { }
 
   DECLARE_NODE_TYPE(Property)
@@ -1220,6 +1221,8 @@
   int position() const { return pos_; }
   bool is_synthetic() const { return type_ == SYNTHETIC; }
 
+  bool IsFunctionPrototype() const { return is_function_prototype_; }
+
   // Marks that this is actually an argument rewritten to a keyed property
   // accessing the argument through the arguments shadow object.
   void set_is_arguments_access(bool is_arguments_access) {
@@ -1249,6 +1252,7 @@
   bool is_monomorphic_;
   ZoneMapList* receiver_types_;
   bool is_array_length_;
+  bool is_function_prototype_;
   bool is_arguments_access_;
   Handle<Map> monomorphic_receiver_type_;
 
@@ -1391,7 +1395,7 @@
       : op_(op), left_(left), right_(right), pos_(pos), is_smi_only_(false) {
     ASSERT(Token::IsBinaryOp(op));
     right_id_ = (op == Token::AND || op == Token::OR)
-        ? GetNextId()
+        ? static_cast<int>(GetNextId())
         : AstNode::kNoNumber;
   }
 
diff --git a/src/builtins.cc b/src/builtins.cc
index 21381f1..0c76f69 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -380,7 +380,7 @@
     Object* receiver) {
   if (!receiver->IsJSArray()) return NULL;
   JSArray* array = JSArray::cast(receiver);
-  HeapObject* elms = HeapObject::cast(array->elements());
+  HeapObject* elms = array->elements();
   if (elms->map() == Heap::fixed_array_map()) return elms;
   if (elms->map() == Heap::fixed_cow_array_map()) {
     return array->EnsureWritableFastElements();
@@ -613,42 +613,38 @@
   Object* receiver = *args.receiver();
   FixedArray* elms;
   int len = -1;
-  { MaybeObject* maybe_elms_obj =
-        EnsureJSArrayWithWritableFastElements(receiver);
-    Object* elms_obj;
-    if (maybe_elms_obj != NULL && maybe_elms_obj->ToObject(&elms_obj)) {
-      if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
-        return CallJsBuiltin("ArraySlice", args);
-      }
-      elms = FixedArray::cast(elms_obj);
-      JSArray* array = JSArray::cast(receiver);
-      ASSERT(array->HasFastElements());
-
-      len = Smi::cast(array->length())->value();
-    } else {
-      // Array.slice(arguments, ...) is quite a common idiom (notably more
-      // than 50% of invocations in Web apps).  Treat it in C++ as well.
-      Map* arguments_map =
-          Top::context()->global_context()->arguments_boilerplate()->map();
-
-      bool is_arguments_object_with_fast_elements =
-          receiver->IsJSObject()
-          && JSObject::cast(receiver)->map() == arguments_map
-          && JSObject::cast(receiver)->HasFastElements();
-      if (!is_arguments_object_with_fast_elements) {
-        return CallJsBuiltin("ArraySlice", args);
-      }
-      elms = FixedArray::cast(JSObject::cast(receiver)->elements());
-      len = elms->length();
-#ifdef DEBUG
-      // Arguments object by construction should have no holes, check it.
-      if (FLAG_enable_slow_asserts) {
-        for (int i = 0; i < len; i++) {
-          ASSERT(elms->get(i) != Heap::the_hole_value());
-        }
-      }
-#endif
+  if (receiver->IsJSArray()) {
+    JSArray* array = JSArray::cast(receiver);
+    if (!array->HasFastElements() ||
+        !IsJSArrayFastElementMovingAllowed(array)) {
+      return CallJsBuiltin("ArraySlice", args);
     }
+
+    elms = FixedArray::cast(array->elements());
+    len = Smi::cast(array->length())->value();
+  } else {
+    // Array.slice(arguments, ...) is quite a common idiom (notably more
+    // than 50% of invocations in Web apps).  Treat it in C++ as well.
+    Map* arguments_map =
+        Top::context()->global_context()->arguments_boilerplate()->map();
+
+    bool is_arguments_object_with_fast_elements =
+        receiver->IsJSObject()
+        && JSObject::cast(receiver)->map() == arguments_map
+        && JSObject::cast(receiver)->HasFastElements();
+    if (!is_arguments_object_with_fast_elements) {
+      return CallJsBuiltin("ArraySlice", args);
+    }
+    elms = FixedArray::cast(JSObject::cast(receiver)->elements());
+    len = elms->length();
+#ifdef DEBUG
+    // Arguments object by construction should have no holes, check it.
+    if (FLAG_enable_slow_asserts) {
+      for (int i = 0; i < len; i++) {
+        ASSERT(elms->get(i) != Heap::the_hole_value());
+      }
+    }
+#endif
   }
   ASSERT(len >= 0);
   int n_arguments = args.length() - 1;
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.cc b/src/d8-debug.cc
index 5f3ed76..8a3886c 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -34,12 +34,21 @@
 
 namespace v8 {
 
-void PrintPrompt() {
-  printf("dbg> ");
+static bool was_running = true;
+
+void PrintPrompt(bool is_running) {
+  const char* prompt = is_running? "> " : "dbg> ";
+  was_running = is_running;
+  printf("%s", prompt);
   fflush(stdout);
 }
 
 
+void PrintPrompt() {
+  PrintPrompt(was_running);
+}
+
+
 void HandleDebugEvent(DebugEvent event,
                       Handle<Object> exec_state,
                       Handle<Object> event_data,
@@ -91,7 +100,7 @@
   bool running = false;
   while (!running) {
     char command[kBufferSize];
-    PrintPrompt();
+    PrintPrompt(running);
     char* str = fgets(command, kBufferSize, stdin);
     if (str == NULL) break;
 
@@ -284,7 +293,9 @@
   } else {
     printf("???\n");
   }
-  PrintPrompt();
+
+  bool is_running = details->Get(String::New("running"))->ToBoolean()->Value();
+  PrintPrompt(is_running);
 }
 
 
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/date.js b/src/date.js
index bc70327..9eb607c 100644
--- a/src/date.js
+++ b/src/date.js
@@ -1000,7 +1000,7 @@
 function DateToJSON(key) {
   var o = ToObject(this);
   var tv = DefaultNumber(o);
-  if (IS_NUMBER(tv) && !$isFinite(tv)) { 
+  if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) { 
     return null; 
   }
   return o.toISOString();
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/deoptimizer.cc b/src/deoptimizer.cc
index dd70baa..185ff92 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -309,9 +309,9 @@
 }
 
 
-unsigned Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
-                                    unsigned id,
-                                    SharedFunctionInfo* shared) {
+int Deoptimizer::GetOutputInfo(DeoptimizationOutputData* data,
+                               unsigned id,
+                               SharedFunctionInfo* shared) {
   // TODO(kasperl): For now, we do a simple linear search for the PC
   // offset associated with the given node id. This should probably be
   // changed to a binary search.
diff --git a/src/deoptimizer.h b/src/deoptimizer.h
index 2d7dfc8..f9bf280 100644
--- a/src/deoptimizer.h
+++ b/src/deoptimizer.h
@@ -145,9 +145,9 @@
 
   static Address GetDeoptimizationEntry(int id, BailoutType type);
   static int GetDeoptimizationId(Address addr, BailoutType type);
-  static unsigned GetOutputInfo(DeoptimizationOutputData* data,
-                                unsigned node_id,
-                                SharedFunctionInfo* shared);
+  static int GetOutputInfo(DeoptimizationOutputData* data,
+                           unsigned node_id,
+                           SharedFunctionInfo* shared);
 
   static void Setup();
   static void TearDown();
diff --git a/src/factory.cc b/src/factory.cc
index 83af447..2bc878c 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -99,6 +99,14 @@
   CALL_HEAP_FUNCTION(Heap::LookupSymbol(string), String);
 }
 
+Handle<String> Factory::LookupAsciiSymbol(Vector<const char> string) {
+  CALL_HEAP_FUNCTION(Heap::LookupAsciiSymbol(string), String);
+}
+
+Handle<String> Factory::LookupTwoByteSymbol(Vector<const uc16> string) {
+  CALL_HEAP_FUNCTION(Heap::LookupTwoByteSymbol(string), String);
+}
+
 
 Handle<String> Factory::NewStringFromAscii(Vector<const char> string,
                                            PretenureFlag pretenure) {
diff --git a/src/factory.h b/src/factory.h
index b7a2882..a5e1591 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -61,6 +61,8 @@
       PretenureFlag pretenure);
 
   static Handle<String> LookupSymbol(Vector<const char> str);
+  static Handle<String> LookupAsciiSymbol(Vector<const char> str);
+  static Handle<String> LookupTwoByteSymbol(Vector<const uc16> str);
   static Handle<String> LookupAsciiSymbol(const char* str) {
     return LookupSymbol(CStrVector(str));
   }
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/globals.h b/src/globals.h
index 35156ae..9b24bf6 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -181,10 +181,6 @@
 #define USING_BSD_ABI
 #endif
 
-// Code-point values in Unicode 4.0 are 21 bits wide.
-typedef uint16_t uc16;
-typedef int32_t uc32;
-
 // -----------------------------------------------------------------------------
 // Constants
 
@@ -228,6 +224,15 @@
 const int kBinary32MantissaBits = 23;
 const int kBinary32ExponentShift = 23;
 
+// ASCII/UC16 constants
+// Code-point values in Unicode 4.0 are 21 bits wide.
+typedef uint16_t uc16;
+typedef int32_t uc32;
+const int kASCIISize    = kCharSize;
+const int kUC16Size     = sizeof(uc16);      // NOLINT
+const uc32 kMaxAsciiCharCode = 0x7f;
+const uint32_t kMaxAsciiCharCodeU = 0x7fu;
+
 
 // The expression OFFSET_OF(type, field) computes the byte-offset
 // of the specified field relative to the containing type. This
diff --git a/src/heap-inl.h b/src/heap-inl.h
index ef83998..e7700e9 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -40,6 +40,19 @@
 }
 
 
+MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> str,
+                                          PretenureFlag pretenure) {
+  // Check for ASCII first since this is the common case.
+  if (String::IsAscii(str.start(), str.length())) {
+    // If the string is ASCII, we do not need to convert the characters
+    // since UTF8 is backwards compatible with ASCII.
+    return AllocateStringFromAscii(str, pretenure);
+  }
+  // Non-ASCII and we need to decode.
+  return AllocateStringFromUtf8Slow(str, pretenure);
+}
+
+
 MaybeObject* Heap::AllocateSymbol(Vector<const char> str,
                                   int chars,
                                   uint32_t hash_field) {
@@ -49,6 +62,71 @@
 }
 
 
+MaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str,
+                                       uint32_t hash_field) {
+  if (str.length() > SeqAsciiString::kMaxLength) {
+    return Failure::OutOfMemoryException();
+  }
+  // Compute map and object size.
+  Map* map = ascii_symbol_map();
+  int size = SeqAsciiString::SizeFor(str.length());
+
+  // Allocate string.
+  Object* result;
+  { MaybeObject* maybe_result = (size > MaxObjectSizeInPagedSpace())
+                   ? lo_space_->AllocateRaw(size)
+                   : old_data_space_->AllocateRaw(size);
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+  }
+
+  reinterpret_cast<HeapObject*>(result)->set_map(map);
+  // Set length and hash fields of the allocated string.
+  String* answer = String::cast(result);
+  answer->set_length(str.length());
+  answer->set_hash_field(hash_field);
+
+  ASSERT_EQ(size, answer->Size());
+
+  // Fill in the characters.
+  memcpy(answer->address() + SeqAsciiString::kHeaderSize,
+         str.start(), str.length());
+
+  return answer;
+}
+
+
+MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str,
+                                         uint32_t hash_field) {
+  if (str.length() > SeqTwoByteString::kMaxLength) {
+    return Failure::OutOfMemoryException();
+  }
+  // Compute map and object size.
+  Map* map = symbol_map();
+  int size = SeqTwoByteString::SizeFor(str.length());
+
+  // Allocate string.
+  Object* result;
+  { MaybeObject* maybe_result = (size > MaxObjectSizeInPagedSpace())
+                   ? lo_space_->AllocateRaw(size)
+                   : old_data_space_->AllocateRaw(size);
+    if (!maybe_result->ToObject(&result)) return maybe_result;
+  }
+
+  reinterpret_cast<HeapObject*>(result)->set_map(map);
+  // Set length and hash fields of the allocated string.
+  String* answer = String::cast(result);
+  answer->set_length(str.length());
+  answer->set_hash_field(hash_field);
+
+  ASSERT_EQ(size, answer->Size());
+
+  // Fill in the characters.
+  memcpy(answer->address() + SeqTwoByteString::kHeaderSize,
+         str.start(), str.length() * kUC16Size);
+
+  return answer;
+}
+
 MaybeObject* Heap::CopyFixedArray(FixedArray* src) {
   return CopyFixedArrayWithMap(src, src->map());
 }
@@ -443,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/heap.cc b/src/heap.cc
index 1e99991..44229f0 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2549,20 +2549,10 @@
   }
 
   // For small strings we check whether the resource contains only
-  // ascii characters.  If yes, we use a different string map.
-  bool is_ascii = true;
-  if (length >= static_cast<size_t>(String::kMinNonFlatLength)) {
-    is_ascii = false;
-  } else {
-    const uc16* data = resource->data();
-    for (size_t i = 0; i < length; i++) {
-      if (data[i] > String::kMaxAsciiCharCode) {
-        is_ascii = false;
-        break;
-      }
-    }
-  }
-
+  // ASCII characters.  If yes, we use a different string map.
+  static const size_t kAsciiCheckLengthLimit = 32;
+  bool is_ascii = length <= kAsciiCheckLengthLimit &&
+      String::IsAscii(resource->data(), static_cast<int>(length));
   Map* map = is_ascii ?
       Heap::external_string_with_ascii_data_map() : Heap::external_string_map();
   Object* result;
@@ -3307,8 +3297,8 @@
 }
 
 
-MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> string,
-                                          PretenureFlag pretenure) {
+MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
+                                              PretenureFlag pretenure) {
   // V8 only supports characters in the Basic Multilingual Plane.
   const uc32 kMaxSupportedChar = 0xFFFF;
   // Count the number of characters in the UTF-8 string and check if
@@ -3317,17 +3307,11 @@
       decoder(ScannerConstants::utf8_decoder());
   decoder->Reset(string.start(), string.length());
   int chars = 0;
-  bool is_ascii = true;
   while (decoder->has_more()) {
-    uc32 r = decoder->GetNext();
-    if (r > String::kMaxAsciiCharCode) is_ascii = false;
+    decoder->GetNext();
     chars++;
   }
 
-  // If the string is ascii, we do not need to convert the characters
-  // since UTF8 is backwards compatible with ascii.
-  if (is_ascii) return AllocateStringFromAscii(string, pretenure);
-
   Object* result;
   { MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure);
     if (!maybe_result->ToObject(&result)) return maybe_result;
@@ -3348,11 +3332,8 @@
 MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string,
                                              PretenureFlag pretenure) {
   // Check if the string is an ASCII string.
-  int i = 0;
-  while (i < string.length() && string[i] <= String::kMaxAsciiCharCode) i++;
-
   MaybeObject* maybe_result;
-  if (i == string.length()) {  // It's an ASCII string.
+  if (String::IsAscii(string.start(), string.length())) {
     maybe_result = AllocateRawAsciiString(string.length(), pretenure);
   } else {  // It's not an ASCII string.
     maybe_result = AllocateRawTwoByteString(string.length(), pretenure);
@@ -4032,6 +4013,36 @@
 }
 
 
+MaybeObject* Heap::LookupAsciiSymbol(Vector<const char> string) {
+  Object* symbol = NULL;
+  Object* new_table;
+  { MaybeObject* maybe_new_table =
+        symbol_table()->LookupAsciiSymbol(string, &symbol);
+    if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
+  }
+  // Can't use set_symbol_table because SymbolTable::cast knows that
+  // SymbolTable is a singleton and checks for identity.
+  roots_[kSymbolTableRootIndex] = new_table;
+  ASSERT(symbol != NULL);
+  return symbol;
+}
+
+
+MaybeObject* Heap::LookupTwoByteSymbol(Vector<const uc16> string) {
+  Object* symbol = NULL;
+  Object* new_table;
+  { MaybeObject* maybe_new_table =
+        symbol_table()->LookupTwoByteSymbol(string, &symbol);
+    if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table;
+  }
+  // Can't use set_symbol_table because SymbolTable::cast knows that
+  // SymbolTable is a singleton and checks for identity.
+  roots_[kSymbolTableRootIndex] = new_table;
+  ASSERT(symbol != NULL);
+  return symbol;
+}
+
+
 MaybeObject* Heap::LookupSymbol(String* string) {
   if (string->IsSymbol()) return string;
   Object* symbol = NULL;
diff --git a/src/heap.h b/src/heap.h
index 18a4afb..3ceefd8 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -412,7 +412,10 @@
   MUST_USE_RESULT static MaybeObject* AllocateStringFromAscii(
       Vector<const char> str,
       PretenureFlag pretenure = NOT_TENURED);
-  MUST_USE_RESULT static MaybeObject* AllocateStringFromUtf8(
+  MUST_USE_RESULT static inline MaybeObject* AllocateStringFromUtf8(
+      Vector<const char> str,
+      PretenureFlag pretenure = NOT_TENURED);
+  MUST_USE_RESULT static MaybeObject* AllocateStringFromUtf8Slow(
       Vector<const char> str,
       PretenureFlag pretenure = NOT_TENURED);
   MUST_USE_RESULT static MaybeObject* AllocateStringFromTwoByte(
@@ -428,6 +431,14 @@
       int chars,
       uint32_t hash_field);
 
+  MUST_USE_RESULT static inline MaybeObject* AllocateAsciiSymbol(
+        Vector<const char> str,
+        uint32_t hash_field);
+
+  MUST_USE_RESULT static inline MaybeObject* AllocateTwoByteSymbol(
+        Vector<const uc16> str,
+        uint32_t hash_field);
+
   MUST_USE_RESULT static MaybeObject* AllocateInternalSymbol(
       unibrow::CharacterStream* buffer, int chars, uint32_t hash_field);
 
@@ -683,6 +694,9 @@
   // failed.
   // Please note this function does not perform a garbage collection.
   MUST_USE_RESULT static MaybeObject* LookupSymbol(Vector<const char> str);
+  MUST_USE_RESULT static MaybeObject* LookupAsciiSymbol(Vector<const char> str);
+  MUST_USE_RESULT static MaybeObject* LookupTwoByteSymbol(
+      Vector<const uc16> str);
   MUST_USE_RESULT static MaybeObject* LookupAsciiSymbol(const char* str) {
     return LookupSymbol(CStrVector(str));
   }
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index cbbe8fc..a3c23c6 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -76,7 +76,6 @@
 //       HLoadKeyed
 //         HLoadKeyedFastElement
 //         HLoadKeyedGeneric
-//       HLoadNamedGeneric
 //       HPower
 //       HStoreNamed
 //         HStoreNamedField
@@ -119,7 +118,6 @@
 //       HStoreKeyedFastElement
 //       HStoreKeyedGeneric
 //     HUnaryOperation
-//       HArrayLength
 //       HBitNot
 //       HChange
 //       HCheckFunction
@@ -129,9 +127,13 @@
 //       HCheckPrototypeMaps
 //       HCheckSmi
 //       HDeleteProperty
+//       HFixedArrayLength
+//       HJSArrayLength
 //       HLoadElements
 //         HTypeofIs
 //       HLoadNamedField
+//       HLoadNamedGeneric
+//       HLoadFunctionPrototype
 //       HPushArgument
 //       HTypeof
 //       HUnaryMathOperation
@@ -170,7 +172,6 @@
   V(ArgumentsElements)                         \
   V(ArgumentsLength)                           \
   V(ArgumentsObject)                           \
-  V(ArrayLength)                               \
   V(ArrayLiteral)                              \
   V(BitAnd)                                    \
   V(BitNot)                                    \
@@ -203,6 +204,7 @@
   V(Deoptimize)                                \
   V(Div)                                       \
   V(EnterInlined)                              \
+  V(FixedArrayLength)                          \
   V(FunctionLiteral)                           \
   V(GlobalObject)                              \
   V(GlobalReceiver)                            \
@@ -213,6 +215,7 @@
   V(IsSmi)                                     \
   V(HasInstanceType)                           \
   V(HasCachedArrayIndex)                       \
+  V(JSArrayLength)                             \
   V(ClassOfTest)                               \
   V(LeaveInlined)                              \
   V(LoadElements)                              \
@@ -221,6 +224,7 @@
   V(LoadKeyedGeneric)                          \
   V(LoadNamedField)                            \
   V(LoadNamedGeneric)                          \
+  V(LoadFunctionPrototype)                     \
   V(Mod)                                       \
   V(Mul)                                       \
   V(ObjectLiteral)                             \
@@ -256,6 +260,7 @@
   V(GlobalVars)                                \
   V(Maps)                                      \
   V(ArrayLengths)                              \
+  V(FunctionPrototypes)                        \
   V(OsrEntries)
 
 #define DECLARE_INSTRUCTION(type)                   \
@@ -905,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_; }
@@ -1015,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() {}
@@ -1032,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 {
@@ -1074,7 +1082,7 @@
   }
   int ast_id_;
   int pop_count_;
-  int environment_height_;
+  int environment_length_;
   ZoneList<HValue*> values_;
   ZoneList<int> assigned_indexes_;
 };
@@ -1336,9 +1344,9 @@
 };
 
 
-class HArrayLength: public HUnaryOperation {
+class HJSArrayLength: public HUnaryOperation {
  public:
-  explicit HArrayLength(HValue* value) : HUnaryOperation(value) {
+  explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
     // The length of an array is stored as a tagged value in the array
     // object. It is guaranteed to be 32 bit integer, but it can be
     // represented as either a smi or heap number.
@@ -1351,7 +1359,23 @@
     return Representation::Tagged();
   }
 
-  DECLARE_CONCRETE_INSTRUCTION(ArrayLength, "array_length")
+  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
+};
+
+
+class HFixedArrayLength: public HUnaryOperation {
+ public:
+  explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
+    set_representation(Representation::Tagged());
+    SetFlag(kDependsOnArrayLengths);
+    SetFlag(kUseGVN);
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
 };
 
 
@@ -1766,6 +1790,8 @@
 
   Handle<Object> handle() const { return handle_; }
 
+  bool InOldSpace() const { return !Heap::InNewSpace(*handle_); }
+
   virtual bool EmitAtUses() const { return !representation().IsDouble(); }
   virtual void PrintDataTo(StringStream* stream) const;
   virtual HType CalculateInferredType() const;
@@ -2617,6 +2643,27 @@
 };
 
 
+class HLoadFunctionPrototype: public HUnaryOperation {
+ public:
+  explicit HLoadFunctionPrototype(HValue* function)
+      : HUnaryOperation(function) {
+    set_representation(Representation::Tagged());
+    SetFlagMask(kDependsOnFunctionPrototypes);
+  }
+
+  HValue* function() const { return OperandAt(0); }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return Representation::Tagged();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
+
+ protected:
+  virtual bool DataEquals(HValue* other) const { return true; }
+};
+
+
 class HLoadKeyed: public HBinaryOperation {
  public:
   HLoadKeyed(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
@@ -2663,6 +2710,12 @@
 };
 
 
+static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
+  return !value->type().IsSmi() &&
+      !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
+}
+
+
 class HStoreNamed: public HBinaryOperation {
  public:
   HStoreNamed(HValue* obj, Handle<Object> name, HValue* val)
@@ -2680,6 +2733,10 @@
   HValue* value() const { return OperandAt(1); }
   void set_value(HValue* value) { SetOperandAt(1, value); }
 
+  bool NeedsWriteBarrier() const {
+    return StoringValueNeedsWriteBarrier(value());
+  }
+
   DECLARE_INSTRUCTION(StoreNamed)
 
  protected:
@@ -2760,6 +2817,10 @@
   HValue* key() const { return OperandAt(1); }
   HValue* value() const { return OperandAt(2); }
 
+  bool NeedsWriteBarrier() const {
+    return StoringValueNeedsWriteBarrier(value());
+  }
+
   DECLARE_INSTRUCTION(StoreKeyed)
 
  protected:
@@ -2779,10 +2840,6 @@
     SetFlag(kChangesArrayElements);
   }
 
-  bool NeedsWriteBarrier() const {
-    return !value()->type().IsSmi();
-  }
-
   virtual Representation RequiredInputRepresentation(int index) const {
     // The key is supposed to be Integer32.
     return (index == 1) ? Representation::Integer32()
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index e34acd6..fbe4cd7 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) {
@@ -3103,8 +3103,15 @@
   // this basic block the current basic block.
   HBasicBlock* join_block = graph_->CreateBasicBlock();
   for (int i = 0; i < subgraphs->length(); ++i) {
-    if (subgraphs->at(i)->HasExit()) {
-      subgraphs->at(i)->exit_block()->Goto(join_block);
+    HSubgraph* subgraph = subgraphs->at(i);
+    if (subgraph->HasExit()) {
+      // In an effect context the value of the type switch is not needed.
+      // There is no need to merge it at the join block only to discard it.
+      HBasicBlock* subgraph_exit = subgraph->exit_block();
+      if (ast_context()->IsEffect()) {
+        subgraph_exit->last_environment()->Drop(1);
+      }
+      subgraph_exit->Goto(join_block);
     }
   }
 
@@ -3242,7 +3249,8 @@
     Push(value);
     instr->set_position(expr->position());
     AddInstruction(instr);
-    if (instr->HasSideEffects()) AddSimulate(expr->id());
+    if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
+    ast_context()->ReturnValue(Pop());
   } else {
     // Build subgraph for generic store through IC.
     {
@@ -3260,11 +3268,14 @@
     }
 
     HBasicBlock* new_exit_block =
-        BuildTypeSwitch(&maps, &subgraphs, object, expr->AssignmentId());
+        BuildTypeSwitch(&maps, &subgraphs, object, expr->id());
     subgraph()->set_exit_block(new_exit_block);
+    // In an effect context, we did not materialized the value in the
+    // predecessor environments so there's no need to handle it here.
+    if (subgraph()->HasExit() && !ast_context()->IsEffect()) {
+      ast_context()->ReturnValue(Pop());
+    }
   }
-
-  if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop());
 }
 
 
@@ -3548,8 +3559,7 @@
   if (maps.length() == 0) {
     HInstruction* instr = BuildLoadNamedGeneric(object, expr);
     instr->set_position(expr->position());
-    PushAndAdd(instr);
-    if (instr->HasSideEffects()) AddSimulate(expr->id());
+    ast_context()->ReturnInstruction(instr, expr->id());
   } else {
     // Build subgraph for generic load through IC.
     {
@@ -3568,9 +3578,12 @@
     HBasicBlock* new_exit_block =
         BuildTypeSwitch(&maps, &subgraphs, object, expr->id());
     subgraph()->set_exit_block(new_exit_block);
+    // In an effect context, we did not materialized the value in the
+    // predecessor environments so there's no need to handle it here.
+    if (subgraph()->HasExit() && !ast_context()->IsEffect()) {
+      ast_context()->ReturnValue(Pop());
+    }
   }
-
-  if (subgraph()->HasExit()) ast_context()->ReturnValue(Pop());
 }
 
 
@@ -3643,9 +3656,18 @@
   Handle<Map> map = expr->GetMonomorphicReceiverType();
   ASSERT(map->has_fast_elements());
   AddInstruction(new HCheckMap(object, map));
-  HInstruction* elements = AddInstruction(new HLoadElements(object));
-  HInstruction* length = AddInstruction(new HArrayLength(elements));
-  AddInstruction(new HBoundsCheck(key, length));
+  bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
+  HLoadElements* elements = new HLoadElements(object);
+  HInstruction* length = NULL;
+  if (is_array) {
+    length = AddInstruction(new HJSArrayLength(object));
+    AddInstruction(new HBoundsCheck(key, length));
+    AddInstruction(elements);
+  } else {
+    AddInstruction(elements);
+    length = AddInstruction(new HFixedArrayLength(elements));
+    AddInstruction(new HBoundsCheck(key, length));
+  }
   return new HLoadKeyedFastElement(elements, key);
 }
 
@@ -3671,9 +3693,9 @@
   bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
   HInstruction* length = NULL;
   if (is_array) {
-    length = AddInstruction(new HArrayLength(object));
+    length = AddInstruction(new HJSArrayLength(object));
   } else {
-    length = AddInstruction(new HArrayLength(elements));
+    length = AddInstruction(new HFixedArrayLength(elements));
   }
   AddInstruction(new HBoundsCheck(key, length));
   return new HStoreKeyedFastElement(elements, key, val);
@@ -3720,7 +3742,13 @@
   if (expr->IsArrayLength()) {
     HValue* array = Pop();
     AddInstruction(new HCheckNonSmi(array));
-    instr = new HArrayLength(array);
+    AddInstruction(new HCheckInstanceType(array, JS_ARRAY_TYPE, JS_ARRAY_TYPE));
+    instr = new HJSArrayLength(array);
+
+  } else if (expr->IsFunctionPrototype()) {
+    HValue* function = Pop();
+    AddInstruction(new HCheckNonSmi(function));
+    instr = new HLoadFunctionPrototype(function);
 
   } else if (expr->key()->IsPropertyName()) {
     Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
@@ -3841,7 +3869,11 @@
     HBasicBlock* new_exit_block =
         BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id());
     subgraph()->set_exit_block(new_exit_block);
-    if (new_exit_block != NULL) ast_context()->ReturnValue(Pop());
+    // In an effect context, we did not materialized the value in the
+    // predecessor environments so there's no need to handle it here.
+    if (new_exit_block != NULL && !ast_context()->IsEffect()) {
+      ast_context()->ReturnValue(Pop());
+    }
   }
 }
 
@@ -4854,7 +4886,9 @@
     switch (op) {
       case Token::EQ:
       case Token::EQ_STRICT: {
+        AddInstruction(new HCheckNonSmi(left));
         AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left));
+        AddInstruction(new HCheckNonSmi(right));
         AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right));
         instr = new HCompareJSObjectEq(left, right);
         break;
@@ -5262,6 +5296,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());
@@ -5292,26 +5339,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();
   }
 }
 
@@ -5376,7 +5442,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/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 13a1177..5beec0d 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -379,7 +379,7 @@
 
 void FullCodeGenerator::AccumulatorValueContext::Plug(
     Handle<Object> lit) const {
-  __ mov(result_register(), lit);
+  __ Set(result_register(), Immediate(lit));
 }
 
 
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 d64f528..0f56825 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -940,7 +940,7 @@
 
 void LCodeGen::DoConstantI(LConstantI* instr) {
   ASSERT(instr->result()->IsRegister());
-  __ mov(ToRegister(instr->result()), instr->value());
+  __ Set(ToRegister(instr->result()), Immediate(instr->value()));
 }
 
 
@@ -973,27 +973,21 @@
 
 void LCodeGen::DoConstantT(LConstantT* instr) {
   ASSERT(instr->result()->IsRegister());
-  __ mov(ToRegister(instr->result()), Immediate(instr->value()));
+  __ Set(ToRegister(instr->result()), Immediate(instr->value()));
 }
 
 
-void LCodeGen::DoArrayLength(LArrayLength* instr) {
+void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
   Register result = ToRegister(instr->result());
+  Register array = ToRegister(instr->input());
+  __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
+}
 
-  if (instr->hydrogen()->value()->IsLoadElements()) {
-    // We load the length directly from the elements array.
-    Register elements = ToRegister(instr->input());
-    __ mov(result, FieldOperand(elements, FixedArray::kLengthOffset));
-  } else {
-    // Check that the receiver really is an array.
-    Register array = ToRegister(instr->input());
-    Register temporary = ToRegister(instr->temporary());
-    __ CmpObjectType(array, JS_ARRAY_TYPE, temporary);
-    DeoptimizeIf(not_equal, instr->environment());
 
-    // Load length directly from the array.
-    __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
-  }
+void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
+  Register result = ToRegister(instr->result());
+  Register array = ToRegister(instr->input());
+  __ mov(result, FieldOperand(array, FixedArray::kLengthOffset));
 }
 
 
@@ -1837,6 +1831,48 @@
 }
 
 
+void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
+  Register function = ToRegister(instr->function());
+  Register temp = ToRegister(instr->temporary());
+  Register result = ToRegister(instr->result());
+
+  // Check that the function really is a function.
+  __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
+  DeoptimizeIf(not_equal, instr->environment());
+
+  // Check whether the function has an instance prototype.
+  NearLabel non_instance;
+  __ test_b(FieldOperand(result, Map::kBitFieldOffset),
+            1 << Map::kHasNonInstancePrototype);
+  __ j(not_zero, &non_instance);
+
+  // Get the prototype or initial map from the function.
+  __ mov(result,
+         FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
+
+  // Check that the function has a prototype or an initial map.
+  __ cmp(Operand(result), Immediate(Factory::the_hole_value()));
+  DeoptimizeIf(equal, instr->environment());
+
+  // If the function does not have an initial map, we're done.
+  NearLabel done;
+  __ CmpObjectType(result, MAP_TYPE, temp);
+  __ j(not_equal, &done);
+
+  // Get the prototype from the initial map.
+  __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
+  __ jmp(&done);
+
+  // Non-instance prototype: Fetch prototype from constructor field
+  // in the function's map.
+  __ bind(&non_instance);
+  __ mov(result, FieldOperand(result, Map::kConstructorOffset));
+
+  // All done.
+  __ bind(&done);
+}
+
+
 void LCodeGen::DoLoadElements(LLoadElements* instr) {
   ASSERT(instr->result()->Equals(instr->input()));
   Register reg = ToRegister(instr->input());
@@ -2891,9 +2927,6 @@
   InstanceType first = instr->hydrogen()->first();
   InstanceType last = instr->hydrogen()->last();
 
-  __ test(input, Immediate(kSmiTagMask));
-  DeoptimizeIf(zero, instr->environment());
-
   __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
   __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
           static_cast<int8_t>(first));
@@ -3006,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 3b272d0..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(),
@@ -1677,19 +1669,15 @@
 }
 
 
-LInstruction* LChunkBuilder::DoArrayLength(HArrayLength* instr) {
-  LOperand* array = NULL;
-  LOperand* temporary = NULL;
+LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
+  LOperand* array = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LJSArrayLength(array));
+}
 
-  if (instr->value()->IsLoadElements()) {
-    array = UseRegisterAtStart(instr->value());
-  } else {
-    array = UseRegister(instr->value());
-    temporary = TempRegister();
-  }
 
-  LInstruction* result = new LArrayLength(array, temporary);
-  return AssignEnvironment(DefineAsRegister(result));
+LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
+  LOperand* array = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new LFixedArrayLength(array));
 }
 
 
@@ -1860,6 +1848,14 @@
 }
 
 
+LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
+    HLoadFunctionPrototype* instr) {
+  return AssignEnvironment(DefineAsRegister(
+      new LLoadFunctionPrototype(UseRegister(instr->function()),
+                                 TempRegister())));
+}
+
+
 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
   LOperand* input = UseRegisterAtStart(instr->value());
   return DefineSameAsFirst(new LLoadElements(input));
@@ -1931,7 +1927,7 @@
 
 
 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
-  bool needs_write_barrier = !instr->value()->type().IsSmi();
+  bool needs_write_barrier = instr->NeedsWriteBarrier();
 
   LOperand* obj = needs_write_barrier
       ? UseTempRegister(instr->object())
@@ -2035,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);
 }
 
@@ -2059,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 3f48e50..00dc394 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -104,7 +104,6 @@
 //     LStoreNamedField
 //     LStoreNamedGeneric
 //   LUnaryOperation
-//     LArrayLength
 //     LBitNotI
 //     LBranch
 //     LCallNew
@@ -117,6 +116,7 @@
 //     LClassOfTestAndBranch
 //     LDeleteProperty
 //     LDoubleToI
+//     LFixedArrayLength
 //     LHasCachedArrayIndex
 //     LHasCachedArrayIndexAndBranch
 //     LHasInstanceType
@@ -128,8 +128,10 @@
 //     LIsObjectAndBranch
 //     LIsSmi
 //     LIsSmiAndBranch
+//     LJSArrayLength
 //     LLoadNamedField
 //     LLoadNamedGeneric
+//     LLoadFunctionPrototype
 //     LNumberTagD
 //     LNumberTagI
 //     LPushArgument
@@ -164,7 +166,6 @@
   V(ArgumentsLength)                            \
   V(ArithmeticD)                                \
   V(ArithmeticT)                                \
-  V(ArrayLength)                                \
   V(ArrayLiteral)                               \
   V(BitI)                                       \
   V(BitNotI)                                    \
@@ -203,6 +204,7 @@
   V(GlobalObject)                               \
   V(GlobalReceiver)                             \
   V(Goto)                                       \
+  V(FixedArrayLength)                           \
   V(InstanceOf)                                 \
   V(InstanceOfAndBranch)                        \
   V(Integer32ToDouble)                          \
@@ -212,6 +214,7 @@
   V(IsObjectAndBranch)                          \
   V(IsSmi)                                      \
   V(IsSmiAndBranch)                             \
+  V(JSArrayLength)                              \
   V(HasInstanceType)                            \
   V(HasInstanceTypeAndBranch)                   \
   V(HasCachedArrayIndex)                        \
@@ -226,6 +229,7 @@
   V(LoadKeyedGeneric)                           \
   V(LoadNamedField)                             \
   V(LoadNamedGeneric)                           \
+  V(LoadFunctionPrototype)                      \
   V(ModI)                                       \
   V(MulI)                                       \
   V(NumberTagD)                                 \
@@ -1146,18 +1150,21 @@
 };
 
 
-class LArrayLength: public LUnaryOperation {
+class LJSArrayLength: public LUnaryOperation {
  public:
-  LArrayLength(LOperand* input, LOperand* temporary)
-      : LUnaryOperation(input), temporary_(temporary) { }
+  explicit LJSArrayLength(LOperand* input) : LUnaryOperation(input) { }
 
-  LOperand* temporary() const { return temporary_; }
+  DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length")
+  DECLARE_HYDROGEN_ACCESSOR(JSArrayLength)
+};
 
-  DECLARE_CONCRETE_INSTRUCTION(ArrayLength, "array-length")
-  DECLARE_HYDROGEN_ACCESSOR(ArrayLength)
 
- private:
-  LOperand* temporary_;
+class LFixedArrayLength: public LUnaryOperation {
+ public:
+  explicit LFixedArrayLength(LOperand* input) : LUnaryOperation(input) { }
+
+  DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
+  DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
 };
 
 
@@ -1271,6 +1278,22 @@
 };
 
 
+class LLoadFunctionPrototype: public LUnaryOperation {
+ public:
+  LLoadFunctionPrototype(LOperand* function, LOperand* temporary)
+      : LUnaryOperation(function), temporary_(temporary) { }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
+  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
+
+  LOperand* function() const { return input(); }
+  LOperand* temporary() const { return temporary_; }
+
+ private:
+  LOperand* temporary_;
+};
+
+
 class LLoadElements: public LUnaryOperation {
  public:
   explicit LLoadElements(LOperand* obj) : LUnaryOperation(obj) { }
@@ -2064,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 d435a70..1213448 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -211,9 +211,7 @@
   // If input is ASCII, don't even bother calling here if the string to
   // match contains a non-ascii character.
   if (mode_ == ASCII) {
-    for (int i = 0; i < str.length(); i++) {
-      ASSERT(str[i] <= String::kMaxAsciiCharCodeU);
-    }
+    ASSERT(String::IsAscii(str.start(), str.length()));
   }
 #endif
   int byte_length = str.length() * char_size();
@@ -654,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/json.js b/src/json.js
index 89009a9..0034176 100644
--- a/src/json.js
+++ b/src/json.js
@@ -27,11 +27,6 @@
 
 var $JSON = global.JSON;
 
-function ParseJSONUnfiltered(text) {
-  var s = $String(text);
-  return %ParseJson(s);
-}
-
 function Revive(holder, name, reviver) {
   var val = holder[name];
   if (IS_OBJECT(val)) {
@@ -58,7 +53,7 @@
 }
 
 function JSONParse(text, reviver) {
-  var unfiltered = ParseJSONUnfiltered(text);
+  var unfiltered = %ParseJson(TO_STRING_INLINE(text));
   if (IS_FUNCTION(reviver)) {
     return Revive({'': unfiltered}, '', reviver);
   } else {
@@ -158,7 +153,7 @@
   if (IS_STRING(value)) {
     return %QuoteJSONString(value);
   } else if (IS_NUMBER(value)) {
-    return $isFinite(value) ? $String(value) : "null";
+    return NUMBER_IS_FINITE(value) ? $String(value) : "null";
   } else if (IS_BOOLEAN(value)) {
     return value ? "true" : "false";
   } else if (IS_NULL(value)) {
@@ -169,7 +164,7 @@
       return SerializeArray(value, replacer, stack, indent, gap);
     } else if (IS_NUMBER_WRAPPER(value)) {
       value = ToNumber(value);
-      return $isFinite(value) ? ToString(value) : "null";
+      return NUMBER_IS_FINITE(value) ? ToString(value) : "null";
     } else if (IS_STRING_WRAPPER(value)) {
       return %QuoteJSONString(ToString(value));
     } else if (IS_BOOLEAN_WRAPPER(value)) {
@@ -244,7 +239,7 @@
   if (IS_STRING(value)) {
     builder.push(%QuoteJSONString(value));
   } else if (IS_NUMBER(value)) {
-    builder.push(($isFinite(value) ? %_NumberToString(value) : "null"));
+    builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null");
   } else if (IS_BOOLEAN(value)) {
     builder.push(value ? "true" : "false");
   } else if (IS_NULL(value)) {
@@ -254,7 +249,7 @@
     // Unwrap value if necessary
     if (IS_NUMBER_WRAPPER(value)) {
       value = ToNumber(value);
-      builder.push(($isFinite(value) ? %_NumberToString(value) : "null"));
+      builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null");
     } else if (IS_STRING_WRAPPER(value)) {
       builder.push(%QuoteJSONString(ToString(value)));
     } else if (IS_BOOLEAN_WRAPPER(value)) {
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/liveedit-debugger.js b/src/liveedit-debugger.js
index 0f7c12d..7ed22c8 100644
--- a/src/liveedit-debugger.js
+++ b/src/liveedit-debugger.js
@@ -144,8 +144,8 @@
           replace_code_list[i].live_shared_function_infos;
 
       if (live_shared_function_infos) {
-        for (var i = 0; i < live_shared_function_infos.length; i++) {
-          replaced_function_infos.push(live_shared_function_infos[i]);
+        for (var j = 0; j < live_shared_function_infos.length; j++) {
+          replaced_function_infos.push(live_shared_function_infos[j]);
         }
       }
     }
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/macros.py b/src/macros.py
index 6d66def..01512e4 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -120,6 +120,7 @@
 
 # Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
 macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
+macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || arg - arg == 0);
 macro TO_INTEGER(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToInteger(ToNumber(arg)));
 macro TO_INTEGER_MAP_MINUS_ZERO(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : %NumberToIntegerMapMinusZero(ToNumber(arg)));
 macro TO_INT32(arg) = (%_IsSmi(%IS_VAR(arg)) ? arg : (arg >> 0));
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 55836ce..9177a6b 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -2369,7 +2369,7 @@
   if (isNaN(value)) {
     return 'NaN';
   }
-  if (!isFinite(value)) {
+  if (!NUMBER_IS_FINITE(value)) {
     if (value > 0) {
       return 'Infinity';
     } else {
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 53296d9..0b83182 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -35,34 +35,8 @@
 namespace v8 {
 namespace internal {
 
-#ifdef OBJECT_PRINT
-
-static const char* TypeToString(InstanceType type);
-
-
-void MaybeObject::Print(FILE* out) {
-  Object* this_as_object;
-  if (ToObject(&this_as_object)) {
-    if (this_as_object->IsSmi()) {
-      Smi::cast(this_as_object)->SmiPrint(out);
-    } else {
-      HeapObject::cast(this_as_object)->HeapObjectPrint(out);
-    }
-  } else {
-    Failure::cast(this)->FailurePrint(out);
-  }
-  Flush(out);
-}
-
-
-void MaybeObject::PrintLn(FILE* out) {
-  Print(out);
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
 #ifdef DEBUG
+
 void MaybeObject::Verify() {
   Object* this_as_object;
   if (ToObject(&this_as_object)) {
@@ -94,120 +68,8 @@
 void Failure::FailureVerify() {
   ASSERT(IsFailure());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void HeapObject::PrintHeader(FILE* out, const char* id) {
-  PrintF(out, "%p: [%s]\n", reinterpret_cast<void*>(this), id);
-}
-
-
-void HeapObject::HeapObjectPrint(FILE* out) {
-  InstanceType instance_type = map()->instance_type();
-
-  HandleScope scope;
-  if (instance_type < FIRST_NONSTRING_TYPE) {
-    String::cast(this)->StringPrint(out);
-    return;
-  }
-
-  switch (instance_type) {
-    case MAP_TYPE:
-      Map::cast(this)->MapPrint(out);
-      break;
-    case HEAP_NUMBER_TYPE:
-      HeapNumber::cast(this)->HeapNumberPrint(out);
-      break;
-    case FIXED_ARRAY_TYPE:
-      FixedArray::cast(this)->FixedArrayPrint(out);
-      break;
-    case BYTE_ARRAY_TYPE:
-      ByteArray::cast(this)->ByteArrayPrint(out);
-      break;
-    case PIXEL_ARRAY_TYPE:
-      PixelArray::cast(this)->PixelArrayPrint(out);
-      break;
-    case EXTERNAL_BYTE_ARRAY_TYPE:
-      ExternalByteArray::cast(this)->ExternalByteArrayPrint(out);
-      break;
-    case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
-      ExternalUnsignedByteArray::cast(this)
-          ->ExternalUnsignedByteArrayPrint(out);
-      break;
-    case EXTERNAL_SHORT_ARRAY_TYPE:
-      ExternalShortArray::cast(this)->ExternalShortArrayPrint(out);
-      break;
-    case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
-      ExternalUnsignedShortArray::cast(this)
-          ->ExternalUnsignedShortArrayPrint(out);
-      break;
-    case EXTERNAL_INT_ARRAY_TYPE:
-      ExternalIntArray::cast(this)->ExternalIntArrayPrint(out);
-      break;
-    case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
-      ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayPrint(out);
-      break;
-    case EXTERNAL_FLOAT_ARRAY_TYPE:
-      ExternalFloatArray::cast(this)->ExternalFloatArrayPrint(out);
-      break;
-    case FILLER_TYPE:
-      PrintF(out, "filler");
-      break;
-    case JS_OBJECT_TYPE:  // fall through
-    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
-    case JS_ARRAY_TYPE:
-    case JS_REGEXP_TYPE:
-      JSObject::cast(this)->JSObjectPrint(out);
-      break;
-    case ODDBALL_TYPE:
-      Oddball::cast(this)->to_string()->Print(out);
-      break;
-    case JS_FUNCTION_TYPE:
-      JSFunction::cast(this)->JSFunctionPrint(out);
-      break;
-    case JS_GLOBAL_PROXY_TYPE:
-      JSGlobalProxy::cast(this)->JSGlobalProxyPrint(out);
-      break;
-    case JS_GLOBAL_OBJECT_TYPE:
-      JSGlobalObject::cast(this)->JSGlobalObjectPrint(out);
-      break;
-    case JS_BUILTINS_OBJECT_TYPE:
-      JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(out);
-      break;
-    case JS_VALUE_TYPE:
-      PrintF(out, "Value wrapper around:");
-      JSValue::cast(this)->value()->Print(out);
-      break;
-    case CODE_TYPE:
-      Code::cast(this)->CodePrint(out);
-      break;
-    case PROXY_TYPE:
-      Proxy::cast(this)->ProxyPrint(out);
-      break;
-    case SHARED_FUNCTION_INFO_TYPE:
-      SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(out);
-      break;
-    case JS_GLOBAL_PROPERTY_CELL_TYPE:
-      JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint(out);
-      break;
-#define MAKE_STRUCT_CASE(NAME, Name, name) \
-  case NAME##_TYPE:                        \
-    Name::cast(this)->Name##Print(out);    \
-    break;
-  STRUCT_LIST(MAKE_STRUCT_CASE)
-#undef MAKE_STRUCT_CASE
-
-    default:
-      PrintF(out, "UNKNOWN TYPE %d", map()->instance_type());
-      UNREACHABLE();
-      break;
-  }
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void HeapObject::HeapObjectVerify() {
   InstanceType instance_type = map()->instance_type();
 
@@ -320,57 +182,8 @@
 void HeapNumber::HeapNumberVerify() {
   ASSERT(IsHeapNumber());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void ByteArray::ByteArrayPrint(FILE* out) {
-  PrintF(out, "byte array, data starts at %p", GetDataStartAddress());
-}
-
-
-void PixelArray::PixelArrayPrint(FILE* out) {
-  PrintF(out, "pixel array");
-}
-
-
-void ExternalByteArray::ExternalByteArrayPrint(FILE* out) {
-  PrintF(out, "external byte array");
-}
-
-
-void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint(FILE* out) {
-  PrintF(out, "external unsigned byte array");
-}
-
-
-void ExternalShortArray::ExternalShortArrayPrint(FILE* out) {
-  PrintF(out, "external short array");
-}
-
-
-void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint(FILE* out) {
-  PrintF(out, "external unsigned short array");
-}
-
-
-void ExternalIntArray::ExternalIntArrayPrint(FILE* out) {
-  PrintF(out, "external int array");
-}
-
-
-void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint(FILE* out) {
-  PrintF(out, "external unsigned int array");
-}
-
-
-void ExternalFloatArray::ExternalFloatArrayPrint(FILE* out) {
-  PrintF(out, "external float array");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void ByteArray::ByteArrayVerify() {
   ASSERT(IsByteArray());
 }
@@ -414,146 +227,8 @@
 void ExternalFloatArray::ExternalFloatArrayVerify() {
   ASSERT(IsExternalFloatArray());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void JSObject::PrintProperties(FILE* out) {
-  if (HasFastProperties()) {
-    DescriptorArray* descs = map()->instance_descriptors();
-    for (int i = 0; i < descs->number_of_descriptors(); i++) {
-      PrintF(out, "   ");
-      descs->GetKey(i)->StringPrint(out);
-      PrintF(out, ": ");
-      switch (descs->GetType(i)) {
-        case FIELD: {
-          int index = descs->GetFieldIndex(i);
-          FastPropertyAt(index)->ShortPrint(out);
-          PrintF(out, " (field at offset %d)\n", index);
-          break;
-        }
-        case CONSTANT_FUNCTION:
-          descs->GetConstantFunction(i)->ShortPrint(out);
-          PrintF(out, " (constant function)\n");
-          break;
-        case CALLBACKS:
-          descs->GetCallbacksObject(i)->ShortPrint(out);
-          PrintF(out, " (callback)\n");
-          break;
-        case MAP_TRANSITION:
-          PrintF(out, " (map transition)\n");
-          break;
-        case CONSTANT_TRANSITION:
-          PrintF(out, " (constant transition)\n");
-          break;
-        case NULL_DESCRIPTOR:
-          PrintF(out, " (null descriptor)\n");
-          break;
-        default:
-          UNREACHABLE();
-          break;
-      }
-    }
-  } else {
-    property_dictionary()->Print(out);
-  }
-}
-
-
-void JSObject::PrintElements(FILE* out) {
-  switch (GetElementsKind()) {
-    case FAST_ELEMENTS: {
-      // Print in array notation for non-sparse arrays.
-      FixedArray* p = FixedArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: ", i);
-        p->get(i)->ShortPrint(out);
-        PrintF(out, "\n");
-      }
-      break;
-    }
-    case PIXEL_ELEMENTS: {
-      PixelArray* p = PixelArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %d\n", i, p->get(i));
-      }
-      break;
-    }
-    case EXTERNAL_BYTE_ELEMENTS: {
-      ExternalByteArray* p = ExternalByteArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
-      }
-      break;
-    }
-    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
-      ExternalUnsignedByteArray* p =
-          ExternalUnsignedByteArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
-      }
-      break;
-    }
-    case EXTERNAL_SHORT_ELEMENTS: {
-      ExternalShortArray* p = ExternalShortArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
-      }
-      break;
-    }
-    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
-      ExternalUnsignedShortArray* p =
-          ExternalUnsignedShortArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
-      }
-      break;
-    }
-    case EXTERNAL_INT_ELEMENTS: {
-      ExternalIntArray* p = ExternalIntArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
-      }
-      break;
-    }
-    case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
-      ExternalUnsignedIntArray* p =
-          ExternalUnsignedIntArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
-      }
-      break;
-    }
-    case EXTERNAL_FLOAT_ELEMENTS: {
-      ExternalFloatArray* p = ExternalFloatArray::cast(elements());
-      for (int i = 0; i < p->length(); i++) {
-        PrintF(out, "   %d: %f\n", i, p->get(i));
-      }
-      break;
-    }
-    case DICTIONARY_ELEMENTS:
-      elements()->Print(out);
-      break;
-    default:
-      UNREACHABLE();
-      break;
-  }
-}
-
-
-void JSObject::JSObjectPrint(FILE* out) {
-  PrintF(out, "%p: [JSObject]\n", reinterpret_cast<void*>(this));
-  PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
-  PrintF(out, " - prototype = %p\n", reinterpret_cast<void*>(GetPrototype()));
-  PrintF(out, " {\n");
-  PrintProperties(out);
-  PrintElements(out);
-  PrintF(out, " }\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void JSObject::JSObjectVerify() {
   VerifyHeapPointer(properties());
   VerifyHeapPointer(elements());
@@ -567,103 +242,8 @@
           elements()->map() == Heap::fixed_cow_array_map()));
   ASSERT(map()->has_fast_elements() == HasFastElements());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-static const char* TypeToString(InstanceType type) {
-  switch (type) {
-    case INVALID_TYPE: return "INVALID";
-    case MAP_TYPE: return "MAP";
-    case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
-    case SYMBOL_TYPE: return "SYMBOL";
-    case ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
-    case CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
-    case CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
-    case EXTERNAL_ASCII_SYMBOL_TYPE:
-    case EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE:
-    case EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
-    case ASCII_STRING_TYPE: return "ASCII_STRING";
-    case STRING_TYPE: return "TWO_BYTE_STRING";
-    case CONS_STRING_TYPE:
-    case CONS_ASCII_STRING_TYPE: return "CONS_STRING";
-    case EXTERNAL_ASCII_STRING_TYPE:
-    case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE:
-    case EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
-    case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
-    case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
-    case PIXEL_ARRAY_TYPE: return "PIXEL_ARRAY";
-    case EXTERNAL_BYTE_ARRAY_TYPE: return "EXTERNAL_BYTE_ARRAY";
-    case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
-      return "EXTERNAL_UNSIGNED_BYTE_ARRAY";
-    case EXTERNAL_SHORT_ARRAY_TYPE: return "EXTERNAL_SHORT_ARRAY";
-    case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
-      return "EXTERNAL_UNSIGNED_SHORT_ARRAY";
-    case EXTERNAL_INT_ARRAY_TYPE: return "EXTERNAL_INT_ARRAY";
-    case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
-      return "EXTERNAL_UNSIGNED_INT_ARRAY";
-    case EXTERNAL_FLOAT_ARRAY_TYPE: return "EXTERNAL_FLOAT_ARRAY";
-    case FILLER_TYPE: return "FILLER";
-    case JS_OBJECT_TYPE: return "JS_OBJECT";
-    case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
-    case ODDBALL_TYPE: return "ODDBALL";
-    case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL";
-    case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
-    case JS_FUNCTION_TYPE: return "JS_FUNCTION";
-    case CODE_TYPE: return "CODE";
-    case JS_ARRAY_TYPE: return "JS_ARRAY";
-    case JS_REGEXP_TYPE: return "JS_REGEXP";
-    case JS_VALUE_TYPE: return "JS_VALUE";
-    case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
-    case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
-    case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
-    case PROXY_TYPE: return "PROXY";
-#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
-  STRUCT_LIST(MAKE_STRUCT_CASE)
-#undef MAKE_STRUCT_CASE
-  }
-  return "UNKNOWN";
-}
-
-
-void Map::MapPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "Map");
-  PrintF(out, " - type: %s\n", TypeToString(instance_type()));
-  PrintF(out, " - instance size: %d\n", instance_size());
-  PrintF(out, " - inobject properties: %d\n", inobject_properties());
-  PrintF(out, " - pre-allocated property fields: %d\n",
-      pre_allocated_property_fields());
-  PrintF(out, " - unused property fields: %d\n", unused_property_fields());
-  if (is_hidden_prototype()) {
-    PrintF(out, " - hidden_prototype\n");
-  }
-  if (has_named_interceptor()) {
-    PrintF(out, " - named_interceptor\n");
-  }
-  if (has_indexed_interceptor()) {
-    PrintF(out, " - indexed_interceptor\n");
-  }
-  if (is_undetectable()) {
-    PrintF(out, " - undetectable\n");
-  }
-  if (has_instance_call_handler()) {
-    PrintF(out, " - instance_call_handler\n");
-  }
-  if (is_access_check_needed()) {
-    PrintF(out, " - access_check_needed\n");
-  }
-  PrintF(out, " - instance descriptors: ");
-  instance_descriptors()->ShortPrint(out);
-  PrintF(out, "\n - prototype: ");
-  prototype()->ShortPrint(out);
-  PrintF(out, "\n - constructor: ");
-  constructor()->ShortPrint(out);
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void Map::MapVerify() {
   ASSERT(!Heap::InNewSpace(this));
   ASSERT(FIRST_TYPE <= instance_type() && instance_type() <= LAST_TYPE);
@@ -685,21 +265,8 @@
   ASSERT_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
       visitor_id());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void CodeCache::CodeCachePrint(FILE* out) {
-  HeapObject::PrintHeader(out, "CodeCache");
-  PrintF(out, "\n - default_cache: ");
-  default_cache()->ShortPrint(out);
-  PrintF(out, "\n - normal_type_cache: ");
-  normal_type_cache()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void CodeCache::CodeCacheVerify() {
   VerifyHeapPointer(default_cache());
   VerifyHeapPointer(normal_type_cache());
@@ -707,23 +274,8 @@
   ASSERT(normal_type_cache()->IsUndefined()
          || normal_type_cache()->IsCodeCacheHashTable());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void FixedArray::FixedArrayPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "FixedArray");
-  PrintF(out, " - length: %d", length());
-  for (int i = 0; i < length(); i++) {
-    PrintF(out, "\n  [%d]: ", i);
-    get(i)->ShortPrint(out);
-  }
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void FixedArray::FixedArrayVerify() {
   for (int i = 0; i < length(); i++) {
     Object* e = get(i);
@@ -734,57 +286,16 @@
     }
   }
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void JSValue::JSValuePrint(FILE* out) {
-  HeapObject::PrintHeader(out, "ValueObject");
-  value()->Print(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void JSValue::JSValueVerify() {
   Object* v = value();
   if (v->IsHeapObject()) {
     VerifyHeapPointer(v);
   }
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void String::StringPrint(FILE* out) {
-  if (StringShape(this).IsSymbol()) {
-    PrintF(out, "#");
-  } else if (StringShape(this).IsCons()) {
-    PrintF(out, "c\"");
-  } else {
-    PrintF(out, "\"");
-  }
-
-  const char truncated_epilogue[] = "...<truncated>";
-  int len = length();
-  if (!FLAG_use_verbose_printer) {
-    if (len > 100) {
-      len = 100 - sizeof(truncated_epilogue);
-    }
-  }
-  for (int i = 0; i < len; i++) {
-    PrintF(out, "%c", Get(i));
-  }
-  if (len != length()) {
-    PrintF(out, "%s", truncated_epilogue);
-  }
-
-  if (!StringShape(this).IsSymbol()) PrintF(out, "\"");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void String::StringVerify() {
   CHECK(IsString());
   CHECK(length() >= 0 && length() <= Smi::kMaxValue);
@@ -792,36 +303,8 @@
     CHECK(!Heap::InNewSpace(this));
   }
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void JSFunction::JSFunctionPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "Function");
-  PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
-  PrintF(out, " - initial_map = ");
-  if (has_initial_map()) {
-    initial_map()->ShortPrint(out);
-  }
-  PrintF(out, "\n - shared_info = ");
-  shared()->ShortPrint(out);
-  PrintF(out, "\n   - name = ");
-  shared()->name()->Print(out);
-  PrintF(out, "\n - context = ");
-  unchecked_context()->ShortPrint(out);
-  PrintF(out, "\n - code = ");
-  code()->ShortPrint(out);
-  PrintF(out, "\n");
-
-  PrintProperties(out);
-  PrintElements(out);
-
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void JSFunction::JSFunctionVerify() {
   CHECK(IsJSFunction());
   VerifyObjectField(kPrototypeOrInitialMapOffset);
@@ -829,41 +312,8 @@
   CHECK(next_function_link()->IsUndefined() ||
         next_function_link()->IsJSFunction());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "SharedFunctionInfo");
-  PrintF(out, " - name: ");
-  name()->ShortPrint(out);
-  PrintF(out, "\n - expected_nof_properties: %d", expected_nof_properties());
-  PrintF(out, "\n - instance class name = ");
-  instance_class_name()->Print(out);
-  PrintF(out, "\n - code = ");
-  code()->ShortPrint(out);
-  PrintF(out, "\n - source code = ");
-  GetSourceCode()->ShortPrint(out);
-  // Script files are often large, hard to read.
-  // PrintF(out, "\n - script =");
-  // script()->Print(out);
-  PrintF(out, "\n - function token position = %d", function_token_position());
-  PrintF(out, "\n - start position = %d", start_position());
-  PrintF(out, "\n - end position = %d", end_position());
-  PrintF(out, "\n - is expression = %d", is_expression());
-  PrintF(out, "\n - debug info = ");
-  debug_info()->ShortPrint(out);
-  PrintF(out, "\n - length = %d", length());
-  PrintF(out, "\n - has_only_simple_this_property_assignments = %d",
-         has_only_simple_this_property_assignments());
-  PrintF(out, "\n - this_property_assignments = ");
-  this_property_assignments()->ShortPrint(out);
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void SharedFunctionInfo::SharedFunctionInfoVerify() {
   CHECK(IsSharedFunctionInfo());
   VerifyObjectField(kNameOffset);
@@ -874,21 +324,8 @@
   VerifyObjectField(kScriptOffset);
   VerifyObjectField(kDebugInfoOffset);
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) {
-  PrintF(out, "global_proxy");
-  JSObjectPrint(out);
-  PrintF(out, "context : ");
-  context()->ShortPrint(out);
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void JSGlobalProxy::JSGlobalProxyVerify() {
   CHECK(IsJSGlobalProxy());
   JSObjectVerify();
@@ -898,21 +335,8 @@
   CHECK(HasFastElements());
   CHECK_EQ(0, FixedArray::cast(elements())->length());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void JSGlobalObject::JSGlobalObjectPrint(FILE* out) {
-  PrintF(out, "global ");
-  JSObjectPrint(out);
-  PrintF(out, "global context : ");
-  global_context()->ShortPrint(out);
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void JSGlobalObject::JSGlobalObjectVerify() {
   CHECK(IsJSGlobalObject());
   JSObjectVerify();
@@ -922,18 +346,8 @@
     VerifyObjectField(i);
   }
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void JSBuiltinsObject::JSBuiltinsObjectPrint(FILE* out) {
-  PrintF(out, "builtins ");
-  JSObjectPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void JSBuiltinsObject::JSBuiltinsObjectVerify() {
   CHECK(IsJSBuiltinsObject());
   JSObjectVerify();
@@ -964,27 +378,8 @@
   CHECK(IsJSGlobalPropertyCell());
   VerifyObjectField(kValueOffset);
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void JSGlobalPropertyCell::JSGlobalPropertyCellPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "JSGlobalPropertyCell");
-}
-
-
-void Code::CodePrint(FILE* out) {
-  HeapObject::PrintHeader(out, "Code");
-#ifdef ENABLE_DISASSEMBLER
-  if (FLAG_use_verbose_printer) {
-    Disassemble(NULL, out);
-  }
-#endif
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void Code::CodeVerify() {
   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
                   kCodeAlignment));
@@ -1039,17 +434,8 @@
       break;
   }
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void Proxy::ProxyPrint(FILE* out) {
-  PrintF(out, "proxy to %p", proxy());
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void Proxy::ProxyVerify() {
   ASSERT(IsProxy());
 }
@@ -1063,50 +449,16 @@
   VerifyPointer(data());
   VerifyPointer(flag());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void AccessorInfo::AccessorInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "AccessorInfo");
-  PrintF(out, "\n - getter: ");
-  getter()->ShortPrint(out);
-  PrintF(out, "\n - setter: ");
-  setter()->ShortPrint(out);
-  PrintF(out, "\n - name: ");
-  name()->ShortPrint(out);
-  PrintF(out, "\n - data: ");
-  data()->ShortPrint(out);
-  PrintF(out, "\n - flag: ");
-  flag()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void AccessCheckInfo::AccessCheckInfoVerify() {
   CHECK(IsAccessCheckInfo());
   VerifyPointer(named_callback());
   VerifyPointer(indexed_callback());
   VerifyPointer(data());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void AccessCheckInfo::AccessCheckInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "AccessCheckInfo");
-  PrintF(out, "\n - named_callback: ");
-  named_callback()->ShortPrint(out);
-  PrintF(out, "\n - indexed_callback: ");
-  indexed_callback()->ShortPrint(out);
-  PrintF(out, "\n - data: ");
-  data()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void InterceptorInfo::InterceptorInfoVerify() {
   CHECK(IsInterceptorInfo());
   VerifyPointer(getter());
@@ -1116,50 +468,15 @@
   VerifyPointer(enumerator());
   VerifyPointer(data());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void InterceptorInfo::InterceptorInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "InterceptorInfo");
-  PrintF(out, "\n - getter: ");
-  getter()->ShortPrint(out);
-  PrintF(out, "\n - setter: ");
-  setter()->ShortPrint(out);
-  PrintF(out, "\n - query: ");
-  query()->ShortPrint(out);
-  PrintF(out, "\n - deleter: ");
-  deleter()->ShortPrint(out);
-  PrintF(out, "\n - enumerator: ");
-  enumerator()->ShortPrint(out);
-  PrintF(out, "\n - data: ");
-  data()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void CallHandlerInfo::CallHandlerInfoVerify() {
   CHECK(IsCallHandlerInfo());
   VerifyPointer(callback());
   VerifyPointer(data());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void CallHandlerInfo::CallHandlerInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "CallHandlerInfo");
-  PrintF(out, "\n - callback: ");
-  callback()->ShortPrint(out);
-  PrintF(out, "\n - data: ");
-  data()->ShortPrint(out);
-  PrintF(out, "\n - call_stub_cache: ");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void TemplateInfo::TemplateInfoVerify() {
   VerifyPointer(tag());
   VerifyPointer(property_list());
@@ -1179,106 +496,29 @@
   VerifyPointer(signature());
   VerifyPointer(access_check_info());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void FunctionTemplateInfo::FunctionTemplateInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "FunctionTemplateInfo");
-  PrintF(out, "\n - class name: ");
-  class_name()->ShortPrint(out);
-  PrintF(out, "\n - tag: ");
-  tag()->ShortPrint(out);
-  PrintF(out, "\n - property_list: ");
-  property_list()->ShortPrint(out);
-  PrintF(out, "\n - serial_number: ");
-  serial_number()->ShortPrint(out);
-  PrintF(out, "\n - call_code: ");
-  call_code()->ShortPrint(out);
-  PrintF(out, "\n - property_accessors: ");
-  property_accessors()->ShortPrint(out);
-  PrintF(out, "\n - prototype_template: ");
-  prototype_template()->ShortPrint(out);
-  PrintF(out, "\n - parent_template: ");
-  parent_template()->ShortPrint(out);
-  PrintF(out, "\n - named_property_handler: ");
-  named_property_handler()->ShortPrint(out);
-  PrintF(out, "\n - indexed_property_handler: ");
-  indexed_property_handler()->ShortPrint(out);
-  PrintF(out, "\n - instance_template: ");
-  instance_template()->ShortPrint(out);
-  PrintF(out, "\n - signature: ");
-  signature()->ShortPrint(out);
-  PrintF(out, "\n - access_check_info: ");
-  access_check_info()->ShortPrint(out);
-  PrintF(out, "\n - hidden_prototype: %s",
-         hidden_prototype() ? "true" : "false");
-  PrintF(out, "\n - undetectable: %s", undetectable() ? "true" : "false");
-  PrintF(out, "\n - need_access_check: %s",
-         needs_access_check() ? "true" : "false");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void ObjectTemplateInfo::ObjectTemplateInfoVerify() {
   CHECK(IsObjectTemplateInfo());
   TemplateInfoVerify();
   VerifyPointer(constructor());
   VerifyPointer(internal_field_count());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void ObjectTemplateInfo::ObjectTemplateInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "ObjectTemplateInfo");
-  PrintF(out, "\n - constructor: ");
-  constructor()->ShortPrint(out);
-  PrintF(out, "\n - internal_field_count: ");
-  internal_field_count()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void SignatureInfo::SignatureInfoVerify() {
   CHECK(IsSignatureInfo());
   VerifyPointer(receiver());
   VerifyPointer(args());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void SignatureInfo::SignatureInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "SignatureInfo");
-  PrintF(out, "\n - receiver: ");
-  receiver()->ShortPrint(out);
-  PrintF(out, "\n - args: ");
-  args()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void TypeSwitchInfo::TypeSwitchInfoVerify() {
   CHECK(IsTypeSwitchInfo());
   VerifyPointer(types());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void TypeSwitchInfo::TypeSwitchInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "TypeSwitchInfo");
-  PrintF(out, "\n - types: ");
-  types()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void Script::ScriptVerify() {
   CHECK(IsScript());
   VerifyPointer(source());
@@ -1291,45 +531,9 @@
   VerifyPointer(line_ends());
   VerifyPointer(id());
 }
-#endif  // DEBUG
-
-
-#ifdef OBJECT_PRINT
-void Script::ScriptPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "Script");
-  PrintF(out, "\n - source: ");
-  source()->ShortPrint(out);
-  PrintF(out, "\n - name: ");
-  name()->ShortPrint(out);
-  PrintF(out, "\n - line_offset: ");
-  line_offset()->ShortPrint(out);
-  PrintF(out, "\n - column_offset: ");
-  column_offset()->ShortPrint(out);
-  PrintF(out, "\n - type: ");
-  type()->ShortPrint(out);
-  PrintF(out, "\n - id: ");
-  id()->ShortPrint(out);
-  PrintF(out, "\n - data: ");
-  data()->ShortPrint(out);
-  PrintF(out, "\n - context data: ");
-  context_data()->ShortPrint(out);
-  PrintF(out, "\n - wrapper: ");
-  wrapper()->ShortPrint(out);
-  PrintF(out, "\n - compilation type: ");
-  compilation_type()->ShortPrint(out);
-  PrintF(out, "\n - line ends: ");
-  line_ends()->ShortPrint(out);
-  PrintF(out, "\n - eval from shared: ");
-  eval_from_shared()->ShortPrint(out);
-  PrintF(out, "\n - eval from instructions offset: ");
-  eval_from_instructions_offset()->ShortPrint(out);
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
 
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
-#ifdef DEBUG
 void DebugInfo::DebugInfoVerify() {
   CHECK(IsDebugInfo());
   VerifyPointer(shared());
@@ -1337,25 +541,8 @@
   VerifyPointer(code());
   VerifyPointer(break_points());
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void DebugInfo::DebugInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "DebugInfo");
-  PrintF(out, "\n - shared: ");
-  shared()->ShortPrint(out);
-  PrintF(out, "\n - original_code: ");
-  original_code()->ShortPrint(out);
-  PrintF(out, "\n - code: ");
-  code()->ShortPrint(out);
-  PrintF(out, "\n - break_points: ");
-  break_points()->Print(out);
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 void BreakPointInfo::BreakPointInfoVerify() {
   CHECK(IsBreakPointInfo());
   code_position()->SmiVerify();
@@ -1363,23 +550,9 @@
   statement_position()->SmiVerify();
   VerifyPointer(break_point_objects());
 }
-#endif  // DEBUG
-
-
-#ifdef OBJECT_PRINT
-void BreakPointInfo::BreakPointInfoPrint(FILE* out) {
-  HeapObject::PrintHeader(out, "BreakPointInfo");
-  PrintF(out, "\n - code_position: %d", code_position()->value());
-  PrintF(out, "\n - source_position: %d", source_position()->value());
-  PrintF(out, "\n - statement_position: %d", statement_position()->value());
-  PrintF(out, "\n - break_point_objects: ");
-  break_point_objects()->ShortPrint(out);
-}
-#endif  // OBJECT_PRINT
 #endif  // ENABLE_DEBUGGER_SUPPORT
 
 
-#ifdef DEBUG
 void JSObject::IncrementSpillStatistics(SpillInformation* info) {
   info->number_of_objects_++;
   // Named properties
@@ -1462,24 +635,8 @@
 
   PrintF("\n");
 }
-#endif  // DEBUG
 
 
-#ifdef OBJECT_PRINT
-void DescriptorArray::PrintDescriptors(FILE* out) {
-  PrintF(out, "Descriptor array  %d\n", number_of_descriptors());
-  for (int i = 0; i < number_of_descriptors(); i++) {
-    PrintF(out, " %d: ", i);
-    Descriptor desc;
-    Get(i, &desc);
-    desc.Print(out);
-  }
-  PrintF(out, "\n");
-}
-#endif  // OBJECT_PRINT
-
-
-#ifdef DEBUG
 bool DescriptorArray::IsSortedNoDuplicates() {
   String* current_key = NULL;
   uint32_t current = 0;
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
new file mode 100644
index 0000000..9879da2
--- /dev/null
+++ b/src/objects-printer.cc
@@ -0,0 +1,778 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "disassembler.h"
+#include "disasm.h"
+#include "jsregexp.h"
+#include "objects-visiting.h"
+
+namespace v8 {
+namespace internal {
+
+#ifdef OBJECT_PRINT
+
+static const char* TypeToString(InstanceType type);
+
+
+void MaybeObject::Print(FILE* out) {
+  Object* this_as_object;
+  if (ToObject(&this_as_object)) {
+    if (this_as_object->IsSmi()) {
+      Smi::cast(this_as_object)->SmiPrint(out);
+    } else {
+      HeapObject::cast(this_as_object)->HeapObjectPrint(out);
+    }
+  } else {
+    Failure::cast(this)->FailurePrint(out);
+  }
+  Flush(out);
+}
+
+
+void MaybeObject::PrintLn(FILE* out) {
+  Print(out);
+  PrintF(out, "\n");
+}
+
+
+void HeapObject::PrintHeader(FILE* out, const char* id) {
+  PrintF(out, "%p: [%s]\n", reinterpret_cast<void*>(this), id);
+}
+
+
+void HeapObject::HeapObjectPrint(FILE* out) {
+  InstanceType instance_type = map()->instance_type();
+
+  HandleScope scope;
+  if (instance_type < FIRST_NONSTRING_TYPE) {
+    String::cast(this)->StringPrint(out);
+    return;
+  }
+
+  switch (instance_type) {
+    case MAP_TYPE:
+      Map::cast(this)->MapPrint(out);
+      break;
+    case HEAP_NUMBER_TYPE:
+      HeapNumber::cast(this)->HeapNumberPrint(out);
+      break;
+    case FIXED_ARRAY_TYPE:
+      FixedArray::cast(this)->FixedArrayPrint(out);
+      break;
+    case BYTE_ARRAY_TYPE:
+      ByteArray::cast(this)->ByteArrayPrint(out);
+      break;
+    case PIXEL_ARRAY_TYPE:
+      PixelArray::cast(this)->PixelArrayPrint(out);
+      break;
+    case EXTERNAL_BYTE_ARRAY_TYPE:
+      ExternalByteArray::cast(this)->ExternalByteArrayPrint(out);
+      break;
+    case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
+      ExternalUnsignedByteArray::cast(this)
+          ->ExternalUnsignedByteArrayPrint(out);
+      break;
+    case EXTERNAL_SHORT_ARRAY_TYPE:
+      ExternalShortArray::cast(this)->ExternalShortArrayPrint(out);
+      break;
+    case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
+      ExternalUnsignedShortArray::cast(this)
+          ->ExternalUnsignedShortArrayPrint(out);
+      break;
+    case EXTERNAL_INT_ARRAY_TYPE:
+      ExternalIntArray::cast(this)->ExternalIntArrayPrint(out);
+      break;
+    case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
+      ExternalUnsignedIntArray::cast(this)->ExternalUnsignedIntArrayPrint(out);
+      break;
+    case EXTERNAL_FLOAT_ARRAY_TYPE:
+      ExternalFloatArray::cast(this)->ExternalFloatArrayPrint(out);
+      break;
+    case FILLER_TYPE:
+      PrintF(out, "filler");
+      break;
+    case JS_OBJECT_TYPE:  // fall through
+    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
+    case JS_ARRAY_TYPE:
+    case JS_REGEXP_TYPE:
+      JSObject::cast(this)->JSObjectPrint(out);
+      break;
+    case ODDBALL_TYPE:
+      Oddball::cast(this)->to_string()->Print(out);
+      break;
+    case JS_FUNCTION_TYPE:
+      JSFunction::cast(this)->JSFunctionPrint(out);
+      break;
+    case JS_GLOBAL_PROXY_TYPE:
+      JSGlobalProxy::cast(this)->JSGlobalProxyPrint(out);
+      break;
+    case JS_GLOBAL_OBJECT_TYPE:
+      JSGlobalObject::cast(this)->JSGlobalObjectPrint(out);
+      break;
+    case JS_BUILTINS_OBJECT_TYPE:
+      JSBuiltinsObject::cast(this)->JSBuiltinsObjectPrint(out);
+      break;
+    case JS_VALUE_TYPE:
+      PrintF(out, "Value wrapper around:");
+      JSValue::cast(this)->value()->Print(out);
+      break;
+    case CODE_TYPE:
+      Code::cast(this)->CodePrint(out);
+      break;
+    case PROXY_TYPE:
+      Proxy::cast(this)->ProxyPrint(out);
+      break;
+    case SHARED_FUNCTION_INFO_TYPE:
+      SharedFunctionInfo::cast(this)->SharedFunctionInfoPrint(out);
+      break;
+    case JS_GLOBAL_PROPERTY_CELL_TYPE:
+      JSGlobalPropertyCell::cast(this)->JSGlobalPropertyCellPrint(out);
+      break;
+#define MAKE_STRUCT_CASE(NAME, Name, name) \
+  case NAME##_TYPE:                        \
+    Name::cast(this)->Name##Print(out);    \
+    break;
+  STRUCT_LIST(MAKE_STRUCT_CASE)
+#undef MAKE_STRUCT_CASE
+
+    default:
+      PrintF(out, "UNKNOWN TYPE %d", map()->instance_type());
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void ByteArray::ByteArrayPrint(FILE* out) {
+  PrintF(out, "byte array, data starts at %p", GetDataStartAddress());
+}
+
+
+void PixelArray::PixelArrayPrint(FILE* out) {
+  PrintF(out, "pixel array");
+}
+
+
+void ExternalByteArray::ExternalByteArrayPrint(FILE* out) {
+  PrintF(out, "external byte array");
+}
+
+
+void ExternalUnsignedByteArray::ExternalUnsignedByteArrayPrint(FILE* out) {
+  PrintF(out, "external unsigned byte array");
+}
+
+
+void ExternalShortArray::ExternalShortArrayPrint(FILE* out) {
+  PrintF(out, "external short array");
+}
+
+
+void ExternalUnsignedShortArray::ExternalUnsignedShortArrayPrint(FILE* out) {
+  PrintF(out, "external unsigned short array");
+}
+
+
+void ExternalIntArray::ExternalIntArrayPrint(FILE* out) {
+  PrintF(out, "external int array");
+}
+
+
+void ExternalUnsignedIntArray::ExternalUnsignedIntArrayPrint(FILE* out) {
+  PrintF(out, "external unsigned int array");
+}
+
+
+void ExternalFloatArray::ExternalFloatArrayPrint(FILE* out) {
+  PrintF(out, "external float array");
+}
+
+
+void JSObject::PrintProperties(FILE* out) {
+  if (HasFastProperties()) {
+    DescriptorArray* descs = map()->instance_descriptors();
+    for (int i = 0; i < descs->number_of_descriptors(); i++) {
+      PrintF(out, "   ");
+      descs->GetKey(i)->StringPrint(out);
+      PrintF(out, ": ");
+      switch (descs->GetType(i)) {
+        case FIELD: {
+          int index = descs->GetFieldIndex(i);
+          FastPropertyAt(index)->ShortPrint(out);
+          PrintF(out, " (field at offset %d)\n", index);
+          break;
+        }
+        case CONSTANT_FUNCTION:
+          descs->GetConstantFunction(i)->ShortPrint(out);
+          PrintF(out, " (constant function)\n");
+          break;
+        case CALLBACKS:
+          descs->GetCallbacksObject(i)->ShortPrint(out);
+          PrintF(out, " (callback)\n");
+          break;
+        case MAP_TRANSITION:
+          PrintF(out, " (map transition)\n");
+          break;
+        case CONSTANT_TRANSITION:
+          PrintF(out, " (constant transition)\n");
+          break;
+        case NULL_DESCRIPTOR:
+          PrintF(out, " (null descriptor)\n");
+          break;
+        default:
+          UNREACHABLE();
+          break;
+      }
+    }
+  } else {
+    property_dictionary()->Print(out);
+  }
+}
+
+
+void JSObject::PrintElements(FILE* out) {
+  switch (GetElementsKind()) {
+    case FAST_ELEMENTS: {
+      // Print in array notation for non-sparse arrays.
+      FixedArray* p = FixedArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: ", i);
+        p->get(i)->ShortPrint(out);
+        PrintF(out, "\n");
+      }
+      break;
+    }
+    case PIXEL_ELEMENTS: {
+      PixelArray* p = PixelArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %d\n", i, p->get(i));
+      }
+      break;
+    }
+    case EXTERNAL_BYTE_ELEMENTS: {
+      ExternalByteArray* p = ExternalByteArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
+      }
+      break;
+    }
+    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
+      ExternalUnsignedByteArray* p =
+          ExternalUnsignedByteArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
+      }
+      break;
+    }
+    case EXTERNAL_SHORT_ELEMENTS: {
+      ExternalShortArray* p = ExternalShortArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
+      }
+      break;
+    }
+    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
+      ExternalUnsignedShortArray* p =
+          ExternalUnsignedShortArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
+      }
+      break;
+    }
+    case EXTERNAL_INT_ELEMENTS: {
+      ExternalIntArray* p = ExternalIntArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
+      }
+      break;
+    }
+    case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
+      ExternalUnsignedIntArray* p =
+          ExternalUnsignedIntArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %d\n", i, static_cast<int>(p->get(i)));
+      }
+      break;
+    }
+    case EXTERNAL_FLOAT_ELEMENTS: {
+      ExternalFloatArray* p = ExternalFloatArray::cast(elements());
+      for (int i = 0; i < p->length(); i++) {
+        PrintF(out, "   %d: %f\n", i, p->get(i));
+      }
+      break;
+    }
+    case DICTIONARY_ELEMENTS:
+      elements()->Print(out);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void JSObject::JSObjectPrint(FILE* out) {
+  PrintF(out, "%p: [JSObject]\n", reinterpret_cast<void*>(this));
+  PrintF(out, " - map = %p\n", reinterpret_cast<void*>(map()));
+  PrintF(out, " - prototype = %p\n", reinterpret_cast<void*>(GetPrototype()));
+  PrintF(out, " {\n");
+  PrintProperties(out);
+  PrintElements(out);
+  PrintF(out, " }\n");
+}
+
+
+static const char* TypeToString(InstanceType type) {
+  switch (type) {
+    case INVALID_TYPE: return "INVALID";
+    case MAP_TYPE: return "MAP";
+    case HEAP_NUMBER_TYPE: return "HEAP_NUMBER";
+    case SYMBOL_TYPE: return "SYMBOL";
+    case ASCII_SYMBOL_TYPE: return "ASCII_SYMBOL";
+    case CONS_SYMBOL_TYPE: return "CONS_SYMBOL";
+    case CONS_ASCII_SYMBOL_TYPE: return "CONS_ASCII_SYMBOL";
+    case EXTERNAL_ASCII_SYMBOL_TYPE:
+    case EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE:
+    case EXTERNAL_SYMBOL_TYPE: return "EXTERNAL_SYMBOL";
+    case ASCII_STRING_TYPE: return "ASCII_STRING";
+    case STRING_TYPE: return "TWO_BYTE_STRING";
+    case CONS_STRING_TYPE:
+    case CONS_ASCII_STRING_TYPE: return "CONS_STRING";
+    case EXTERNAL_ASCII_STRING_TYPE:
+    case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE:
+    case EXTERNAL_STRING_TYPE: return "EXTERNAL_STRING";
+    case FIXED_ARRAY_TYPE: return "FIXED_ARRAY";
+    case BYTE_ARRAY_TYPE: return "BYTE_ARRAY";
+    case PIXEL_ARRAY_TYPE: return "PIXEL_ARRAY";
+    case EXTERNAL_BYTE_ARRAY_TYPE: return "EXTERNAL_BYTE_ARRAY";
+    case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
+      return "EXTERNAL_UNSIGNED_BYTE_ARRAY";
+    case EXTERNAL_SHORT_ARRAY_TYPE: return "EXTERNAL_SHORT_ARRAY";
+    case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
+      return "EXTERNAL_UNSIGNED_SHORT_ARRAY";
+    case EXTERNAL_INT_ARRAY_TYPE: return "EXTERNAL_INT_ARRAY";
+    case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
+      return "EXTERNAL_UNSIGNED_INT_ARRAY";
+    case EXTERNAL_FLOAT_ARRAY_TYPE: return "EXTERNAL_FLOAT_ARRAY";
+    case FILLER_TYPE: return "FILLER";
+    case JS_OBJECT_TYPE: return "JS_OBJECT";
+    case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return "JS_CONTEXT_EXTENSION_OBJECT";
+    case ODDBALL_TYPE: return "ODDBALL";
+    case JS_GLOBAL_PROPERTY_CELL_TYPE: return "JS_GLOBAL_PROPERTY_CELL";
+    case SHARED_FUNCTION_INFO_TYPE: return "SHARED_FUNCTION_INFO";
+    case JS_FUNCTION_TYPE: return "JS_FUNCTION";
+    case CODE_TYPE: return "CODE";
+    case JS_ARRAY_TYPE: return "JS_ARRAY";
+    case JS_REGEXP_TYPE: return "JS_REGEXP";
+    case JS_VALUE_TYPE: return "JS_VALUE";
+    case JS_GLOBAL_OBJECT_TYPE: return "JS_GLOBAL_OBJECT";
+    case JS_BUILTINS_OBJECT_TYPE: return "JS_BUILTINS_OBJECT";
+    case JS_GLOBAL_PROXY_TYPE: return "JS_GLOBAL_PROXY";
+    case PROXY_TYPE: return "PROXY";
+#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return #NAME;
+  STRUCT_LIST(MAKE_STRUCT_CASE)
+#undef MAKE_STRUCT_CASE
+  }
+  return "UNKNOWN";
+}
+
+
+void Map::MapPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "Map");
+  PrintF(out, " - type: %s\n", TypeToString(instance_type()));
+  PrintF(out, " - instance size: %d\n", instance_size());
+  PrintF(out, " - inobject properties: %d\n", inobject_properties());
+  PrintF(out, " - pre-allocated property fields: %d\n",
+      pre_allocated_property_fields());
+  PrintF(out, " - unused property fields: %d\n", unused_property_fields());
+  if (is_hidden_prototype()) {
+    PrintF(out, " - hidden_prototype\n");
+  }
+  if (has_named_interceptor()) {
+    PrintF(out, " - named_interceptor\n");
+  }
+  if (has_indexed_interceptor()) {
+    PrintF(out, " - indexed_interceptor\n");
+  }
+  if (is_undetectable()) {
+    PrintF(out, " - undetectable\n");
+  }
+  if (has_instance_call_handler()) {
+    PrintF(out, " - instance_call_handler\n");
+  }
+  if (is_access_check_needed()) {
+    PrintF(out, " - access_check_needed\n");
+  }
+  PrintF(out, " - instance descriptors: ");
+  instance_descriptors()->ShortPrint(out);
+  PrintF(out, "\n - prototype: ");
+  prototype()->ShortPrint(out);
+  PrintF(out, "\n - constructor: ");
+  constructor()->ShortPrint(out);
+  PrintF(out, "\n");
+}
+
+
+void CodeCache::CodeCachePrint(FILE* out) {
+  HeapObject::PrintHeader(out, "CodeCache");
+  PrintF(out, "\n - default_cache: ");
+  default_cache()->ShortPrint(out);
+  PrintF(out, "\n - normal_type_cache: ");
+  normal_type_cache()->ShortPrint(out);
+}
+
+
+void FixedArray::FixedArrayPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "FixedArray");
+  PrintF(out, " - length: %d", length());
+  for (int i = 0; i < length(); i++) {
+    PrintF(out, "\n  [%d]: ", i);
+    get(i)->ShortPrint(out);
+  }
+  PrintF(out, "\n");
+}
+
+
+void JSValue::JSValuePrint(FILE* out) {
+  HeapObject::PrintHeader(out, "ValueObject");
+  value()->Print(out);
+}
+
+
+void String::StringPrint(FILE* out) {
+  if (StringShape(this).IsSymbol()) {
+    PrintF(out, "#");
+  } else if (StringShape(this).IsCons()) {
+    PrintF(out, "c\"");
+  } else {
+    PrintF(out, "\"");
+  }
+
+  const char truncated_epilogue[] = "...<truncated>";
+  int len = length();
+  if (!FLAG_use_verbose_printer) {
+    if (len > 100) {
+      len = 100 - sizeof(truncated_epilogue);
+    }
+  }
+  for (int i = 0; i < len; i++) {
+    PrintF(out, "%c", Get(i));
+  }
+  if (len != length()) {
+    PrintF(out, "%s", truncated_epilogue);
+  }
+
+  if (!StringShape(this).IsSymbol()) PrintF(out, "\"");
+}
+
+
+void JSFunction::JSFunctionPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "Function");
+  PrintF(out, " - map = 0x%p\n", reinterpret_cast<void*>(map()));
+  PrintF(out, " - initial_map = ");
+  if (has_initial_map()) {
+    initial_map()->ShortPrint(out);
+  }
+  PrintF(out, "\n - shared_info = ");
+  shared()->ShortPrint(out);
+  PrintF(out, "\n   - name = ");
+  shared()->name()->Print(out);
+  PrintF(out, "\n - context = ");
+  unchecked_context()->ShortPrint(out);
+  PrintF(out, "\n - code = ");
+  code()->ShortPrint(out);
+  PrintF(out, "\n");
+
+  PrintProperties(out);
+  PrintElements(out);
+
+  PrintF(out, "\n");
+}
+
+
+void SharedFunctionInfo::SharedFunctionInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "SharedFunctionInfo");
+  PrintF(out, " - name: ");
+  name()->ShortPrint(out);
+  PrintF(out, "\n - expected_nof_properties: %d", expected_nof_properties());
+  PrintF(out, "\n - instance class name = ");
+  instance_class_name()->Print(out);
+  PrintF(out, "\n - code = ");
+  code()->ShortPrint(out);
+  PrintF(out, "\n - source code = ");
+  GetSourceCode()->ShortPrint(out);
+  // Script files are often large, hard to read.
+  // PrintF(out, "\n - script =");
+  // script()->Print(out);
+  PrintF(out, "\n - function token position = %d", function_token_position());
+  PrintF(out, "\n - start position = %d", start_position());
+  PrintF(out, "\n - end position = %d", end_position());
+  PrintF(out, "\n - is expression = %d", is_expression());
+  PrintF(out, "\n - debug info = ");
+  debug_info()->ShortPrint(out);
+  PrintF(out, "\n - length = %d", length());
+  PrintF(out, "\n - has_only_simple_this_property_assignments = %d",
+         has_only_simple_this_property_assignments());
+  PrintF(out, "\n - this_property_assignments = ");
+  this_property_assignments()->ShortPrint(out);
+  PrintF(out, "\n");
+}
+
+
+void JSGlobalProxy::JSGlobalProxyPrint(FILE* out) {
+  PrintF(out, "global_proxy");
+  JSObjectPrint(out);
+  PrintF(out, "context : ");
+  context()->ShortPrint(out);
+  PrintF(out, "\n");
+}
+
+
+void JSGlobalObject::JSGlobalObjectPrint(FILE* out) {
+  PrintF(out, "global ");
+  JSObjectPrint(out);
+  PrintF(out, "global context : ");
+  global_context()->ShortPrint(out);
+  PrintF(out, "\n");
+}
+
+
+void JSBuiltinsObject::JSBuiltinsObjectPrint(FILE* out) {
+  PrintF(out, "builtins ");
+  JSObjectPrint(out);
+}
+
+
+void JSGlobalPropertyCell::JSGlobalPropertyCellPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "JSGlobalPropertyCell");
+}
+
+
+void Code::CodePrint(FILE* out) {
+  HeapObject::PrintHeader(out, "Code");
+#ifdef ENABLE_DISASSEMBLER
+  if (FLAG_use_verbose_printer) {
+    Disassemble(NULL, out);
+  }
+#endif
+}
+
+
+void Proxy::ProxyPrint(FILE* out) {
+  PrintF(out, "proxy to %p", proxy());
+}
+
+
+void AccessorInfo::AccessorInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "AccessorInfo");
+  PrintF(out, "\n - getter: ");
+  getter()->ShortPrint(out);
+  PrintF(out, "\n - setter: ");
+  setter()->ShortPrint(out);
+  PrintF(out, "\n - name: ");
+  name()->ShortPrint(out);
+  PrintF(out, "\n - data: ");
+  data()->ShortPrint(out);
+  PrintF(out, "\n - flag: ");
+  flag()->ShortPrint(out);
+}
+
+
+void AccessCheckInfo::AccessCheckInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "AccessCheckInfo");
+  PrintF(out, "\n - named_callback: ");
+  named_callback()->ShortPrint(out);
+  PrintF(out, "\n - indexed_callback: ");
+  indexed_callback()->ShortPrint(out);
+  PrintF(out, "\n - data: ");
+  data()->ShortPrint(out);
+}
+
+
+void InterceptorInfo::InterceptorInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "InterceptorInfo");
+  PrintF(out, "\n - getter: ");
+  getter()->ShortPrint(out);
+  PrintF(out, "\n - setter: ");
+  setter()->ShortPrint(out);
+  PrintF(out, "\n - query: ");
+  query()->ShortPrint(out);
+  PrintF(out, "\n - deleter: ");
+  deleter()->ShortPrint(out);
+  PrintF(out, "\n - enumerator: ");
+  enumerator()->ShortPrint(out);
+  PrintF(out, "\n - data: ");
+  data()->ShortPrint(out);
+}
+
+
+void CallHandlerInfo::CallHandlerInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "CallHandlerInfo");
+  PrintF(out, "\n - callback: ");
+  callback()->ShortPrint(out);
+  PrintF(out, "\n - data: ");
+  data()->ShortPrint(out);
+  PrintF(out, "\n - call_stub_cache: ");
+}
+
+
+void FunctionTemplateInfo::FunctionTemplateInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "FunctionTemplateInfo");
+  PrintF(out, "\n - class name: ");
+  class_name()->ShortPrint(out);
+  PrintF(out, "\n - tag: ");
+  tag()->ShortPrint(out);
+  PrintF(out, "\n - property_list: ");
+  property_list()->ShortPrint(out);
+  PrintF(out, "\n - serial_number: ");
+  serial_number()->ShortPrint(out);
+  PrintF(out, "\n - call_code: ");
+  call_code()->ShortPrint(out);
+  PrintF(out, "\n - property_accessors: ");
+  property_accessors()->ShortPrint(out);
+  PrintF(out, "\n - prototype_template: ");
+  prototype_template()->ShortPrint(out);
+  PrintF(out, "\n - parent_template: ");
+  parent_template()->ShortPrint(out);
+  PrintF(out, "\n - named_property_handler: ");
+  named_property_handler()->ShortPrint(out);
+  PrintF(out, "\n - indexed_property_handler: ");
+  indexed_property_handler()->ShortPrint(out);
+  PrintF(out, "\n - instance_template: ");
+  instance_template()->ShortPrint(out);
+  PrintF(out, "\n - signature: ");
+  signature()->ShortPrint(out);
+  PrintF(out, "\n - access_check_info: ");
+  access_check_info()->ShortPrint(out);
+  PrintF(out, "\n - hidden_prototype: %s",
+         hidden_prototype() ? "true" : "false");
+  PrintF(out, "\n - undetectable: %s", undetectable() ? "true" : "false");
+  PrintF(out, "\n - need_access_check: %s",
+         needs_access_check() ? "true" : "false");
+}
+
+
+void ObjectTemplateInfo::ObjectTemplateInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "ObjectTemplateInfo");
+  PrintF(out, "\n - constructor: ");
+  constructor()->ShortPrint(out);
+  PrintF(out, "\n - internal_field_count: ");
+  internal_field_count()->ShortPrint(out);
+}
+
+
+void SignatureInfo::SignatureInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "SignatureInfo");
+  PrintF(out, "\n - receiver: ");
+  receiver()->ShortPrint(out);
+  PrintF(out, "\n - args: ");
+  args()->ShortPrint(out);
+}
+
+
+void TypeSwitchInfo::TypeSwitchInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "TypeSwitchInfo");
+  PrintF(out, "\n - types: ");
+  types()->ShortPrint(out);
+}
+
+
+void Script::ScriptPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "Script");
+  PrintF(out, "\n - source: ");
+  source()->ShortPrint(out);
+  PrintF(out, "\n - name: ");
+  name()->ShortPrint(out);
+  PrintF(out, "\n - line_offset: ");
+  line_offset()->ShortPrint(out);
+  PrintF(out, "\n - column_offset: ");
+  column_offset()->ShortPrint(out);
+  PrintF(out, "\n - type: ");
+  type()->ShortPrint(out);
+  PrintF(out, "\n - id: ");
+  id()->ShortPrint(out);
+  PrintF(out, "\n - data: ");
+  data()->ShortPrint(out);
+  PrintF(out, "\n - context data: ");
+  context_data()->ShortPrint(out);
+  PrintF(out, "\n - wrapper: ");
+  wrapper()->ShortPrint(out);
+  PrintF(out, "\n - compilation type: ");
+  compilation_type()->ShortPrint(out);
+  PrintF(out, "\n - line ends: ");
+  line_ends()->ShortPrint(out);
+  PrintF(out, "\n - eval from shared: ");
+  eval_from_shared()->ShortPrint(out);
+  PrintF(out, "\n - eval from instructions offset: ");
+  eval_from_instructions_offset()->ShortPrint(out);
+  PrintF(out, "\n");
+}
+
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void DebugInfo::DebugInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "DebugInfo");
+  PrintF(out, "\n - shared: ");
+  shared()->ShortPrint(out);
+  PrintF(out, "\n - original_code: ");
+  original_code()->ShortPrint(out);
+  PrintF(out, "\n - code: ");
+  code()->ShortPrint(out);
+  PrintF(out, "\n - break_points: ");
+  break_points()->Print(out);
+}
+
+
+void BreakPointInfo::BreakPointInfoPrint(FILE* out) {
+  HeapObject::PrintHeader(out, "BreakPointInfo");
+  PrintF(out, "\n - code_position: %d", code_position()->value());
+  PrintF(out, "\n - source_position: %d", source_position()->value());
+  PrintF(out, "\n - statement_position: %d", statement_position()->value());
+  PrintF(out, "\n - break_point_objects: ");
+  break_point_objects()->ShortPrint(out);
+}
+#endif  // ENABLE_DEBUGGER_SUPPORT
+
+
+void DescriptorArray::PrintDescriptors(FILE* out) {
+  PrintF(out, "Descriptor array  %d\n", number_of_descriptors());
+  for (int i = 0; i < number_of_descriptors(); i++) {
+    PrintF(out, " %d: ", i);
+    Descriptor desc;
+    Get(i, &desc);
+    desc.Print(out);
+  }
+  PrintF(out, "\n");
+}
+
+
+#endif  // OBJECT_PRINT
+
+
+} }  // namespace v8::internal
diff --git a/src/objects-visiting.h b/src/objects-visiting.h
index 55a0a53..6510ca8 100644
--- a/src/objects-visiting.h
+++ b/src/objects-visiting.h
@@ -186,9 +186,9 @@
 template<typename StaticVisitor>
 class BodyVisitorBase : public AllStatic {
  public:
-  static inline void IteratePointers(HeapObject* object,
+  INLINE(static void IteratePointers(HeapObject* object,
                                      int start_offset,
-                                     int end_offset) {
+                                     int end_offset)) {
     Object** start_slot = reinterpret_cast<Object**>(object->address() +
                                                      start_offset);
     Object** end_slot = reinterpret_cast<Object**>(object->address() +
diff --git a/src/objects.cc b/src/objects.cc
index ab2f964..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()) {
@@ -5143,6 +5142,26 @@
 }
 
 
+bool String::IsAsciiEqualTo(Vector<const char> str) {
+  int slen = length();
+  if (str.length() != slen) return false;
+  for (int i = 0; i < slen; i++) {
+    if (Get(i) != static_cast<uint16_t>(str[i])) return false;
+  }
+  return true;
+}
+
+
+bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
+  int slen = length();
+  if (str.length() != slen) return false;
+  for (int i = 0; i < slen; i++) {
+    if (Get(i) != str[i]) return false;
+  }
+  return true;
+}
+
+
 template <typename schar>
 static inline uint32_t HashSequentialString(const schar* chars, int length) {
   StringHasher hasher(length);
@@ -6775,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;
@@ -6799,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;
 }
@@ -6910,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;
@@ -6920,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);
@@ -6963,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)) {
@@ -6981,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);
@@ -7051,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).
@@ -8086,6 +8113,85 @@
 };
 
 
+template <typename Char>
+class SequentialSymbolKey : public HashTableKey {
+ public:
+  explicit SequentialSymbolKey(Vector<const Char> string)
+      : string_(string), hash_field_(0) { }
+
+  uint32_t Hash() {
+    StringHasher hasher(string_.length());
+
+    // Very long strings have a trivial hash that doesn't inspect the
+    // string contents.
+    if (hasher.has_trivial_hash()) {
+      hash_field_ = hasher.GetHashField();
+    } else {
+      int i = 0;
+      // Do the iterative array index computation as long as there is a
+      // chance this is an array index.
+      while (i < string_.length() && hasher.is_array_index()) {
+        hasher.AddCharacter(static_cast<uc32>(string_[i]));
+        i++;
+      }
+
+      // Process the remaining characters without updating the array
+      // index.
+      while (i < string_.length()) {
+        hasher.AddCharacterNoIndex(static_cast<uc32>(string_[i]));
+        i++;
+      }
+      hash_field_ = hasher.GetHashField();
+    }
+
+    uint32_t result = hash_field_ >> String::kHashShift;
+    ASSERT(result != 0);  // Ensure that the hash value of 0 is never computed.
+    return result;
+  }
+
+
+  uint32_t HashForObject(Object* other) {
+    return String::cast(other)->Hash();
+  }
+
+  Vector<const Char> string_;
+  uint32_t hash_field_;
+};
+
+
+
+class AsciiSymbolKey : public SequentialSymbolKey<char> {
+ public:
+  explicit AsciiSymbolKey(Vector<const char> str)
+      : SequentialSymbolKey<char>(str) { }
+
+  bool IsMatch(Object* string) {
+    return String::cast(string)->IsAsciiEqualTo(string_);
+  }
+
+  MaybeObject* AsObject() {
+    if (hash_field_ == 0) Hash();
+    return Heap::AllocateAsciiSymbol(string_, hash_field_);
+  }
+};
+
+
+class TwoByteSymbolKey : public SequentialSymbolKey<uc16> {
+ public:
+  explicit TwoByteSymbolKey(Vector<const uc16> str)
+      : SequentialSymbolKey<uc16>(str) { }
+
+  bool IsMatch(Object* string) {
+    return String::cast(string)->IsTwoByteEqualTo(string_);
+  }
+
+  MaybeObject* AsObject() {
+    if (hash_field_ == 0) Hash();
+    return Heap::AllocateTwoByteSymbol(string_, hash_field_);
+  }
+};
+
+
 // SymbolKey carries a string/symbol object as key.
 class SymbolKey : public HashTableKey {
  public:
@@ -8830,6 +8936,19 @@
 }
 
 
+MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str,
+                                            Object** s) {
+  AsciiSymbolKey key(str);
+  return LookupKey(&key, s);
+}
+
+
+MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str,
+                                              Object** s) {
+  TwoByteSymbolKey key(str);
+  return LookupKey(&key, s);
+}
+
 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
   int entry = FindEntry(key);
 
diff --git a/src/objects.h b/src/objects.h
index c5fda7d..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);
 
@@ -2327,6 +2334,10 @@
   // been enlarged.  If the return value is not a failure, the symbol
   // pointer *s is set to the symbol found.
   MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str, Object** s);
+  MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str,
+                                                 Object** s);
+  MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str,
+                                                   Object** s);
   MUST_USE_RESULT MaybeObject* LookupString(String* key, Object** s);
 
   // Looks up a symbol that is equal to the given string and returns
@@ -5074,6 +5085,8 @@
   // String equality operations.
   inline bool Equals(String* other);
   bool IsEqualTo(Vector<const char> str);
+  bool IsAsciiEqualTo(Vector<const char> str);
+  bool IsTwoByteEqualTo(Vector<const uc16> str);
 
   // Return a UTF8 representation of the string.  The string is null
   // terminated but may optionally contain nulls.  Length is returned
@@ -5245,6 +5258,34 @@
                           int from,
                           int to);
 
+  static inline bool IsAscii(const char* chars, int length) {
+    const char* limit = chars + length;
+#ifdef V8_HOST_CAN_READ_UNALIGNED
+    ASSERT(kMaxAsciiCharCode == 0x7F);
+    const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
+    while (chars <= limit - sizeof(uintptr_t)) {
+      if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
+        return false;
+      }
+      chars += sizeof(uintptr_t);
+    }
+#endif
+    while (chars < limit) {
+      if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false;
+      ++chars;
+    }
+    return true;
+  }
+
+  static inline bool IsAscii(const uc16* chars, int length) {
+    const uc16* limit = chars + length;
+    while (chars < limit) {
+      if (*chars > kMaxAsciiCharCodeU) return false;
+      ++chars;
+    }
+    return true;
+  }
+
  protected:
   class ReadBlockBuffer {
    public:
diff --git a/src/parser.cc b/src/parser.cc
index 08f77b8..5526933 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -323,22 +323,24 @@
 }
 
 
-Handle<String> Parser::LookupSymbol(int symbol_id,
-                                    Vector<const char> string) {
+Handle<String> Parser::LookupSymbol(int symbol_id) {
   // Length of symbol cache is the number of identified symbols.
   // If we are larger than that, or negative, it's not a cached symbol.
   // This might also happen if there is no preparser symbol data, even
   // if there is some preparser data.
   if (static_cast<unsigned>(symbol_id)
       >= static_cast<unsigned>(symbol_cache_.length())) {
-    return Factory::LookupSymbol(string);
+    if (scanner().is_literal_ascii()) {
+      return Factory::LookupAsciiSymbol(scanner().literal_ascii_string());
+    } else {
+      return Factory::LookupTwoByteSymbol(scanner().literal_uc16_string());
+    }
   }
-  return LookupCachedSymbol(symbol_id, string);
+  return LookupCachedSymbol(symbol_id);
 }
 
 
-Handle<String> Parser::LookupCachedSymbol(int symbol_id,
-                                          Vector<const char> string) {
+Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
   // Make sure the cache is large enough to hold the symbol identifier.
   if (symbol_cache_.length() <= symbol_id) {
     // Increase length to index + 1.
@@ -347,7 +349,11 @@
   }
   Handle<String> result = symbol_cache_.at(symbol_id);
   if (result.is_null()) {
-    result = Factory::LookupSymbol(string);
+    if (scanner().is_literal_ascii()) {
+      result = Factory::LookupAsciiSymbol(scanner().literal_ascii_string());
+    } else {
+      result = Factory::LookupTwoByteSymbol(scanner().literal_uc16_string());
+    }
     symbol_cache_.at(symbol_id) = result;
     return result;
   }
@@ -615,11 +621,11 @@
     // identical calls.
     ExternalTwoByteStringUC16CharacterStream stream(
         Handle<ExternalTwoByteString>::cast(source), 0, source->length());
-    scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals);
+    scanner_.Initialize(&stream);
     return DoParseProgram(source, in_global_context, &zone_scope);
   } else {
     GenericStringUC16CharacterStream stream(source, 0, source->length());
-    scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals);
+    scanner_.Initialize(&stream);
     return DoParseProgram(source, in_global_context, &zone_scope);
   }
 }
@@ -705,7 +711,7 @@
 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info,
                                    UC16CharacterStream* source,
                                    ZoneScope* zone_scope) {
-  scanner_.Initialize(source, JavaScriptScanner::kAllLiterals);
+  scanner_.Initialize(source);
   ASSERT(target_stack_ == NULL);
 
   Handle<String> name(String::cast(info->name()));
@@ -757,7 +763,7 @@
   if (pre_data() != NULL) {
     symbol_id = pre_data()->GetSymbolIdentifier();
   }
-  return LookupSymbol(symbol_id, scanner().literal());
+  return LookupSymbol(symbol_id);
 }
 
 
@@ -2715,8 +2721,9 @@
 
     case Token::NUMBER: {
       Consume(Token::NUMBER);
-      double value =
-        StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS);
+      ASSERT(scanner().is_literal_ascii());
+      double value = StringToDouble(scanner().literal_ascii_string(),
+                                    ALLOW_HEX | ALLOW_OCTALS);
       result = NewNumberLiteral(value);
       break;
     }
@@ -2988,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;
@@ -3066,8 +3081,9 @@
       }
       case Token::NUMBER: {
         Consume(Token::NUMBER);
-        double value =
-          StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS);
+        ASSERT(scanner().is_literal_ascii());
+        double value = StringToDouble(scanner().literal_ascii_string(),
+                                      ALLOW_HEX | ALLOW_OCTALS);
         key = NewNumberLiteral(value);
         break;
       }
@@ -3137,11 +3153,9 @@
 
   int literal_index = temp_scope_->NextMaterializedLiteralIndex();
 
-  Handle<String> js_pattern =
-      Factory::NewStringFromUtf8(scanner().next_literal(), TENURED);
+  Handle<String> js_pattern = NextLiteralString(TENURED);
   scanner().ScanRegExpFlags();
-  Handle<String> js_flags =
-      Factory::NewStringFromUtf8(scanner().next_literal(), TENURED);
+  Handle<String> js_flags = NextLiteralString(TENURED);
   Next();
 
   return new RegExpLiteral(js_pattern, js_flags, literal_index);
@@ -3423,10 +3437,10 @@
                                                  bool* ok) {
   Expect(Token::IDENTIFIER, ok);
   if (!*ok) return Handle<String>();
-  if (scanner().literal_length() == 3) {
-    const char* token = scanner().literal_string();
-    *is_get = strcmp(token, "get") == 0;
-    *is_set = !*is_get && strcmp(token, "set") == 0;
+  if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
+    const char* token = scanner().literal_ascii_string().start();
+    *is_get = strncmp(token, "get", 3) == 0;
+    *is_set = !*is_get && strncmp(token, "set", 3) == 0;
   }
   return GetSymbol(ok);
 }
@@ -3604,9 +3618,11 @@
   if (literal_length == 0) {
     return Factory::empty_string();
   }
-  const char* literal_string = scanner_.literal_string();
-  Vector<const char> literal(literal_string, literal_length);
-  return Factory::NewStringFromUtf8(literal);
+  if (scanner_.is_literal_ascii()) {
+    return Factory::NewStringFromAscii(scanner_.literal_ascii_string());
+  } else {
+    return Factory::NewStringFromTwoByte(scanner_.literal_uc16_string());
+  }
 }
 
 
@@ -3618,7 +3634,8 @@
       return GetString();
     }
     case Token::NUMBER: {
-      double value = StringToDouble(scanner_.literal(),
+      ASSERT(scanner_.is_literal_ascii());
+      double value = StringToDouble(scanner_.literal_ascii_string(),
                                     NO_FLAGS,  // Hex, octal or trailing junk.
                                     OS::nan_value());
       return Factory::NewNumber(value);
@@ -3663,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) {
@@ -4597,10 +4616,9 @@
 // Create a Scanner for the preparser to use as input, and preparse the source.
 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
                                   bool allow_lazy,
-                                  ParserRecorder* recorder,
-                                  int literal_flags) {
+                                  ParserRecorder* recorder) {
   V8JavaScriptScanner scanner;
-  scanner.Initialize(source, literal_flags);
+  scanner.Initialize(source);
   intptr_t stack_limit = StackGuard::real_climit();
   if (!preparser::PreParser::PreParseProgram(&scanner,
                                              recorder,
@@ -4628,8 +4646,7 @@
     return NULL;
   }
   PartialParserRecorder recorder;
-  return DoPreParse(source, allow_lazy, &recorder,
-                    JavaScriptScanner::kNoLiterals);
+  return DoPreParse(source, allow_lazy, &recorder);
 }
 
 
@@ -4638,9 +4655,7 @@
   Handle<Script> no_script;
   bool allow_lazy = FLAG_lazy && (extension == NULL);
   CompleteParserRecorder recorder;
-  int kPreParseLiteralsFlags =
-      JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier;
-  return DoPreParse(source, allow_lazy, &recorder, kPreParseLiteralsFlags);
+  return DoPreParse(source, allow_lazy, &recorder);
 }
 
 
diff --git a/src/parser.h b/src/parser.h
index 70d0e18..8623f38 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -578,6 +578,26 @@
   bool Check(Token::Value token);
   void ExpectSemicolon(bool* ok);
 
+  Handle<String> LiteralString(PretenureFlag tenured) {
+    if (scanner().is_literal_ascii()) {
+      return Factory::NewStringFromAscii(scanner().literal_ascii_string(),
+                                         tenured);
+    } else {
+      return Factory::NewStringFromTwoByte(scanner().literal_uc16_string(),
+                                           tenured);
+    }
+  }
+
+  Handle<String> NextLiteralString(PretenureFlag tenured) {
+    if (scanner().is_next_literal_ascii()) {
+      return Factory::NewStringFromAscii(scanner().next_literal_ascii_string(),
+                                         tenured);
+    } else {
+      return Factory::NewStringFromTwoByte(scanner().next_literal_uc16_string(),
+                                           tenured);
+    }
+  }
+
   Handle<String> GetSymbol(bool* ok);
 
   // Get odd-ball literals.
@@ -612,11 +632,9 @@
 
   Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
 
-  Handle<String> LookupSymbol(int symbol_id,
-                              Vector<const char> string);
+  Handle<String> LookupSymbol(int symbol_id);
 
-  Handle<String> LookupCachedSymbol(int symbol_id,
-                                    Vector<const char> string);
+  Handle<String> LookupCachedSymbol(int symbol_id);
 
   Expression* NewCall(Expression* expression,
                       ZoneList<Expression*>* arguments,
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..25a9ca0 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,9 @@
   // 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,
+        reinterpret_cast<unsigned long>(thread->name()),  // NOLINT
+        0, 0, 0);
   thread->thread_handle_data()->thread_ = pthread_self();
   ASSERT(thread->IsValid());
   thread->Run();
@@ -570,6 +580,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/preparse-data.cc b/src/preparse-data.cc
index 9a36771..7c9d8a6 100644
--- a/src/preparse-data.cc
+++ b/src/preparse-data.cc
@@ -110,26 +110,29 @@
 
 CompleteParserRecorder::CompleteParserRecorder()
     : FunctionLoggingParserRecorder(),
+      literal_chars_(0),
       symbol_store_(0),
-      symbol_entries_(0),
+      symbol_keys_(0),
       symbol_table_(vector_compare),
       symbol_id_(0) {
 }
 
 
-void CompleteParserRecorder::LogSymbol(
-    int start, const char* literal_chars, int length) {
-  if (!is_recording_) return;
-
-  Vector<const char> literal(literal_chars, length);
-  int hash = vector_hash(literal);
-  HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
+void CompleteParserRecorder::LogSymbol(int start,
+                                       int hash,
+                                       bool is_ascii,
+                                       Vector<const byte> literal_bytes) {
+  Key key = { is_ascii, literal_bytes };
+  HashMap::Entry* entry = symbol_table_.Lookup(&key, hash, true);
   int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
   if (id == 0) {
+    // Copy literal contents for later comparison.
+    key.literal_bytes =
+        Vector<const byte>::cast(literal_chars_.AddBlock(literal_bytes));
     // Put (symbol_id_ + 1) into entry and increment it.
     id = ++symbol_id_;
     entry->value = reinterpret_cast<void*>(id);
-    Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal);
+    Vector<Key> symbol = symbol_keys_.AddBlock(1, key);
     entry->key = &symbol[0];
   }
   WriteNumber(id - 1);
diff --git a/src/preparse-data.h b/src/preparse-data.h
index a96e50f..cc82bcc 100644
--- a/src/preparse-data.h
+++ b/src/preparse-data.h
@@ -75,7 +75,8 @@
                            int properties) = 0;
 
   // Logs a symbol creation of a literal or identifier.
-  virtual void LogSymbol(int start, const char* symbol, int length) = 0;
+  virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
+  virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
 
   // Logs an error message and marks the log as containing an error.
   // Further logging will be ignored, and ExtractData will return a vector
@@ -165,7 +166,8 @@
 class PartialParserRecorder : public FunctionLoggingParserRecorder {
  public:
   PartialParserRecorder() : FunctionLoggingParserRecorder() { }
-  virtual void LogSymbol(int start, const char* symbol, int length) { }
+  virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
+  virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { }
   virtual ~PartialParserRecorder() { }
   virtual Vector<unsigned> ExtractData();
   virtual int symbol_position() { return 0; }
@@ -181,7 +183,17 @@
   CompleteParserRecorder();
   virtual ~CompleteParserRecorder() { }
 
-  virtual void LogSymbol(int start, const char* symbol, int length);
+  virtual void LogAsciiSymbol(int start, Vector<const char> literal) {
+    if (!is_recording_) return;
+    int hash = vector_hash(literal);
+    LogSymbol(start, hash, true, Vector<const byte>::cast(literal));
+  }
+
+  virtual void LogUC16Symbol(int start, Vector<const uc16> literal) {
+    if (!is_recording_) return;
+    int hash = vector_hash(literal);
+    LogSymbol(start, hash, false, Vector<const byte>::cast(literal));
+  }
 
   virtual Vector<unsigned> ExtractData();
 
@@ -189,10 +201,21 @@
   virtual int symbol_ids() { return symbol_id_; }
 
  private:
-  static int vector_hash(Vector<const char> string) {
+  struct Key {
+    bool is_ascii;
+    Vector<const byte> literal_bytes;
+  };
+
+  virtual void LogSymbol(int start,
+                         int hash,
+                         bool is_ascii,
+                         Vector<const byte> literal);
+
+  template <typename Char>
+  static int vector_hash(Vector<const Char> string) {
     int hash = 0;
     for (int i = 0; i < string.length(); i++) {
-      int c = string[i];
+      int c = static_cast<int>(string[i]);
       hash += c;
       hash += (hash << 10);
       hash ^= (hash >> 6);
@@ -201,18 +224,21 @@
   }
 
   static bool vector_compare(void* a, void* b) {
-    Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a);
-    Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b);
-    int length = string1->length();
-    if (string2->length() != length) return false;
-    return memcmp(string1->start(), string2->start(), length) == 0;
+    Key* string1 = reinterpret_cast<Key*>(a);
+    Key* string2 = reinterpret_cast<Key*>(b);
+    if (string1->is_ascii != string2->is_ascii) return false;
+    int length = string1->literal_bytes.length();
+    if (string2->literal_bytes.length() != length) return false;
+    return memcmp(string1->literal_bytes.start(),
+                  string2->literal_bytes.start(), length) == 0;
   }
 
   // Write a non-negative number to the symbol store.
   void WriteNumber(int number);
 
+  Collector<byte> literal_chars_;
   Collector<byte> symbol_store_;
-  Collector<Vector<const char> > symbol_entries_;
+  Collector<Key> symbol_keys_;
   HashMap symbol_table_;
   int symbol_id_;
 };
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 7cce685..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() {
-  const char* literal_chars = scanner_->literal_string();
-  int literal_length = scanner_->literal_length();
+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());
+  }
+}
 
-  log_->LogSymbol(identifier_pos, literal_chars, literal_length);
 
-  return kUnknownExpression;
+PreParser::Identifier PreParser::GetIdentifierSymbol() {
+  LogSymbol();
+  return kUnknownIdentifier;
 }
 
 
 PreParser::Expression PreParser::GetStringSymbol() {
-  const char* literal_chars = scanner_->literal_string();
-  int literal_length = scanner_->literal_length();
-
-  int literal_position = scanner_->location().beg_pos;
-  log_->LogSymbol(literal_position, literal_chars, literal_length);
-
+  LogSymbol();
   return kUnknownExpression;
 }
 
@@ -1154,7 +1158,8 @@
   if (i::Token::IsKeyword(next)) {
     int pos = scanner_->location().beg_pos;
     const char* keyword = i::Token::String(next);
-    log_->LogSymbol(pos, keyword, i::StrLength(keyword));
+    log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
+                                                    i::StrLength(keyword)));
     return kUnknownExpression;
   }
   if (next == i::Token::IDENTIFIER) {
@@ -1173,8 +1178,8 @@
                                                            bool* is_set,
                                                            bool* ok) {
   Expect(i::Token::IDENTIFIER, CHECK_OK);
-  if (scanner_->literal_length() == 3) {
-    const char* token = scanner_->literal_string();
+  if (scanner_->is_literal_ascii() && scanner_->literal_length() == 3) {
+    const char* token = scanner_->literal_ascii_string().start();
     *is_get = strncmp(token, "get", 3) == 0;
     *is_set = !*is_get && strncmp(token, "set", 3) == 0;
   }
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.cc b/src/scanner-base.cc
index b26fee0..1babaeb 100644
--- a/src/scanner-base.cc
+++ b/src/scanner-base.cc
@@ -35,28 +35,6 @@
 namespace internal {
 
 // ----------------------------------------------------------------------------
-// LiteralCollector
-
-LiteralCollector::LiteralCollector()
-    : buffer_(kInitialCapacity), recording_(false) { }
-
-
-LiteralCollector::~LiteralCollector() {}
-
-
-void LiteralCollector::AddCharSlow(uc32 c) {
-  ASSERT(static_cast<unsigned>(c) > unibrow::Utf8::kMaxOneByteChar);
-  int length = unibrow::Utf8::Length(c);
-  Vector<char> block = buffer_.AddBlock(length, '\0');
-#ifdef DEBUG
-  int written_length = unibrow::Utf8::Encode(block.start(), c);
-  CHECK_EQ(length, written_length);
-#else
-  unibrow::Utf8::Encode(block.start(), c);
-#endif
-}
-
-// ----------------------------------------------------------------------------
 // Character predicates
 
 unibrow::Predicate<IdentifierStart, 128> ScannerConstants::kIsIdentifierStart;
@@ -256,7 +234,7 @@
 
 
 void JavaScriptScanner::Scan() {
-  next_.literal_chars = Vector<const char>();
+  next_.literal_chars = NULL;
   Token::Value token;
   do {
     // Remember the position of the next token
@@ -561,7 +539,7 @@
   uc32 quote = c0_;
   Advance();  // consume quote
 
-  LiteralScope literal(this, kLiteralString);
+  LiteralScope literal(this);
   while (c0_ != quote && c0_ >= 0
          && !ScannerConstants::kIsLineTerminator.get(c0_)) {
     uc32 c = c0_;
@@ -592,7 +570,7 @@
 
   enum { DECIMAL, HEX, OCTAL } kind = DECIMAL;
 
-  LiteralScope literal(this, kLiteralNumber);
+  LiteralScope literal(this);
   if (seen_period) {
     // we have already seen a decimal point of the float
     AddLiteralChar('.');
@@ -681,7 +659,7 @@
 
 Token::Value JavaScriptScanner::ScanIdentifierOrKeyword() {
   ASSERT(ScannerConstants::kIsIdentifierStart.get(c0_));
-  LiteralScope literal(this, kLiteralIdentifier);
+  LiteralScope literal(this);
   KeywordMatcher keyword_match;
   // Scan identifier start character.
   if (c0_ == '\\') {
@@ -747,7 +725,7 @@
   // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
   // the scanner should pass uninterpreted bodies to the RegExp
   // constructor.
-  LiteralScope literal(this, kLiteralRegExp);
+  LiteralScope literal(this);
   if (seen_equal)
     AddLiteralChar('=');
 
@@ -773,7 +751,7 @@
 
 bool JavaScriptScanner::ScanRegExpFlags() {
   // Scan regular expression flags.
-  LiteralScope literal(this, kLiteralRegExpFlags);
+  LiteralScope literal(this);
   while (ScannerConstants::kIsIdentifierPart.get(c0_)) {
     if (c0_ == '\\') {
       uc32 c = ScanIdentifierUnicodeEscape();
diff --git a/src/scanner-base.h b/src/scanner-base.h
index c50b8f3..b668df5 100644
--- a/src/scanner-base.h
+++ b/src/scanner-base.h
@@ -141,61 +141,105 @@
 };
 
 // ----------------------------------------------------------------------------
-// LiteralCollector -  Collector of chars of literals.
+// LiteralBuffer -  Collector of chars of literals.
 
-class LiteralCollector {
+class LiteralBuffer {
  public:
-  LiteralCollector();
-  ~LiteralCollector();
+  LiteralBuffer() : is_ascii_(true), position_(0), backing_store_() { }
 
-  inline void AddChar(uc32 c) {
-    if (recording_) {
-      if (static_cast<unsigned>(c) <= unibrow::Utf8::kMaxOneByteChar) {
-        buffer_.Add(static_cast<char>(c));
-      } else {
-        AddCharSlow(c);
+  ~LiteralBuffer() {
+    if (backing_store_.length() > 0) {
+      backing_store_.Dispose();
+    }
+  }
+
+  inline void AddChar(uc16 character) {
+    if (position_ >= backing_store_.length()) ExpandBuffer();
+    if (is_ascii_) {
+      if (character < kMaxAsciiCharCodeU) {
+        backing_store_[position_] = static_cast<byte>(character);
+        position_ += kASCIISize;
+        return;
       }
+      ConvertToUC16();
     }
+    *reinterpret_cast<uc16*>(&backing_store_[position_]) = character;
+    position_ += kUC16Size;
   }
 
-  void StartLiteral() {
-    buffer_.StartSequence();
-    recording_ = true;
+  bool is_ascii() { return is_ascii_; }
+
+  Vector<const uc16> uc16_literal() {
+    ASSERT(!is_ascii_);
+    ASSERT((position_ & 0x1) == 0);
+    return Vector<const uc16>(
+        reinterpret_cast<const uc16*>(backing_store_.start()),
+        position_ >> 1);
   }
 
-  Vector<const char> EndLiteral() {
-    if (recording_) {
-      recording_ = false;
-      buffer_.Add(kEndMarker);
-      Vector<char> sequence = buffer_.EndSequence();
-      return Vector<const char>(sequence.start(), sequence.length());
-    }
-    return Vector<const char>();
+  Vector<const char> ascii_literal() {
+    ASSERT(is_ascii_);
+    return Vector<const char>(
+        reinterpret_cast<const char*>(backing_store_.start()),
+        position_);
   }
 
-  void DropLiteral() {
-    if (recording_) {
-      recording_ = false;
-      buffer_.DropSequence();
-    }
+  int length() {
+    return is_ascii_ ? position_ : (position_ >> 1);
   }
 
   void Reset() {
-    buffer_.Reset();
+    position_ = 0;
+    is_ascii_ = true;
+  }
+ private:
+  static const int kInitialCapacity = 16;
+  static const int kGrowthFactory = 4;
+  static const int kMinConversionSlack = 256;
+  static const int kMaxGrowth = 1 * MB;
+  inline int NewCapacity(int min_capacity) {
+    int capacity = Max(min_capacity, backing_store_.length());
+    int new_capacity = Min(capacity * kGrowthFactory, capacity + kMaxGrowth);
+    return new_capacity;
   }
 
-  // The end marker added after a parsed literal.
-  // Using zero allows the usage of strlen and similar functions on
-  // identifiers and numbers (but not strings, since they may contain zero
-  // bytes).
-  static const char kEndMarker = '\x00';
- private:
-  static const int kInitialCapacity = 256;
-  SequenceCollector<char, 4> buffer_;
-  bool recording_;
-  void AddCharSlow(uc32 c);
+  void ExpandBuffer() {
+    Vector<byte> new_store = Vector<byte>::New(NewCapacity(kInitialCapacity));
+    memcpy(new_store.start(), backing_store_.start(), position_);
+    backing_store_.Dispose();
+    backing_store_ = new_store;
+  }
+
+  void ConvertToUC16() {
+    ASSERT(is_ascii_);
+    Vector<byte> new_store;
+    int new_content_size = position_ * kUC16Size;
+    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_;
+    }
+    char* src = reinterpret_cast<char*>(backing_store_.start());
+    uc16* dst = reinterpret_cast<uc16*>(new_store.start());
+    for (int i = position_ - 1; i >= 0; i--) {
+      dst[i] = src[i];
+    }
+    if (new_store.start() != backing_store_.start()) {
+      backing_store_.Dispose();
+      backing_store_ = new_store;
+    }
+    position_ = new_content_size;
+    is_ascii_ = false;
+  }
+
+  bool is_ascii_;
+  int position_;
+  Vector<byte> backing_store_;
 };
 
+
 // ----------------------------------------------------------------------------
 // Scanner base-class.
 
@@ -241,35 +285,40 @@
   // collected for identifiers, strings, and numbers.
   // These functions only give the correct result if the literal
   // was scanned between calls to StartLiteral() and TerminateLiteral().
-  const char* literal_string() const {
-    return current_.literal_chars.start();
+  bool is_literal_ascii() {
+    ASSERT_NOT_NULL(current_.literal_chars);
+    return current_.literal_chars->is_ascii();
   }
-
+  Vector<const char> literal_ascii_string() {
+    ASSERT_NOT_NULL(current_.literal_chars);
+    return current_.literal_chars->ascii_literal();
+  }
+  Vector<const uc16> literal_uc16_string() {
+    ASSERT_NOT_NULL(current_.literal_chars);
+    return current_.literal_chars->uc16_literal();
+  }
   int literal_length() const {
-    // Excluding terminal '\x00' added by TerminateLiteral().
-    return current_.literal_chars.length() - 1;
-  }
-
-  Vector<const char> literal() const {
-    return Vector<const char>(literal_string(), literal_length());
+    ASSERT_NOT_NULL(current_.literal_chars);
+    return current_.literal_chars->length();
   }
 
   // Returns the literal string for the next token (the token that
   // would be returned if Next() were called).
-  const char* next_literal_string() const {
-    return next_.literal_chars.start();
+  bool is_next_literal_ascii() {
+    ASSERT_NOT_NULL(next_.literal_chars);
+    return next_.literal_chars->is_ascii();
   }
-
-
-  // Returns the length of the next token (that would be returned if
-  // Next() were called).
+  Vector<const char> next_literal_ascii_string() {
+    ASSERT_NOT_NULL(next_.literal_chars);
+    return next_.literal_chars->ascii_literal();
+  }
+  Vector<const uc16> next_literal_uc16_string() {
+    ASSERT_NOT_NULL(next_.literal_chars);
+    return next_.literal_chars->uc16_literal();
+  }
   int next_literal_length() const {
-    // Excluding terminal '\x00' added by TerminateLiteral().
-    return next_.literal_chars.length() - 1;
-  }
-
-  Vector<const char> next_literal() const {
-    return Vector<const char>(next_literal_string(), next_literal_length());
+    ASSERT_NOT_NULL(next_.literal_chars);
+    return next_.literal_chars->length();
   }
 
   static const int kCharacterLookaheadBufferSize = 1;
@@ -279,7 +328,7 @@
   struct TokenDesc {
     Token::Value token;
     Location location;
-    Vector<const char> literal_chars;
+    LiteralBuffer* literal_chars;
   };
 
   // Call this after setting source_ to the input.
@@ -288,29 +337,31 @@
     ASSERT(kCharacterLookaheadBufferSize == 1);
     Advance();
     // Initialize current_ to not refer to a literal.
-    current_.literal_chars = Vector<const char>();
-    // Reset literal buffer.
-    literal_buffer_.Reset();
+    current_.literal_chars = NULL;
   }
 
   // Literal buffer support
   inline void StartLiteral() {
-    literal_buffer_.StartLiteral();
+    LiteralBuffer* free_buffer = (current_.literal_chars == &literal_buffer1_) ?
+            &literal_buffer2_ : &literal_buffer1_;
+    free_buffer->Reset();
+    next_.literal_chars = free_buffer;
   }
 
   inline void AddLiteralChar(uc32 c) {
-    literal_buffer_.AddChar(c);
+    ASSERT_NOT_NULL(next_.literal_chars);
+    next_.literal_chars->AddChar(c);
   }
 
   // Complete scanning of a literal.
   inline void TerminateLiteral() {
-    next_.literal_chars = literal_buffer_.EndLiteral();
+    // Does nothing in the current implementation.
   }
 
   // Stops scanning of a literal and drop the collected characters,
   // e.g., due to an encountered error.
   inline void DropLiteral() {
-    literal_buffer_.DropLiteral();
+    next_.literal_chars = NULL;
   }
 
   inline void AddLiteralCharAdvance() {
@@ -348,15 +399,16 @@
     return source_->pos() - kCharacterLookaheadBufferSize;
   }
 
+  // Buffers collecting literal strings, numbers, etc.
+  LiteralBuffer literal_buffer1_;
+  LiteralBuffer literal_buffer2_;
+
   TokenDesc current_;  // desc for current token (as returned by Next())
   TokenDesc next_;     // desc for next token (one token look-ahead)
 
   // Input stream. Must be initialized to an UC16CharacterStream.
   UC16CharacterStream* source_;
 
-  // Buffer to hold literal values (identifiers, strings, numbers)
-  // using '\x00'-terminated UTF-8 encoding. Handles allocation internally.
-  LiteralCollector literal_buffer_;
 
   // One Unicode character look-ahead; c0_ < 0 at the end of the input.
   uc32 c0_;
@@ -367,28 +419,14 @@
 
 class JavaScriptScanner : public Scanner {
  public:
-
-  // Bit vector representing set of types of literals.
-  enum LiteralType {
-    kNoLiterals = 0,
-    kLiteralNumber = 1,
-    kLiteralIdentifier = 2,
-    kLiteralString = 4,
-    kLiteralRegExp = 8,
-    kLiteralRegExpFlags = 16,
-    kAllLiterals = 31
-  };
-
   // A LiteralScope that disables recording of some types of JavaScript
   // literals. If the scanner is configured to not record the specific
   // type of literal, the scope will not call StartLiteral.
   class LiteralScope {
    public:
-    LiteralScope(JavaScriptScanner* self, LiteralType type)
+    explicit LiteralScope(JavaScriptScanner* self)
         : scanner_(self), complete_(false) {
-      if (scanner_->RecordsLiteral(type)) {
-        scanner_->StartLiteral();
-      }
+      scanner_->StartLiteral();
     }
      ~LiteralScope() {
        if (!complete_) scanner_->DropLiteral();
@@ -430,11 +468,6 @@
   // tokens, which is what it is used for.
   void SeekForward(int pos);
 
-  // Whether this scanner records the given literal type or not.
-  bool RecordsLiteral(LiteralType type) {
-    return (literal_flags_ & type) != 0;
-  }
-
  protected:
   bool SkipWhiteSpace();
   Token::Value SkipSingleLineComment();
@@ -458,7 +491,6 @@
   // If the escape sequence cannot be decoded the result is kBadChar.
   uc32 ScanIdentifierUnicodeEscape();
 
-  int literal_flags_;
   bool has_line_terminator_before_next_;
 };
 
diff --git a/src/scanner.cc b/src/scanner.cc
index 47e9895..7fd6ef2 100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -324,10 +324,8 @@
 V8JavaScriptScanner::V8JavaScriptScanner() : JavaScriptScanner() { }
 
 
-void V8JavaScriptScanner::Initialize(UC16CharacterStream* source,
-                                     int literal_flags) {
+void V8JavaScriptScanner::Initialize(UC16CharacterStream* source) {
   source_ = source;
-  literal_flags_ = literal_flags | kLiteralIdentifier;
   // Need to capture identifiers in order to recognize "get" and "set"
   // in object literals.
   Init();
@@ -377,7 +375,7 @@
 
 
 void JsonScanner::ScanJson() {
-  next_.literal_chars = Vector<const char>();
+  next_.literal_chars = NULL;
   Token::Value token;
   do {
     // Remember the position of the next token
@@ -459,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_ != '\\') {
@@ -506,9 +504,6 @@
       Advance();
     }
   }
-  if (c0_ != '"') {
-    return Token::ILLEGAL;
-  }
   literal.Complete();
   Advance();
   return Token::STRING;
diff --git a/src/scanner.h b/src/scanner.h
index 572778f..bdf899b 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -134,8 +134,7 @@
 class V8JavaScriptScanner : public JavaScriptScanner {
  public:
   V8JavaScriptScanner();
-  void Initialize(UC16CharacterStream* source,
-                  int literal_flags = kAllLiterals);
+  void Initialize(UC16CharacterStream* source);
 };
 
 
diff --git a/src/string-search.h b/src/string-search.h
index eac8475..5de3c09 100644
--- a/src/string-search.h
+++ b/src/string-search.h
@@ -66,12 +66,7 @@
   }
 
   static inline bool IsAsciiString(Vector<const uc16> string) {
-    for (int i = 0, n = string.length(); i < n; i++) {
-      if (static_cast<unsigned>(string[i]) > String::kMaxAsciiCharCodeU) {
-        return false;
-      }
-    }
-    return true;
+    return String::IsAscii(string.start(), string.length());
   }
 
   // The following tables are shared by all searches.
diff --git a/src/string.js b/src/string.js
index 9527599..ab0ab54 100644
--- a/src/string.js
+++ b/src/string.js
@@ -127,7 +127,7 @@
   var index = subLength - patLength;
   if (%_ArgumentsLength() > 1) {
     var position = ToNumber(%_Arguments(1));
-    if (!$isNaN(position)) {
+    if (!NUMBER_IS_NAN(position)) {
       position = TO_INTEGER(position);
       if (position < 0) {
         position = 0;
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/utils.h b/src/utils.h
index 62b8726..21e70d7 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -530,6 +530,24 @@
   }
 
 
+  // Add a contiguous block of elements and return a vector backed
+  // by the added block.
+  // A basic Collector will keep this vector valid as long as the Collector
+  // is alive.
+  inline Vector<T> AddBlock(Vector<const T> source) {
+    if (source.length() > current_chunk_.length() - index_) {
+      Grow(source.length());
+    }
+    T* position = current_chunk_.start() + index_;
+    index_ += source.length();
+    size_ += source.length();
+    for (int i = 0; i < source.length(); i++) {
+      position[i] = source[i];
+    }
+    return Vector<T>(position, source.length());
+  }
+
+
   // Write the contents of the collector into the provided vector.
   void WriteTo(Vector<T> destination) {
     ASSERT(size_ <= destination.length());
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/v8utils.h b/src/v8utils.h
index 87efbcf..e9623be 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -29,10 +29,7 @@
 #define V8_V8UTILS_H_
 
 #include "utils.h"
-#ifdef ANDROID
-// Cherry pick from r6346 to build on Android.
-#include "platform.h"
-#endif
+#include "platform.h"  // For va_list on Solaris.
 
 namespace v8 {
 namespace internal {
diff --git a/src/version.cc b/src/version.cc
index d2c0960..008f779 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     0
-#define BUILD_NUMBER      4
+#define BUILD_NUMBER      6
 #define PATCH_LEVEL       1
 #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 2cf85f1..27f3482 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -223,9 +223,7 @@
   // If input is ASCII, don't even bother calling here if the string to
   // match contains a non-ascii character.
   if (mode_ == ASCII) {
-    for (int i = 0; i < str.length(); i++) {
-      ASSERT(str[i] <= String::kMaxAsciiCharCodeU);
-    }
+    ASSERT(String::IsAscii(str.start(), str.length()));
   }
 #endif
   int byte_length = str.length() * char_size();
@@ -690,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);
 }
 
 
diff --git a/test/cctest/test-assembler-ia32.cc b/test/cctest/test-assembler-ia32.cc
index 40232ef..14692ff 100644
--- a/test/cctest/test-assembler-ia32.cc
+++ b/test/cctest/test-assembler-ia32.cc
@@ -74,7 +74,7 @@
                                   Handle<Object>(Heap::undefined_value()))->
       ToObjectChecked();
   CHECK(code->IsCode());
-#ifdef DEBUG
+#ifdef OBJECT_PRINT
   Code::cast(code)->Print();
 #endif
   F2 f = FUNCTION_CAST<F2>(Code::cast(code)->entry());
@@ -112,7 +112,7 @@
                                   Handle<Object>(Heap::undefined_value()))->
       ToObjectChecked();
   CHECK(code->IsCode());
-#ifdef DEBUG
+#ifdef OBJECT_PRINT
   Code::cast(code)->Print();
 #endif
   F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
@@ -155,7 +155,7 @@
       Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
 
   CHECK(code->IsCode());
-#ifdef DEBUG
+#ifdef OBJECT_PRINT
   Code::cast(code)->Print();
 #endif
   F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry());
@@ -329,7 +329,7 @@
       Code::ComputeFlags(Code::STUB),
       Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
   CHECK(code->IsCode());
-#ifdef DEBUG
+#ifdef OBJECT_PRINT
   Code::cast(code)->Print();
 #endif
   F6 f = FUNCTION_CAST<F6>(Code::cast(code)->entry());
@@ -384,7 +384,7 @@
       Code::ComputeFlags(Code::STUB),
       Handle<Object>(Heap::undefined_value()))->ToObjectChecked());
   CHECK(code->IsCode());
-#ifdef DEBUG
+#ifdef OBJECT_PRINT
   Code::cast(code)->Print();
 #endif
 
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index 5cd56ac..b563f8f 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -443,7 +443,7 @@
       Code::ComputeFlags(Code::STUB),
       Handle<Object>(Heap::undefined_value()))->ToObjectChecked();
   CHECK(code->IsCode());
-#ifdef DEBUG
+#ifdef OBJECT_PRINT
   Code::cast(code)->Print();
   byte* begin = Code::cast(code)->instruction_start();
   byte* end = begin + Code::cast(code)->instruction_size();
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index e642d1b..da5d771 100755
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -573,7 +573,7 @@
                        int skip_pos = 0,  // Zero means not skipping.
                        int skip_to = 0) {
   i::V8JavaScriptScanner scanner;
-  scanner.Initialize(stream, i::JavaScriptScanner::kAllLiterals);
+  scanner.Initialize(stream);
 
   int i = 0;
   do {
diff --git a/test/mjsunit/bugs/bug-1015.js b/test/mjsunit/bugs/bug-1015.js
new file mode 100644
index 0000000..9e4406a
--- /dev/null
+++ b/test/mjsunit/bugs/bug-1015.js
@@ -0,0 +1,66 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1015
+
+// Object and array literals should be created using DefineOwnProperty, and
+// therefore not hit setters in the prototype.
+
+function mkFail(message) {
+  return function () { assertUnreachable(message); }
+}
+
+Object.defineProperty(Object.prototype, "foo",
+                      {get: mkFail("oget"), set: mkFail("oset")});
+Object.defineProperty(Array.prototype, "2",
+                      {get: mkFail("aget"), set: mkFail("aset")});
+
+function inFunction() {
+  for (var i = 0; i < 10; i++) {
+    // in loop.
+    var ja = JSON.parse('[1,2,3,4]');
+    var jo = JSON.parse('{"bar": 10, "foo": 20}')
+    var jop = JSON.parse('{"bar": 10, "__proto__": { }, "foo": 20}')
+    var a = [1,2,3,4];
+    var o = { bar: 10, foo: 20 };
+    var op = { __proto__: { set bar(v) { assertUnreachable("bset"); } },
+               bar: 10 };
+  }
+}
+
+for (var i = 0; i < 10; i++) {
+  // In global scope.
+  var ja = JSON.parse('[1,2,3,4]');
+  var jo = JSON.parse('{"bar": 10, "foo": 20}')
+  var jop = JSON.parse('{"bar": 10, "__proto__": { }, "foo": 20}')
+  var a = [1,2,3,4];
+  var o = { bar: 10, foo: 20 };
+  var op = { __proto__: { set bar(v) { assertUnreachable("bset"); } },
+             bar: 10 };
+  // In function scope.
+  inFunction();
+}
diff --git a/test/mjsunit/indexed-accessors.js b/test/mjsunit/indexed-accessors.js
index 395f2ab..1634857 100644
--- a/test/mjsunit/indexed-accessors.js
+++ b/test/mjsunit/indexed-accessors.js
@@ -81,19 +81,6 @@
 expected[0] = 111;
 testArray();
 
-// The functionality is not implemented for arrays due to performance issues.
-var a = [ 1 ];
-a.__defineGetter__('2', function() { return 7; });
-assertEquals(undefined, a[2]);
-assertEquals(1, a.length);
-var b = 0;
-a.__defineSetter__('5', function(y) { b = y; });
-assertEquals(1, a.length);
-a[5] = 42;
-assertEquals(0, b);
-assertEquals(42, a[5]);
-assertEquals(6, a.length);
-
 // Using a setter where only a getter is defined throws an exception.
 var q = {};
 q.__defineGetter__('0', function() { return 42; });
diff --git a/test/mjsunit/regress/regress-1017.js b/test/mjsunit/regress/regress-1017.js
new file mode 100644
index 0000000..3daf542
--- /dev/null
+++ b/test/mjsunit/regress/regress-1017.js
@@ -0,0 +1,36 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1017
+
+// 32 ASCII-characters followed by a non-ASCII character.
+// This causes an internal buffer to first expand to 64 bytes, then expand the
+// 32 ASCII characters to 64 bytes of UC16 characters, leaving no room
+// to store the 33rd character. This fails an ASSERT in debug mode.
+
+assertEquals(33, "12345678901234567890123456789012\u2028".length);
+
diff --git a/test/mjsunit/regress/regress-900.js b/test/mjsunit/regress/regress-900.js
new file mode 100644
index 0000000..9f94348
--- /dev/null
+++ b/test/mjsunit/regress/regress-900.js
@@ -0,0 +1,46 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that we allow accessors on JSArray elements.
+
+var a = [];
+var b = {}
+Object.defineProperty(a, "1", {get: function() {return "foo";}});
+Object.defineProperty(
+    b, "1", {get: function() {return "bar";}, set: function() {this.x = 42;}});
+assertEquals(a[1], 'foo');
+assertEquals(b[1], 'bar');
+// Make sure we can't overwrite an accessor, but that the setter is
+// instead called.
+b[1] = 'foobar';
+assertEquals(b[1], 'bar');
+assertEquals(b.x, 42);
+
+var desc = Object.getOwnPropertyDescriptor(b, "1");
+assertEquals(desc['writable'], undefined);
+assertFalse(desc['enumerable']);
+assertFalse(desc['configurable']);
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index 1f9e6eb..5688cf8 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -653,8 +653,6 @@
 js1_5/extensions/regress-336409-2: FAIL_OK
 js1_5/extensions/regress-336410-2: FAIL_OK
 js1_5/extensions/regress-341956-01: FAIL_OK
-js1_5/extensions/regress-341956-02: FAIL_OK
-js1_5/extensions/regress-341956-03: FAIL_OK
 js1_5/extensions/regress-345967: FAIL_OK
 js1_5/extensions/regress-346494-01: FAIL_OK
 js1_5/extensions/regress-346494: FAIL_OK
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 6af6611..365e650 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -27,792 +27,819 @@
 
 {
   'variables': {
+    'use_system_v8%': 0,
     'msvs_use_common_release': 0,
     'gcc_version%': 'unknown',
     'v8_target_arch%': '<(target_arch)',
     'v8_use_snapshot%': 'true',
   },
-  'target_defaults': {
-    'defines': [
-      'ENABLE_LOGGING_AND_PROFILING',
-      'ENABLE_DEBUGGER_SUPPORT',
-      'ENABLE_VMSTATE_TRACKING',
-    ],
-    'conditions': [
-      ['OS!="mac"', {
-        # TODO(mark): The OS!="mac" conditional is temporary. It can be
-        # removed once the Mac Chromium build stops setting target_arch to
-        # ia32 and instead sets it to mac. Other checks in this file for
-        # OS=="mac" can be removed at that time as well. This can be cleaned
-        # up once http://crbug.com/44205 is fixed.
-        'conditions': [
-          ['v8_target_arch=="arm"', {
-            'defines': [
-              'V8_TARGET_ARCH_ARM',
-            ],
-          }],
-          ['v8_target_arch=="ia32"', {
-            'defines': [
-              'V8_TARGET_ARCH_IA32',
-            ],
-          }],
-          ['v8_target_arch=="x64"', {
-            'defines': [
-              'V8_TARGET_ARCH_X64',
-            ],
-          }],
-        ],
-      }],
-    ],
-    'configurations': {
-      'Debug': {
+  'conditions': [
+    ['use_system_v8==0', {
+      'target_defaults': {
         'defines': [
-          'DEBUG',
-          '_DEBUG',
-          'ENABLE_DISASSEMBLER',
-          'V8_ENABLE_CHECKS',
-          'OBJECT_PRINT',
+          'ENABLE_LOGGING_AND_PROFILING',
+          'ENABLE_DEBUGGER_SUPPORT',
+          'ENABLE_VMSTATE_TRACKING',
         ],
-        'msvs_settings': {
-          'VCCLCompilerTool': {
-            'Optimization': '0',
-            
+        'conditions': [
+          ['OS!="mac"', {
+            # TODO(mark): The OS!="mac" conditional is temporary. It can be
+            # removed once the Mac Chromium build stops setting target_arch to
+            # ia32 and instead sets it to mac. Other checks in this file for
+            # OS=="mac" can be removed at that time as well. This can be cleaned
+            # up once http://crbug.com/44205 is fixed.
             'conditions': [
-              ['OS=="win" and component=="shared_library"', {
-                'RuntimeLibrary': '3',  # /MDd
-              }, {
-                'RuntimeLibrary': '1',  # /MTd
+              ['v8_target_arch=="arm"', {
+                'defines': [
+                  'V8_TARGET_ARCH_ARM',
+                ],
               }],
-            ],
-          },
-          'VCLinkerTool': {
-            'LinkIncremental': '2',
-          },
-        },
-        'conditions': [
-         ['OS=="freebsd" or OS=="openbsd"', {
-           'cflags': [ '-I/usr/local/include' ],
-         }],
-       ],
-      },
-      'Release': {
-        'conditions': [
-          ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
-            'cflags!': [
-              '-O2',
-              '-Os',
-            ],
-            'cflags': [
-              '-fomit-frame-pointer',
-              '-O3',
-            ],
-            'conditions': [
-              [ 'gcc_version==44', {
-                'cflags': [
-                  # Avoid crashes with gcc 4.4 in the v8 test suite.
-                  '-fno-tree-vrp',
+              ['v8_target_arch=="ia32"', {
+                'defines': [
+                  'V8_TARGET_ARCH_IA32',
+                ],
+              }],
+              ['v8_target_arch=="x64"', {
+                'defines': [
+                  'V8_TARGET_ARCH_X64',
                 ],
               }],
             ],
           }],
-         ['OS=="freebsd" or OS=="openbsd"', {
-           'cflags': [ '-I/usr/local/include' ],
-         }],
-          ['OS=="mac"', {
-            'xcode_settings': {
-              'GCC_OPTIMIZATION_LEVEL': '3',  # -O3
-              'GCC_STRICT_ALIASING': 'YES',   # -fstrict-aliasing.  Mainline gcc
-                                              # enables this at -O2 and above,
-                                              # but Apple gcc does not unless it
-                                              # is specified explicitly.
-            },
-          }],
-          ['OS=="win"', {
-            'msvs_configuration_attributes': {
-              'OutputDirectory': '$(SolutionDir)$(ConfigurationName)',
-              'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)',
-              'CharacterSet': '1',
-            },
+        ],
+        'configurations': {
+          'Debug': {
+            'defines': [
+              'DEBUG',
+              '_DEBUG',
+              'ENABLE_DISASSEMBLER',
+              'V8_ENABLE_CHECKS',
+              'OBJECT_PRINT',
+            ],
             'msvs_settings': {
               'VCCLCompilerTool': {
-                'Optimization': '2',
-                'InlineFunctionExpansion': '2',
-                'EnableIntrinsicFunctions': 'true',
-                'FavorSizeOrSpeed': '0',
-                'OmitFramePointers': 'true',
-                'StringPooling': 'true',
-                
+                'Optimization': '0',
+
                 'conditions': [
                   ['OS=="win" and component=="shared_library"', {
-                    'RuntimeLibrary': '2',  #/MD
+                    'RuntimeLibrary': '3',  # /MDd
                   }, {
-                    'RuntimeLibrary': '0',  #/MT
+                    'RuntimeLibrary': '1',  # /MTd
                   }],
                 ],
               },
               'VCLinkerTool': {
-                'LinkIncremental': '1',
-                'OptimizeReferences': '2',
-                'OptimizeForWindows98': '1',
-                'EnableCOMDATFolding': '2',
+                'LinkIncremental': '2',
               },
             },
-          }],
-        ],
-      },
-    },
-  },
-  'targets': [
-    {
-      'target_name': 'v8',
-      'conditions': [
-        ['v8_use_snapshot=="true"', {
-          'dependencies': ['v8_snapshot'],
+            'conditions': [
+             ['OS=="freebsd" or OS=="openbsd"', {
+               'cflags': [ '-I/usr/local/include' ],
+             }],
+           ],
+          },
+          'Release': {
+            'conditions': [
+              ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
+                'cflags!': [
+                  '-O2',
+                  '-Os',
+                ],
+                'cflags': [
+                  '-fomit-frame-pointer',
+                  '-O3',
+                ],
+                'conditions': [
+                  [ 'gcc_version==44', {
+                    'cflags': [
+                      # Avoid crashes with gcc 4.4 in the v8 test suite.
+                      '-fno-tree-vrp',
+                    ],
+                  }],
+                ],
+              }],
+             ['OS=="freebsd" or OS=="openbsd"', {
+               'cflags': [ '-I/usr/local/include' ],
+             }],
+              ['OS=="mac"', {
+                'xcode_settings': {
+                  'GCC_OPTIMIZATION_LEVEL': '3',  # -O3
+
+                  # -fstrict-aliasing.  Mainline gcc
+                  # enables this at -O2 and above,
+                  # but Apple gcc does not unless it
+                  # is specified explicitly.
+                  'GCC_STRICT_ALIASING': 'YES',
+                },
+              }],
+              ['OS=="win"', {
+                'msvs_configuration_attributes': {
+                  'OutputDirectory': '$(SolutionDir)$(ConfigurationName)',
+                  'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)',
+                  'CharacterSet': '1',
+                },
+                'msvs_settings': {
+                  'VCCLCompilerTool': {
+                    'Optimization': '2',
+                    'InlineFunctionExpansion': '2',
+                    'EnableIntrinsicFunctions': 'true',
+                    'FavorSizeOrSpeed': '0',
+                    'OmitFramePointers': 'true',
+                    'StringPooling': 'true',
+
+                    'conditions': [
+                      ['OS=="win" and component=="shared_library"', {
+                        'RuntimeLibrary': '2',  #/MD
+                      }, {
+                        'RuntimeLibrary': '0',  #/MT
+                      }],
+                    ],
+                  },
+                  'VCLinkerTool': {
+                    'LinkIncremental': '1',
+                    'OptimizeReferences': '2',
+                    'OptimizeForWindows98': '1',
+                    'EnableCOMDATFolding': '2',
+                  },
+                },
+              }],
+            ],
+          },
         },
+      },
+      'targets': [
         {
-          'dependencies': ['v8_nosnapshot'],
-        }],
-        ['OS=="win" and component=="shared_library"', {
-          'type': '<(component)',
-          'sources': [
-            '../../src/v8dll-main.cc',
-          ],
-          'defines': [
-            'BUILDING_V8_SHARED'
+          'target_name': 'v8',
+          'conditions': [
+            ['v8_use_snapshot=="true"', {
+              'dependencies': ['v8_snapshot'],
+            },
+            {
+              'dependencies': ['v8_nosnapshot'],
+            }],
+            ['OS=="win" and component=="shared_library"', {
+              'type': '<(component)',
+              'sources': [
+                '../../src/v8dll-main.cc',
+              ],
+              'defines': [
+                'BUILDING_V8_SHARED'
+              ],
+              'direct_dependent_settings': {
+                'defines': [
+                  'USING_V8_SHARED',
+                ],
+              },
+            },
+            {
+              'type': 'none',
+            }],
           ],
           'direct_dependent_settings': {
-            'defines': [
-              'USING_V8_SHARED',
+            'include_dirs': [
+               '../../include',
             ],
           },
         },
         {
-          'type': 'none',
-        }],
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-           '../../include',
-        ],
-      },
-    },
-    {
-      'target_name': 'v8_preparser',
-      'include_dirs': [
-        '../../include',
-        '../../src',
-      ],
-      'sources': [
-        '../../src/allocation.cc',
-        '../../src/hashmap.cc',
-        '../../src/preparse-data.cc',
-        '../../src/preparser.cc',
-        '../../src/preparser-api.cc',
-        '../../src/scanner-base.cc',
-        '../../src/token.cc',
-        '../../src/unicode.cc',
-      ],
-      'conditions': [
-        ['OS=="win" and component=="shared_library"', {
-          'sources': [ '../../src/v8preparserdll-main.cc' ],
-          'defines': [ 'BUILDING_V8_SHARED' ],
-          'direct_dependent_settings': {
-            'defines': [ 'USING_V8_SHARED' ]
-          },
-          'type': '<(component)',
-        } , {
-          'type': 'none'
-        }],
-        ['OS!="win"', {
-          'type': '<(library)'
-        }],
-      ]
-    },
-    {
-      'target_name': 'v8_snapshot',
-      'type': '<(library)',
-      'conditions': [
-        ['OS=="win" and component=="shared_library"', {
-          'defines': [
-            'BUILDING_V8_SHARED',
-          ],
-        }],
-      ],
-      'dependencies': [
-        'mksnapshot#host',
-        'js2c#host',
-        'v8_base',
-      ],
-      'include_dirs+': [
-        '../../src',
-      ],
-      'sources': [
-        '<(SHARED_INTERMEDIATE_DIR)/libraries-empty.cc',
-        '<(INTERMEDIATE_DIR)/snapshot.cc',
-      ],
-      'actions': [
-        {
-          'action_name': 'run_mksnapshot',
-          'inputs': [
-            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
-          ],
-          'outputs': [
-            '<(INTERMEDIATE_DIR)/snapshot.cc',
-          ],
-          'action': ['<@(_inputs)', '<@(_outputs)'],
-        },
-      ],
-    },
-    {
-      'target_name': 'v8_nosnapshot',
-      'type': '<(library)',
-      'toolsets': ['host', 'target'],
-      'dependencies': [
-        'js2c#host',
-        'v8_base',
-      ],
-      'include_dirs+': [
-        '../../src',
-      ],
-      'sources': [
-        '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
-        '../../src/snapshot-empty.cc',
-      ],
-      'conditions': [
-        # The ARM assembler assumes the host is 32 bits, so force building
-        # 32-bit host tools.
-        ['v8_target_arch=="arm" and host_arch=="x64" and _toolset=="host"', {
-          'cflags': ['-m32'],
-          'ldflags': ['-m32'],
-        }],
-        ['OS=="win" and component=="shared_library"', {
-          'defines': [
-            'BUILDING_V8_SHARED',
-          ],
-        }],
-      ]
-    },
-    {
-      'target_name': 'v8_base',
-      'type': '<(library)',
-      'toolsets': ['host', 'target'],
-      'include_dirs+': [
-        '../../src',
-      ],
-      'sources': [
-        '../../src/accessors.cc',
-        '../../src/accessors.h',
-        '../../src/allocation.cc',
-        '../../src/allocation.h',
-        '../../src/api.cc',
-        '../../src/api.h',
-        '../../src/apiutils.h',
-        '../../src/arguments.h',
-        '../../src/assembler.cc',
-        '../../src/assembler.h',
-        '../../src/ast.cc',
-        '../../src/ast-inl.h',
-        '../../src/ast.h',
-        '../../src/atomicops_internals_x86_gcc.cc',
-        '../../src/bignum.cc',
-        '../../src/bignum.h',
-        '../../src/bignum-dtoa.cc',
-        '../../src/bignum-dtoa.h',
-        '../../src/bootstrapper.cc',
-        '../../src/bootstrapper.h',
-        '../../src/builtins.cc',
-        '../../src/builtins.h',
-        '../../src/bytecodes-irregexp.h',
-        '../../src/cached-powers.cc',
-        '../../src/cached-powers.h',
-        '../../src/char-predicates-inl.h',
-        '../../src/char-predicates.h',
-        '../../src/checks.cc',
-        '../../src/checks.h',
-        '../../src/circular-queue-inl.h',
-        '../../src/circular-queue.cc',
-        '../../src/circular-queue.h',
-        '../../src/code-stubs.cc',
-        '../../src/code-stubs.h',
-        '../../src/code.h',
-        '../../src/codegen-inl.h',
-        '../../src/codegen.cc',
-        '../../src/codegen.h',
-        '../../src/compilation-cache.cc',
-        '../../src/compilation-cache.h',
-        '../../src/compiler.cc',
-        '../../src/compiler.h',
-        '../../src/contexts.cc',
-        '../../src/contexts.h',
-        '../../src/conversions-inl.h',
-        '../../src/conversions.cc',
-        '../../src/conversions.h',
-        '../../src/counters.cc',
-        '../../src/counters.h',
-        '../../src/cpu.h',
-        '../../src/cpu-profiler-inl.h',
-        '../../src/cpu-profiler.cc',
-        '../../src/cpu-profiler.h',
-        '../../src/data-flow.cc',
-        '../../src/data-flow.h',
-        '../../src/dateparser.cc',
-        '../../src/dateparser.h',
-        '../../src/dateparser-inl.h',
-        '../../src/debug.cc',
-        '../../src/debug.h',
-        '../../src/debug-agent.cc',
-        '../../src/debug-agent.h',
-        '../../src/deoptimizer.cc',
-        '../../src/deoptimizer.h',	
-        '../../src/disasm.h',
-        '../../src/disassembler.cc',
-        '../../src/disassembler.h',
-        '../../src/dtoa.cc',
-        '../../src/dtoa.h',
-        '../../src/diy-fp.cc',
-        '../../src/diy-fp.h',
-        '../../src/double.h',
-        '../../src/execution.cc',
-        '../../src/execution.h',
-        '../../src/factory.cc',
-        '../../src/factory.h',
-        '../../src/fast-dtoa.cc',
-        '../../src/fast-dtoa.h',
-        '../../src/flag-definitions.h',
-        '../../src/fixed-dtoa.cc',
-        '../../src/fixed-dtoa.h',
-        '../../src/flags.cc',
-        '../../src/flags.h',
-        '../../src/frame-element.cc',
-        '../../src/frame-element.h',
-        '../../src/frames-inl.h',
-        '../../src/frames.cc',
-        '../../src/frames.h',
-        '../../src/full-codegen.cc',
-        '../../src/full-codegen.h',
-        '../../src/func-name-inferrer.cc',
-        '../../src/func-name-inferrer.h',
-        '../../src/global-handles.cc',
-        '../../src/global-handles.h',
-        '../../src/globals.h',
-        '../../src/handles-inl.h',
-        '../../src/handles.cc',
-        '../../src/handles.h',
-        '../../src/hashmap.cc',
-        '../../src/hashmap.h',
-        '../../src/heap-inl.h',
-        '../../src/heap.cc',
-        '../../src/heap.h',
-        '../../src/heap-profiler.cc',
-        '../../src/heap-profiler.h',
-        '../../src/hydrogen.cc',
-        '../../src/hydrogen.h',
-        '../../src/hydrogen-instructions.cc',
-        '../../src/hydrogen-instructions.h',
-        '../../src/ic-inl.h',
-        '../../src/ic.cc',
-        '../../src/ic.h',
-        '../../src/interpreter-irregexp.cc',
-        '../../src/interpreter-irregexp.h',
-        '../../src/jump-target-inl.h',
-        '../../src/jump-target.cc',
-        '../../src/jump-target.h',
-        '../../src/jsregexp.cc',
-        '../../src/jsregexp.h',
-        '../../src/list-inl.h',
-        '../../src/list.h',
-        '../../src/lithium-allocator.cc',
-        '../../src/lithium-allocator.h',
-        '../../src/liveedit.cc',
-        '../../src/liveedit.h',
-        '../../src/log-inl.h',
-        '../../src/log-utils.cc',
-        '../../src/log-utils.h',
-        '../../src/log.cc',
-        '../../src/log.h',
-        '../../src/macro-assembler.h',
-        '../../src/mark-compact.cc',
-        '../../src/mark-compact.h',
-        '../../src/memory.h',
-        '../../src/messages.cc',
-        '../../src/messages.h',
-        '../../src/natives.h',
-        '../../src/objects-debug.cc',
-        '../../src/objects-inl.h',
-        '../../src/objects-visiting.cc',
-        '../../src/objects-visiting.h',
-        '../../src/objects.cc',
-        '../../src/objects.h',
-        '../../src/oprofile-agent.h',
-        '../../src/oprofile-agent.cc',
-        '../../src/parser.cc',
-        '../../src/parser.h',
-        '../../src/platform.h',
-        '../../src/preparse-data.cc',
-        '../../src/preparse-data.h',
-        '../../src/preparser.cc',
-        '../../src/preparser.h',
-        '../../src/prettyprinter.cc',
-        '../../src/prettyprinter.h',
-        '../../src/property.cc',
-        '../../src/property.h',
-        '../../src/profile-generator-inl.h',
-        '../../src/profile-generator.cc',
-        '../../src/profile-generator.h',
-        '../../src/regexp-macro-assembler-irregexp-inl.h',
-        '../../src/regexp-macro-assembler-irregexp.cc',
-        '../../src/regexp-macro-assembler-irregexp.h',
-        '../../src/regexp-macro-assembler-tracer.cc',
-        '../../src/regexp-macro-assembler-tracer.h',
-        '../../src/regexp-macro-assembler.cc',
-        '../../src/regexp-macro-assembler.h',
-        '../../src/regexp-stack.cc',
-        '../../src/regexp-stack.h',
-        '../../src/register-allocator.h',
-        '../../src/register-allocator-inl.h',
-        '../../src/register-allocator.cc',
-        '../../src/rewriter.cc',
-        '../../src/rewriter.h',
-        '../../src/runtime.cc',
-        '../../src/runtime.h',
-        '../../src/runtime-profiler.cc',
-        '../../src/runtime-profiler.h',
-        '../../src/safepoint-table.cc',
-        '../../src/safepoint-table.h',
-        '../../src/scanner-base.cc',
-        '../../src/scanner-base.h',
-        '../../src/scanner.cc',
-        '../../src/scanner.h',
-        '../../src/scopeinfo.cc',
-        '../../src/scopeinfo.h',
-        '../../src/scopes.cc',
-        '../../src/scopes.h',
-        '../../src/serialize.cc',
-        '../../src/serialize.h',
-        '../../src/shell.h',
-        '../../src/smart-pointer.h',
-        '../../src/snapshot-common.cc',
-        '../../src/snapshot.h',
-        '../../src/spaces-inl.h',
-        '../../src/spaces.cc',
-        '../../src/spaces.h',
-        '../../src/string-search.cc',
-        '../../src/string-search.h',
-        '../../src/string-stream.cc',
-        '../../src/string-stream.h',
-        '../../src/strtod.cc',
-        '../../src/strtod.h',
-        '../../src/stub-cache.cc',
-        '../../src/stub-cache.h',
-        '../../src/token.cc',
-        '../../src/token.h',
-        '../../src/top.cc',
-        '../../src/top.h',
-        '../../src/type-info.cc',
-        '../../src/type-info.h',
-        '../../src/unbound-queue-inl.h',
-        '../../src/unbound-queue.h',
-        '../../src/unicode-inl.h',
-        '../../src/unicode.cc',
-        '../../src/unicode.h',
-        '../../src/utils.cc',
-        '../../src/utils.h',
-        '../../src/v8-counters.cc',
-        '../../src/v8-counters.h',
-        '../../src/v8.cc',
-        '../../src/v8.h',
-        '../../src/v8checks.h',
-        '../../src/v8globals.h',
-        '../../src/v8threads.cc',
-        '../../src/v8threads.h',
-        '../../src/v8utils.h',
-        '../../src/variables.cc',
-        '../../src/variables.h',
-        '../../src/version.cc',
-        '../../src/version.h',
-        '../../src/virtual-frame-inl.h',
-        '../../src/virtual-frame.cc',
-        '../../src/virtual-frame.h',
-        '../../src/vm-state-inl.h',
-        '../../src/vm-state.h',
-        '../../src/zone-inl.h',
-        '../../src/zone.cc',
-        '../../src/zone.h',
-        '../../src/extensions/externalize-string-extension.cc',
-        '../../src/extensions/externalize-string-extension.h',
-        '../../src/extensions/gc-extension.cc',
-        '../../src/extensions/gc-extension.h',
-      ],
-      'conditions': [
-        ['v8_target_arch=="arm"', {
-          'include_dirs+': [
-            '../../src/arm',
+          'target_name': 'v8_preparser',
+          'include_dirs': [
+            '../../include',
+            '../../src',
           ],
           'sources': [
-            '../../src/jump-target-light.h',
-            '../../src/jump-target-light-inl.h',
-            '../../src/jump-target-light.cc',
-            '../../src/virtual-frame-light-inl.h',
-            '../../src/virtual-frame-light.cc',
-            '../../src/arm/assembler-arm-inl.h',
-            '../../src/arm/assembler-arm.cc',
-            '../../src/arm/assembler-arm.h',
-            '../../src/arm/builtins-arm.cc',
-            '../../src/arm/code-stubs-arm.cc',
-            '../../src/arm/code-stubs-arm.h',
-            '../../src/arm/codegen-arm.cc',
-            '../../src/arm/codegen-arm.h',
-            '../../src/arm/constants-arm.h',
-            '../../src/arm/constants-arm.cc',
-            '../../src/arm/cpu-arm.cc',
-            '../../src/arm/debug-arm.cc',
-            '../../src/arm/deoptimizer-arm.cc',
-            '../../src/arm/disasm-arm.cc',
-            '../../src/arm/frames-arm.cc',
-            '../../src/arm/frames-arm.h',
-            '../../src/arm/full-codegen-arm.cc',
-            '../../src/arm/ic-arm.cc',
-            '../../src/arm/jump-target-arm.cc',
-            '../../src/arm/lithium-codegen-arm.cc',
-            '../../src/arm/lithium-codegen-arm.h',
-            '../../src/arm/lithium-arm.cc',
-            '../../src/arm/lithium-arm.h',
-            '../../src/arm/macro-assembler-arm.cc',
-            '../../src/arm/macro-assembler-arm.h',
-            '../../src/arm/regexp-macro-assembler-arm.cc',
-            '../../src/arm/regexp-macro-assembler-arm.h',
-            '../../src/arm/register-allocator-arm.cc',
-            '../../src/arm/simulator-arm.cc',
-            '../../src/arm/stub-cache-arm.cc',
-            '../../src/arm/virtual-frame-arm-inl.h',
-            '../../src/arm/virtual-frame-arm.cc',
-            '../../src/arm/virtual-frame-arm.h',
+            '../../src/allocation.cc',
+            '../../src/hashmap.cc',
+            '../../src/preparse-data.cc',
+            '../../src/preparser.cc',
+            '../../src/preparser-api.cc',
+            '../../src/scanner-base.cc',
+            '../../src/token.cc',
+            '../../src/unicode.cc',
+          ],
+          'conditions': [
+            ['OS=="win" and component=="shared_library"', {
+              'sources': [ '../../src/v8preparserdll-main.cc' ],
+              'defines': [ 'BUILDING_V8_SHARED' ],
+              'direct_dependent_settings': {
+                'defines': [ 'USING_V8_SHARED' ]
+              },
+              'type': '<(component)',
+            } , {
+              'type': 'none'
+            }],
+            ['OS!="win"', {
+              'type': '<(library)'
+            }],
+          ]
+        },
+        {
+          'target_name': 'v8_snapshot',
+          'type': '<(library)',
+          'conditions': [
+            ['OS=="win" and component=="shared_library"', {
+              'defines': [
+                'BUILDING_V8_SHARED',
+              ],
+            }],
+          ],
+          'dependencies': [
+            'mksnapshot#host',
+            'js2c#host',
+            'v8_base',
+          ],
+          'include_dirs+': [
+            '../../src',
+          ],
+          'sources': [
+            '<(SHARED_INTERMEDIATE_DIR)/libraries-empty.cc',
+            '<(INTERMEDIATE_DIR)/snapshot.cc',
+          ],
+          'actions': [
+            {
+              'action_name': 'run_mksnapshot',
+              'inputs': [
+                '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
+              ],
+              'outputs': [
+                '<(INTERMEDIATE_DIR)/snapshot.cc',
+              ],
+              'action': ['<@(_inputs)', '<@(_outputs)'],
+            },
+          ],
+        },
+        {
+          'target_name': 'v8_nosnapshot',
+          'type': '<(library)',
+          'toolsets': ['host', 'target'],
+          'dependencies': [
+            'js2c#host',
+            'v8_base',
+          ],
+          'include_dirs+': [
+            '../../src',
+          ],
+          'sources': [
+            '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
+            '../../src/snapshot-empty.cc',
           ],
           'conditions': [
             # The ARM assembler assumes the host is 32 bits, so force building
             # 32-bit host tools.
-            ['host_arch=="x64" and _toolset=="host"', {
+            ['v8_target_arch=="arm" and host_arch=="x64" and _toolset=="host"', {
+              'cflags': ['-m32'],
+              'ldflags': ['-m32'],
+            }],
+            ['OS=="win" and component=="shared_library"', {
+              'defines': [
+                'BUILDING_V8_SHARED',
+              ],
+            }],
+          ]
+        },
+        {
+          'target_name': 'v8_base',
+          'type': '<(library)',
+          'toolsets': ['host', 'target'],
+          'include_dirs+': [
+            '../../src',
+          ],
+          'sources': [
+            '../../src/accessors.cc',
+            '../../src/accessors.h',
+            '../../src/allocation.cc',
+            '../../src/allocation.h',
+            '../../src/api.cc',
+            '../../src/api.h',
+            '../../src/apiutils.h',
+            '../../src/arguments.h',
+            '../../src/assembler.cc',
+            '../../src/assembler.h',
+            '../../src/ast.cc',
+            '../../src/ast-inl.h',
+            '../../src/ast.h',
+            '../../src/atomicops_internals_x86_gcc.cc',
+            '../../src/bignum.cc',
+            '../../src/bignum.h',
+            '../../src/bignum-dtoa.cc',
+            '../../src/bignum-dtoa.h',
+            '../../src/bootstrapper.cc',
+            '../../src/bootstrapper.h',
+            '../../src/builtins.cc',
+            '../../src/builtins.h',
+            '../../src/bytecodes-irregexp.h',
+            '../../src/cached-powers.cc',
+            '../../src/cached-powers.h',
+            '../../src/char-predicates-inl.h',
+            '../../src/char-predicates.h',
+            '../../src/checks.cc',
+            '../../src/checks.h',
+            '../../src/circular-queue-inl.h',
+            '../../src/circular-queue.cc',
+            '../../src/circular-queue.h',
+            '../../src/code-stubs.cc',
+            '../../src/code-stubs.h',
+            '../../src/code.h',
+            '../../src/codegen-inl.h',
+            '../../src/codegen.cc',
+            '../../src/codegen.h',
+            '../../src/compilation-cache.cc',
+            '../../src/compilation-cache.h',
+            '../../src/compiler.cc',
+            '../../src/compiler.h',
+            '../../src/contexts.cc',
+            '../../src/contexts.h',
+            '../../src/conversions-inl.h',
+            '../../src/conversions.cc',
+            '../../src/conversions.h',
+            '../../src/counters.cc',
+            '../../src/counters.h',
+            '../../src/cpu.h',
+            '../../src/cpu-profiler-inl.h',
+            '../../src/cpu-profiler.cc',
+            '../../src/cpu-profiler.h',
+            '../../src/data-flow.cc',
+            '../../src/data-flow.h',
+            '../../src/dateparser.cc',
+            '../../src/dateparser.h',
+            '../../src/dateparser-inl.h',
+            '../../src/debug.cc',
+            '../../src/debug.h',
+            '../../src/debug-agent.cc',
+            '../../src/debug-agent.h',
+            '../../src/deoptimizer.cc',
+            '../../src/deoptimizer.h',
+            '../../src/disasm.h',
+            '../../src/disassembler.cc',
+            '../../src/disassembler.h',
+            '../../src/dtoa.cc',
+            '../../src/dtoa.h',
+            '../../src/diy-fp.cc',
+            '../../src/diy-fp.h',
+            '../../src/double.h',
+            '../../src/execution.cc',
+            '../../src/execution.h',
+            '../../src/factory.cc',
+            '../../src/factory.h',
+            '../../src/fast-dtoa.cc',
+            '../../src/fast-dtoa.h',
+            '../../src/flag-definitions.h',
+            '../../src/fixed-dtoa.cc',
+            '../../src/fixed-dtoa.h',
+            '../../src/flags.cc',
+            '../../src/flags.h',
+            '../../src/frame-element.cc',
+            '../../src/frame-element.h',
+            '../../src/frames-inl.h',
+            '../../src/frames.cc',
+            '../../src/frames.h',
+            '../../src/full-codegen.cc',
+            '../../src/full-codegen.h',
+            '../../src/func-name-inferrer.cc',
+            '../../src/func-name-inferrer.h',
+            '../../src/global-handles.cc',
+            '../../src/global-handles.h',
+            '../../src/globals.h',
+            '../../src/handles-inl.h',
+            '../../src/handles.cc',
+            '../../src/handles.h',
+            '../../src/hashmap.cc',
+            '../../src/hashmap.h',
+            '../../src/heap-inl.h',
+            '../../src/heap.cc',
+            '../../src/heap.h',
+            '../../src/heap-profiler.cc',
+            '../../src/heap-profiler.h',
+            '../../src/hydrogen.cc',
+            '../../src/hydrogen.h',
+            '../../src/hydrogen-instructions.cc',
+            '../../src/hydrogen-instructions.h',
+            '../../src/ic-inl.h',
+            '../../src/ic.cc',
+            '../../src/ic.h',
+            '../../src/interpreter-irregexp.cc',
+            '../../src/interpreter-irregexp.h',
+            '../../src/jump-target-inl.h',
+            '../../src/jump-target.cc',
+            '../../src/jump-target.h',
+            '../../src/jsregexp.cc',
+            '../../src/jsregexp.h',
+            '../../src/list-inl.h',
+            '../../src/list.h',
+            '../../src/lithium-allocator.cc',
+            '../../src/lithium-allocator.h',
+            '../../src/liveedit.cc',
+            '../../src/liveedit.h',
+            '../../src/log-inl.h',
+            '../../src/log-utils.cc',
+            '../../src/log-utils.h',
+            '../../src/log.cc',
+            '../../src/log.h',
+            '../../src/macro-assembler.h',
+            '../../src/mark-compact.cc',
+            '../../src/mark-compact.h',
+            '../../src/memory.h',
+            '../../src/messages.cc',
+            '../../src/messages.h',
+            '../../src/natives.h',
+            '../../src/objects-debug.cc',
+            '../../src/objects-printer.cc',
+            '../../src/objects-inl.h',
+            '../../src/objects-visiting.cc',
+            '../../src/objects-visiting.h',
+            '../../src/objects.cc',
+            '../../src/objects.h',
+            '../../src/oprofile-agent.h',
+            '../../src/oprofile-agent.cc',
+            '../../src/parser.cc',
+            '../../src/parser.h',
+            '../../src/platform.h',
+            '../../src/preparse-data.cc',
+            '../../src/preparse-data.h',
+            '../../src/preparser.cc',
+            '../../src/preparser.h',
+            '../../src/prettyprinter.cc',
+            '../../src/prettyprinter.h',
+            '../../src/property.cc',
+            '../../src/property.h',
+            '../../src/profile-generator-inl.h',
+            '../../src/profile-generator.cc',
+            '../../src/profile-generator.h',
+            '../../src/regexp-macro-assembler-irregexp-inl.h',
+            '../../src/regexp-macro-assembler-irregexp.cc',
+            '../../src/regexp-macro-assembler-irregexp.h',
+            '../../src/regexp-macro-assembler-tracer.cc',
+            '../../src/regexp-macro-assembler-tracer.h',
+            '../../src/regexp-macro-assembler.cc',
+            '../../src/regexp-macro-assembler.h',
+            '../../src/regexp-stack.cc',
+            '../../src/regexp-stack.h',
+            '../../src/register-allocator.h',
+            '../../src/register-allocator-inl.h',
+            '../../src/register-allocator.cc',
+            '../../src/rewriter.cc',
+            '../../src/rewriter.h',
+            '../../src/runtime.cc',
+            '../../src/runtime.h',
+            '../../src/runtime-profiler.cc',
+            '../../src/runtime-profiler.h',
+            '../../src/safepoint-table.cc',
+            '../../src/safepoint-table.h',
+            '../../src/scanner-base.cc',
+            '../../src/scanner-base.h',
+            '../../src/scanner.cc',
+            '../../src/scanner.h',
+            '../../src/scopeinfo.cc',
+            '../../src/scopeinfo.h',
+            '../../src/scopes.cc',
+            '../../src/scopes.h',
+            '../../src/serialize.cc',
+            '../../src/serialize.h',
+            '../../src/shell.h',
+            '../../src/smart-pointer.h',
+            '../../src/snapshot-common.cc',
+            '../../src/snapshot.h',
+            '../../src/spaces-inl.h',
+            '../../src/spaces.cc',
+            '../../src/spaces.h',
+            '../../src/string-search.cc',
+            '../../src/string-search.h',
+            '../../src/string-stream.cc',
+            '../../src/string-stream.h',
+            '../../src/strtod.cc',
+            '../../src/strtod.h',
+            '../../src/stub-cache.cc',
+            '../../src/stub-cache.h',
+            '../../src/token.cc',
+            '../../src/token.h',
+            '../../src/top.cc',
+            '../../src/top.h',
+            '../../src/type-info.cc',
+            '../../src/type-info.h',
+            '../../src/unbound-queue-inl.h',
+            '../../src/unbound-queue.h',
+            '../../src/unicode-inl.h',
+            '../../src/unicode.cc',
+            '../../src/unicode.h',
+            '../../src/utils.cc',
+            '../../src/utils.h',
+            '../../src/v8-counters.cc',
+            '../../src/v8-counters.h',
+            '../../src/v8.cc',
+            '../../src/v8.h',
+            '../../src/v8checks.h',
+            '../../src/v8globals.h',
+            '../../src/v8threads.cc',
+            '../../src/v8threads.h',
+            '../../src/v8utils.h',
+            '../../src/variables.cc',
+            '../../src/variables.h',
+            '../../src/version.cc',
+            '../../src/version.h',
+            '../../src/virtual-frame-inl.h',
+            '../../src/virtual-frame.cc',
+            '../../src/virtual-frame.h',
+            '../../src/vm-state-inl.h',
+            '../../src/vm-state.h',
+            '../../src/zone-inl.h',
+            '../../src/zone.cc',
+            '../../src/zone.h',
+            '../../src/extensions/externalize-string-extension.cc',
+            '../../src/extensions/externalize-string-extension.h',
+            '../../src/extensions/gc-extension.cc',
+            '../../src/extensions/gc-extension.h',
+          ],
+          'conditions': [
+            ['v8_target_arch=="arm"', {
+              'include_dirs+': [
+                '../../src/arm',
+              ],
+              'sources': [
+                '../../src/jump-target-light.h',
+                '../../src/jump-target-light-inl.h',
+                '../../src/jump-target-light.cc',
+                '../../src/virtual-frame-light-inl.h',
+                '../../src/virtual-frame-light.cc',
+                '../../src/arm/assembler-arm-inl.h',
+                '../../src/arm/assembler-arm.cc',
+                '../../src/arm/assembler-arm.h',
+                '../../src/arm/builtins-arm.cc',
+                '../../src/arm/code-stubs-arm.cc',
+                '../../src/arm/code-stubs-arm.h',
+                '../../src/arm/codegen-arm.cc',
+                '../../src/arm/codegen-arm.h',
+                '../../src/arm/constants-arm.h',
+                '../../src/arm/constants-arm.cc',
+                '../../src/arm/cpu-arm.cc',
+                '../../src/arm/debug-arm.cc',
+                '../../src/arm/deoptimizer-arm.cc',
+                '../../src/arm/disasm-arm.cc',
+                '../../src/arm/frames-arm.cc',
+                '../../src/arm/frames-arm.h',
+                '../../src/arm/full-codegen-arm.cc',
+                '../../src/arm/ic-arm.cc',
+                '../../src/arm/jump-target-arm.cc',
+                '../../src/arm/lithium-codegen-arm.cc',
+                '../../src/arm/lithium-codegen-arm.h',
+                '../../src/arm/lithium-arm.cc',
+                '../../src/arm/lithium-arm.h',
+                '../../src/arm/macro-assembler-arm.cc',
+                '../../src/arm/macro-assembler-arm.h',
+                '../../src/arm/regexp-macro-assembler-arm.cc',
+                '../../src/arm/regexp-macro-assembler-arm.h',
+                '../../src/arm/register-allocator-arm.cc',
+                '../../src/arm/simulator-arm.cc',
+                '../../src/arm/stub-cache-arm.cc',
+                '../../src/arm/virtual-frame-arm-inl.h',
+                '../../src/arm/virtual-frame-arm.cc',
+                '../../src/arm/virtual-frame-arm.h',
+              ],
+              'conditions': [
+                # The ARM assembler assumes the host is 32 bits,
+                # so force building 32-bit host tools.
+                ['host_arch=="x64" and _toolset=="host"', {
+                  'cflags': ['-m32'],
+                  'ldflags': ['-m32'],
+                }]
+              ]
+            }],
+            ['v8_target_arch=="ia32" or v8_target_arch=="mac" or OS=="mac"', {
+              'include_dirs+': [
+                '../../src/ia32',
+              ],
+              'sources': [
+                '../../src/jump-target-heavy.h',
+                '../../src/jump-target-heavy-inl.h',
+                '../../src/jump-target-heavy.cc',
+                '../../src/virtual-frame-heavy-inl.h',
+                '../../src/virtual-frame-heavy.cc',
+                '../../src/ia32/assembler-ia32-inl.h',
+                '../../src/ia32/assembler-ia32.cc',
+                '../../src/ia32/assembler-ia32.h',
+                '../../src/ia32/builtins-ia32.cc',
+                '../../src/ia32/code-stubs-ia32.cc',
+                '../../src/ia32/code-stubs-ia32.h',
+                '../../src/ia32/codegen-ia32.cc',
+                '../../src/ia32/codegen-ia32.h',
+                '../../src/ia32/cpu-ia32.cc',
+                '../../src/ia32/debug-ia32.cc',
+                '../../src/ia32/deoptimizer-ia32.cc',
+                '../../src/ia32/disasm-ia32.cc',
+                '../../src/ia32/frames-ia32.cc',
+                '../../src/ia32/frames-ia32.h',
+                '../../src/ia32/full-codegen-ia32.cc',
+                '../../src/ia32/ic-ia32.cc',
+                '../../src/ia32/jump-target-ia32.cc',
+                '../../src/ia32/lithium-codegen-ia32.cc',
+                '../../src/ia32/lithium-codegen-ia32.h',
+                '../../src/ia32/lithium-ia32.cc',
+                '../../src/ia32/lithium-ia32.h',
+                '../../src/ia32/macro-assembler-ia32.cc',
+                '../../src/ia32/macro-assembler-ia32.h',
+                '../../src/ia32/regexp-macro-assembler-ia32.cc',
+                '../../src/ia32/regexp-macro-assembler-ia32.h',
+                '../../src/ia32/register-allocator-ia32.cc',
+                '../../src/ia32/stub-cache-ia32.cc',
+                '../../src/ia32/virtual-frame-ia32.cc',
+                '../../src/ia32/virtual-frame-ia32.h',
+              ],
+            }],
+            ['v8_target_arch=="x64" or v8_target_arch=="mac" or OS=="mac"', {
+              'include_dirs+': [
+                '../../src/x64',
+              ],
+              'sources': [
+                '../../src/jump-target-heavy.h',
+                '../../src/jump-target-heavy-inl.h',
+                '../../src/jump-target-heavy.cc',
+                '../../src/virtual-frame-heavy-inl.h',
+                '../../src/virtual-frame-heavy.cc',
+                '../../src/x64/assembler-x64-inl.h',
+                '../../src/x64/assembler-x64.cc',
+                '../../src/x64/assembler-x64.h',
+                '../../src/x64/builtins-x64.cc',
+                '../../src/x64/code-stubs-x64.cc',
+                '../../src/x64/code-stubs-x64.h',
+                '../../src/x64/codegen-x64.cc',
+                '../../src/x64/codegen-x64.h',
+                '../../src/x64/cpu-x64.cc',
+                '../../src/x64/debug-x64.cc',
+                '../../src/x64/deoptimizer-x64.cc',
+                '../../src/x64/disasm-x64.cc',
+                '../../src/x64/frames-x64.cc',
+                '../../src/x64/frames-x64.h',
+                '../../src/x64/full-codegen-x64.cc',
+                '../../src/x64/ic-x64.cc',
+                '../../src/x64/jump-target-x64.cc',
+                '../../src/x64/macro-assembler-x64.cc',
+                '../../src/x64/macro-assembler-x64.h',
+                '../../src/x64/regexp-macro-assembler-x64.cc',
+                '../../src/x64/regexp-macro-assembler-x64.h',
+                '../../src/x64/register-allocator-x64.cc',
+                '../../src/x64/stub-cache-x64.cc',
+                '../../src/x64/virtual-frame-x64.cc',
+                '../../src/x64/virtual-frame-x64.h',
+              ],
+            }],
+            ['OS=="linux"', {
+                'link_settings': {
+                  'libraries': [
+                    # Needed for clock_gettime() used by src/platform-linux.cc.
+                    '-lrt',
+                ]},
+                'sources': [
+                  '../../src/platform-linux.cc',
+                  '../../src/platform-posix.cc'
+                ],
+              }
+            ],
+            ['OS=="freebsd"', {
+                'link_settings': {
+                  'libraries': [
+                    '-L/usr/local/lib -lexecinfo',
+                ]},
+                'sources': [
+                  '../../src/platform-freebsd.cc',
+                  '../../src/platform-posix.cc'
+                ],
+              }
+            ],
+            ['OS=="openbsd"', {
+                'link_settings': {
+                  'libraries': [
+                    '-L/usr/local/lib -lexecinfo',
+                ]},
+                'sources': [
+                  '../../src/platform-openbsd.cc',
+                  '../../src/platform-posix.cc'
+                ],
+              }
+            ],
+            ['OS=="mac"', {
+              'sources': [
+                '../../src/platform-macos.cc',
+                '../../src/platform-posix.cc'
+              ]},
+            ],
+            ['OS=="win"', {
+              'sources': [
+                '../../src/platform-win32.cc',
+              ],
+              # 4355, 4800 came from common.vsprops
+              'msvs_disabled_warnings': [4355, 4800],
+              'link_settings':  {
+                'libraries': [ '-lwinmm.lib' ],
+              },
+            }],
+            ['OS=="win" and component=="shared_library"', {
+              'defines': [
+                'BUILDING_V8_SHARED'
+              ],
+            }],
+          ],
+        },
+        {
+          'target_name': 'js2c',
+          'type': 'none',
+          'toolsets': ['host'],
+          'variables': {
+            'library_files': [
+              '../../src/runtime.js',
+              '../../src/v8natives.js',
+              '../../src/array.js',
+              '../../src/string.js',
+              '../../src/uri.js',
+              '../../src/math.js',
+              '../../src/messages.js',
+              '../../src/apinatives.js',
+              '../../src/debug-debugger.js',
+              '../../src/mirror-debugger.js',
+              '../../src/liveedit-debugger.js',
+              '../../src/date.js',
+              '../../src/json.js',
+              '../../src/regexp.js',
+              '../../src/macros.py',
+            ],
+          },
+          'actions': [
+            {
+              'action_name': 'js2c',
+              'inputs': [
+                '../../tools/js2c.py',
+                '<@(library_files)',
+              ],
+              'outputs': [
+                '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
+                '<(SHARED_INTERMEDIATE_DIR)/libraries-empty.cc',
+              ],
+              'action': [
+                'python',
+                '../../tools/js2c.py',
+                '<@(_outputs)',
+                'CORE',
+                '<@(library_files)'
+              ],
+            },
+          ],
+        },
+        {
+          'target_name': 'mksnapshot',
+          'type': 'executable',
+          'toolsets': ['host'],
+          'dependencies': [
+            'v8_nosnapshot',
+          ],
+          'include_dirs+': [
+            '../../src',
+          ],
+          'sources': [
+            '../../src/mksnapshot.cc',
+          ],
+          'conditions': [
+            # The ARM assembler assumes the host is 32 bits, so force building
+            # 32-bit host tools.
+            ['v8_target_arch=="arm" and host_arch=="x64" and _toolset=="host"', {
               'cflags': ['-m32'],
               'ldflags': ['-m32'],
             }]
           ]
-        }],
-        ['v8_target_arch=="ia32" or v8_target_arch=="mac" or OS=="mac"', {
-          'include_dirs+': [
-            '../../src/ia32',
-          ],
-          'sources': [
-            '../../src/jump-target-heavy.h',
-            '../../src/jump-target-heavy-inl.h',
-            '../../src/jump-target-heavy.cc',
-            '../../src/virtual-frame-heavy-inl.h',
-            '../../src/virtual-frame-heavy.cc',
-            '../../src/ia32/assembler-ia32-inl.h',
-            '../../src/ia32/assembler-ia32.cc',
-            '../../src/ia32/assembler-ia32.h',
-            '../../src/ia32/builtins-ia32.cc',
-            '../../src/ia32/code-stubs-ia32.cc',
-            '../../src/ia32/code-stubs-ia32.h',
-            '../../src/ia32/codegen-ia32.cc',
-            '../../src/ia32/codegen-ia32.h',
-            '../../src/ia32/cpu-ia32.cc',
-            '../../src/ia32/debug-ia32.cc',
-            '../../src/ia32/deoptimizer-ia32.cc',
-            '../../src/ia32/disasm-ia32.cc',
-            '../../src/ia32/frames-ia32.cc',
-            '../../src/ia32/frames-ia32.h',
-            '../../src/ia32/full-codegen-ia32.cc',
-            '../../src/ia32/ic-ia32.cc',
-            '../../src/ia32/jump-target-ia32.cc',
-            '../../src/ia32/lithium-codegen-ia32.cc',
-            '../../src/ia32/lithium-codegen-ia32.h',
-            '../../src/ia32/lithium-ia32.cc',
-            '../../src/ia32/lithium-ia32.h',
-            '../../src/ia32/macro-assembler-ia32.cc',
-            '../../src/ia32/macro-assembler-ia32.h',
-            '../../src/ia32/regexp-macro-assembler-ia32.cc',
-            '../../src/ia32/regexp-macro-assembler-ia32.h',
-            '../../src/ia32/register-allocator-ia32.cc',
-            '../../src/ia32/stub-cache-ia32.cc',
-            '../../src/ia32/virtual-frame-ia32.cc',
-            '../../src/ia32/virtual-frame-ia32.h',
-          ],
-        }],
-        ['v8_target_arch=="x64" or v8_target_arch=="mac" or OS=="mac"', {
-          'include_dirs+': [
-            '../../src/x64',
-          ],
-          'sources': [
-            '../../src/jump-target-heavy.h',
-            '../../src/jump-target-heavy-inl.h',
-            '../../src/jump-target-heavy.cc',
-            '../../src/virtual-frame-heavy-inl.h',
-            '../../src/virtual-frame-heavy.cc',
-            '../../src/x64/assembler-x64-inl.h',
-            '../../src/x64/assembler-x64.cc',
-            '../../src/x64/assembler-x64.h',
-            '../../src/x64/builtins-x64.cc',
-            '../../src/x64/code-stubs-x64.cc',
-            '../../src/x64/code-stubs-x64.h',
-            '../../src/x64/codegen-x64.cc',
-            '../../src/x64/codegen-x64.h',
-            '../../src/x64/cpu-x64.cc',
-            '../../src/x64/debug-x64.cc',
-            '../../src/x64/deoptimizer-x64.cc',
-            '../../src/x64/disasm-x64.cc',
-            '../../src/x64/frames-x64.cc',
-            '../../src/x64/frames-x64.h',
-            '../../src/x64/full-codegen-x64.cc',
-            '../../src/x64/ic-x64.cc',
-            '../../src/x64/jump-target-x64.cc',
-            '../../src/x64/macro-assembler-x64.cc',
-            '../../src/x64/macro-assembler-x64.h',
-            '../../src/x64/regexp-macro-assembler-x64.cc',
-            '../../src/x64/regexp-macro-assembler-x64.h',
-            '../../src/x64/register-allocator-x64.cc',
-            '../../src/x64/stub-cache-x64.cc',
-            '../../src/x64/virtual-frame-x64.cc',
-            '../../src/x64/virtual-frame-x64.h',
-          ],
-        }],
-        ['OS=="linux"', {
-            'link_settings': {
-              'libraries': [
-                # Needed for clock_gettime() used by src/platform-linux.cc.
-                '-lrt',
-            ]},
-            'sources': [
-              '../../src/platform-linux.cc',
-              '../../src/platform-posix.cc'
-            ],
-          }
-        ],
-        ['OS=="freebsd"', {
-            'link_settings': {
-              'libraries': [
-                '-L/usr/local/lib -lexecinfo',
-            ]},
-            'sources': [
-              '../../src/platform-freebsd.cc',
-              '../../src/platform-posix.cc'
-            ],
-          }
-        ],
-        ['OS=="openbsd"', {
-            'link_settings': {
-              'libraries': [
-                '-L/usr/local/lib -lexecinfo',
-            ]},
-            'sources': [
-              '../../src/platform-openbsd.cc',
-              '../../src/platform-posix.cc'
-            ],
-          }
-        ],
-        ['OS=="mac"', {
-          'sources': [
-            '../../src/platform-macos.cc',
-            '../../src/platform-posix.cc'
-          ]},
-        ],
-        ['OS=="win"', {
-          'sources': [
-            '../../src/platform-win32.cc',
-          ],
-          # 4355, 4800 came from common.vsprops
-          'msvs_disabled_warnings': [4355, 4800],
-          'link_settings':  {
-            'libraries': [ '-lwinmm.lib' ],
-          },
-        }],
-        ['OS=="win" and component=="shared_library"', {
-          'defines': [
-            'BUILDING_V8_SHARED'
-          ],
-        }],
-      ],
-    },
-    {
-      'target_name': 'js2c',
-      'type': 'none',
-      'toolsets': ['host'],
-      'variables': {
-        'library_files': [
-          '../../src/runtime.js',
-          '../../src/v8natives.js',
-          '../../src/array.js',
-          '../../src/string.js',
-          '../../src/uri.js',
-          '../../src/math.js',
-          '../../src/messages.js',
-          '../../src/apinatives.js',
-          '../../src/debug-debugger.js',
-          '../../src/mirror-debugger.js',
-          '../../src/liveedit-debugger.js',
-          '../../src/date.js',
-          '../../src/json.js',
-          '../../src/regexp.js',
-          '../../src/macros.py',
-        ],
-      },
-      'actions': [
+        },
         {
-          'action_name': 'js2c',
-          'inputs': [
-            '../../tools/js2c.py',
-            '<@(library_files)',
+          'target_name': 'v8_shell',
+          'type': 'executable',
+          'dependencies': [
+            'v8'
           ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
-            '<(SHARED_INTERMEDIATE_DIR)/libraries-empty.cc',
+          'sources': [
+            '../../samples/shell.cc',
           ],
-          'action': [
-            'python',
-            '../../tools/js2c.py',
-            '<@(_outputs)',
-            'CORE',
-            '<@(library_files)'
+          'conditions': [
+            ['OS=="win"', {
+              # This could be gotten by not setting chromium_code, if that's OK.
+              'defines': ['_CRT_SECURE_NO_WARNINGS'],
+            }],
           ],
         },
       ],
-    },
-    {
-      'target_name': 'mksnapshot',
-      'type': 'executable',
-      'toolsets': ['host'],
-      'dependencies': [
-        'v8_nosnapshot',
+    }, { # use_system_v8 != 0
+      'targets': [
+        {
+          'target_name': 'v8',
+          'type': 'settings',
+          'link_settings': {
+            'libraries': [
+              '-lv8',
+            ],
+          },
+        },
+        {
+          'target_name': 'v8_shell',
+          'type': 'none',
+          'dependencies': [
+            'v8'
+          ],
+        },
       ],
-      'include_dirs+': [
-        '../../src',
-      ],
-      'sources': [
-        '../../src/mksnapshot.cc',
-      ],
-      'conditions': [
-        # The ARM assembler assumes the host is 32 bits, so force building
-        # 32-bit host tools.
-        ['v8_target_arch=="arm" and host_arch=="x64" and _toolset=="host"', {
-          'cflags': ['-m32'],
-          'ldflags': ['-m32'],
-        }]
-      ]
-    },
-    {
-      'target_name': 'v8_shell',
-      'type': 'executable',
-      'dependencies': [
-        'v8'
-      ],
-      'sources': [
-        '../../samples/shell.cc',
-      ],
-      'conditions': [
-        ['OS=="win"', {
-          # This could be gotten by not setting chromium_code, if that's OK.
-          'defines': ['_CRT_SECURE_NO_WARNINGS'],
-        }],
-      ],
-    },
+    }],
   ],
 }
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index 5254c6e..80a845c 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -59,7 +59,6 @@
 		893E24AD12B14B3D0083370F /* hydrogen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248F12B14B3D0083370F /* hydrogen.cc */; };
 		893E24AE12B14B3D0083370F /* lithium-allocator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249312B14B3D0083370F /* lithium-allocator.cc */; };
 		893E24AF12B14B3D0083370F /* preparse-data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249512B14B3D0083370F /* preparse-data.cc */; };
-		893E24B012B14B3D0083370F /* preparser-api.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249712B14B3D0083370F /* preparser-api.cc */; };
 		893E24B112B14B3D0083370F /* preparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249812B14B3D0083370F /* preparser.cc */; };
 		893E24B212B14B3D0083370F /* runtime-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249A12B14B3D0083370F /* runtime-profiler.cc */; };
 		893E24B312B14B3D0083370F /* safepoint-table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249C12B14B3D0083370F /* safepoint-table.cc */; };
@@ -74,7 +73,6 @@
 		893E24BC12B14B3D0083370F /* hydrogen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E248F12B14B3D0083370F /* hydrogen.cc */; };
 		893E24BD12B14B3D0083370F /* lithium-allocator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249312B14B3D0083370F /* lithium-allocator.cc */; };
 		893E24BE12B14B3D0083370F /* preparse-data.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249512B14B3D0083370F /* preparse-data.cc */; };
-		893E24BF12B14B3D0083370F /* preparser-api.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249712B14B3D0083370F /* preparser-api.cc */; };
 		893E24C012B14B3D0083370F /* preparser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249812B14B3D0083370F /* preparser.cc */; };
 		893E24C112B14B3D0083370F /* runtime-profiler.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249A12B14B3D0083370F /* runtime-profiler.cc */; };
 		893E24C212B14B3D0083370F /* safepoint-table.cc in Sources */ = {isa = PBXBuildFile; fileRef = 893E249C12B14B3D0083370F /* safepoint-table.cc */; };
@@ -94,6 +92,8 @@
 		8944AD100F1D4D500028D560 /* regexp-stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */; };
 		8944AD110F1D4D570028D560 /* regexp-stack.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */; };
 		894599A30F5D8729008DA8FB /* debug-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8956B6CD0F5D86570033B5A2 /* debug-agent.cc */; };
+		8946827512C26EB700C914BC /* objects-printer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8946827412C26EB700C914BC /* objects-printer.cc */; };
+		8946827612C26EB700C914BC /* objects-printer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8946827412C26EB700C914BC /* objects-printer.cc */; };
 		89495E480E79FC23001F68C3 /* compilation-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89495E460E79FC23001F68C3 /* compilation-cache.cc */; };
 		89495E490E79FC23001F68C3 /* compilation-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 89495E460E79FC23001F68C3 /* compilation-cache.cc */; };
 		8956B6CF0F5D86730033B5A2 /* debug-agent.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8956B6CD0F5D86570033B5A2 /* debug-agent.cc */; };
@@ -412,7 +412,6 @@
 		893E249412B14B3D0083370F /* lithium-allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "lithium-allocator.h"; sourceTree = "<group>"; };
 		893E249512B14B3D0083370F /* preparse-data.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "preparse-data.cc"; sourceTree = "<group>"; };
 		893E249612B14B3D0083370F /* preparse-data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "preparse-data.h"; sourceTree = "<group>"; };
-		893E249712B14B3D0083370F /* preparser-api.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "preparser-api.cc"; sourceTree = "<group>"; };
 		893E249812B14B3D0083370F /* preparser.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = preparser.cc; sourceTree = "<group>"; };
 		893E249912B14B3D0083370F /* preparser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = preparser.h; sourceTree = "<group>"; };
 		893E249A12B14B3D0083370F /* runtime-profiler.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "runtime-profiler.cc"; sourceTree = "<group>"; };
@@ -447,6 +446,7 @@
 		893E24DB12B14B9F0083370F /* gc-extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "gc-extension.h"; path = "extensions/gc-extension.h"; sourceTree = "<group>"; };
 		8944AD0E0F1D4D3A0028D560 /* regexp-stack.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "regexp-stack.cc"; sourceTree = "<group>"; };
 		8944AD0F0F1D4D3A0028D560 /* regexp-stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "regexp-stack.h"; sourceTree = "<group>"; };
+		8946827412C26EB700C914BC /* objects-printer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "objects-printer.cc"; sourceTree = "<group>"; };
 		89471C7F0EB23EE400B6874B /* flag-definitions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "flag-definitions.h"; sourceTree = "<group>"; };
 		89495E460E79FC23001F68C3 /* compilation-cache.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "compilation-cache.cc"; sourceTree = "<group>"; };
 		89495E470E79FC23001F68C3 /* compilation-cache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "compilation-cache.h"; sourceTree = "<group>"; };
@@ -467,8 +467,6 @@
 		897F767A0E71B4CC007ACF34 /* v8_shell */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = v8_shell; sourceTree = BUILT_PRODUCTS_DIR; };
 		897FF0D40E719A8500D62E90 /* v8-debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-debug.h"; sourceTree = "<group>"; };
 		897FF0D50E719A8500D62E90 /* v8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8.h; sourceTree = "<group>"; };
-		897FF0E00E719B3500D62E90 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COPYING; sourceTree = "<group>"; };
-		897FF0E10E719B3500D62E90 /* dtoa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dtoa.c; sourceTree = "<group>"; };
 		897FF0F60E719B8F00D62E90 /* accessors.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = accessors.cc; sourceTree = "<group>"; };
 		897FF0F70E719B8F00D62E90 /* accessors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = accessors.h; sourceTree = "<group>"; };
 		897FF0F80E719B8F00D62E90 /* allocation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = allocation.cc; sourceTree = "<group>"; };
@@ -1003,6 +1001,7 @@
 				897FF15F0E719B8F00D62E90 /* natives.h */,
 				897FF1600E719B8F00D62E90 /* objects-debug.cc */,
 				897FF1610E719B8F00D62E90 /* objects-inl.h */,
+				8946827412C26EB700C914BC /* objects-printer.cc */,
 				C2D1E9711212F27B00187A52 /* objects-visiting.cc */,
 				C2D1E9721212F27B00187A52 /* objects-visiting.h */,
 				897FF1620E719B8F00D62E90 /* objects.cc */,
@@ -1020,7 +1019,6 @@
 				897FF16A0E719B8F00D62E90 /* platform.h */,
 				893E249512B14B3D0083370F /* preparse-data.cc */,
 				893E249612B14B3D0083370F /* preparse-data.h */,
-				893E249712B14B3D0083370F /* preparser-api.cc */,
 				893E249812B14B3D0083370F /* preparser.cc */,
 				893E249912B14B3D0083370F /* preparser.h */,
 				897FF16B0E719B8F00D62E90 /* prettyprinter.cc */,
@@ -1161,7 +1159,6 @@
 				893E24E212B14BD20083370F /* C++ */,
 				89A9C1630E71C8E300BE6CCA /* generated */,
 				897FF0D80E719ABA00D62E90 /* js */,
-				897FF0DE0E719B3400D62E90 /* third_party */,
 			);
 			path = src;
 			sourceTree = "<group>";
@@ -1194,23 +1191,6 @@
 			name = js;
 			sourceTree = "<group>";
 		};
-		897FF0DE0E719B3400D62E90 /* third_party */ = {
-			isa = PBXGroup;
-			children = (
-				897FF0DF0E719B3400D62E90 /* dtoa */,
-			);
-			path = third_party;
-			sourceTree = "<group>";
-		};
-		897FF0DF0E719B3400D62E90 /* dtoa */ = {
-			isa = PBXGroup;
-			children = (
-				897FF0E00E719B3500D62E90 /* COPYING */,
-				897FF0E10E719B3500D62E90 /* dtoa.c */,
-			);
-			path = dtoa;
-			sourceTree = "<group>";
-		};
 		897FF1B30E719BCE00D62E90 /* samples */ = {
 			isa = PBXGroup;
 			children = (
@@ -1583,7 +1563,6 @@
 				893E24BC12B14B3D0083370F /* hydrogen.cc in Sources */,
 				893E24BD12B14B3D0083370F /* lithium-allocator.cc in Sources */,
 				893E24BE12B14B3D0083370F /* preparse-data.cc in Sources */,
-				893E24BF12B14B3D0083370F /* preparser-api.cc in Sources */,
 				893E24C012B14B3D0083370F /* preparser.cc in Sources */,
 				893E24C112B14B3D0083370F /* runtime-profiler.cc in Sources */,
 				893E24C212B14B3D0083370F /* safepoint-table.cc in Sources */,
@@ -1595,6 +1574,7 @@
 				893E24D712B14B8A0083370F /* lithium-ia32.cc in Sources */,
 				893E24DC12B14B9F0083370F /* externalize-string-extension.cc in Sources */,
 				893E24DD12B14B9F0083370F /* gc-extension.cc in Sources */,
+				8946827512C26EB700C914BC /* objects-printer.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1738,7 +1718,6 @@
 				893E24AD12B14B3D0083370F /* hydrogen.cc in Sources */,
 				893E24AE12B14B3D0083370F /* lithium-allocator.cc in Sources */,
 				893E24AF12B14B3D0083370F /* preparse-data.cc in Sources */,
-				893E24B012B14B3D0083370F /* preparser-api.cc in Sources */,
 				893E24B112B14B3D0083370F /* preparser.cc in Sources */,
 				893E24B212B14B3D0083370F /* runtime-profiler.cc in Sources */,
 				893E24B312B14B3D0083370F /* safepoint-table.cc in Sources */,
@@ -1750,6 +1729,7 @@
 				893E24CE12B14B520083370F /* lithium-codegen-arm.cc in Sources */,
 				893E24DE12B14B9F0083370F /* externalize-string-extension.cc in Sources */,
 				893E24DF12B14B9F0083370F /* gc-extension.cc in Sources */,
+				8946827612C26EB700C914BC /* objects-printer.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1850,7 +1830,7 @@
 					DEBUG,
 					ENABLE_LOGGING_AND_PROFILING,
 					V8_ENABLE_CHECKS,
-                                        OBJECT_PRINT,
+					OBJECT_PRINT,
 					ENABLE_VMSTATE_TRACKING,
 				);
 				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
@@ -1915,7 +1895,7 @@
 					V8_TARGET_ARCH_IA32,
 					DEBUG,
 					V8_ENABLE_CHECKS,
-                                        OBJECT_PRINT,
+					OBJECT_PRINT,
 					ENABLE_DEBUGGER_SUPPORT,
 				);
 				HEADER_SEARCH_PATHS = ../src;
@@ -1978,7 +1958,7 @@
 					V8_TARGET_ARCH_IA32,
 					DEBUG,
 					V8_ENABLE_CHECKS,
-                                        OBJECT_PRINT,
+					OBJECT_PRINT,
 					ENABLE_DEBUGGER_SUPPORT,
 				);
 				HEADER_SEARCH_PATHS = ../src;
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
index e53b3fc..ceeebf9 100644
--- a/tools/visual_studio/v8_base.vcproj
+++ b/tools/visual_studio/v8_base.vcproj
@@ -793,6 +793,10 @@
         >
       </File>
       <File
+        RelativePath="..\..\src\objects-printer.cc"
+        >
+      </File>
+      <File
         RelativePath="..\..\src\objects-visiting.cc"
         >
       </File>
diff --git a/tools/visual_studio/v8_base_arm.vcproj b/tools/visual_studio/v8_base_arm.vcproj
index 1054958..cd4c52e 100644
--- a/tools/visual_studio/v8_base_arm.vcproj
+++ b/tools/visual_studio/v8_base_arm.vcproj
@@ -793,6 +793,10 @@
         >
       </File>
       <File
+        RelativePath="..\..\src\objects-printer.cc"
+        >
+      </File>
+      <File
         RelativePath="..\..\src\objects-visiting.cc"
         >
       </File>
diff --git a/tools/visual_studio/v8_base_x64.vcproj b/tools/visual_studio/v8_base_x64.vcproj
index 28f299e..2c7bf5e 100644
--- a/tools/visual_studio/v8_base_x64.vcproj
+++ b/tools/visual_studio/v8_base_x64.vcproj
@@ -770,6 +770,10 @@
         >
       </File>
       <File
+        RelativePath="..\..\src\objects-printer.cc"
+        >
+      </File>
+      <File
         RelativePath="..\..\src\objects-visiting.cc"
         >
       </File>