Version 2.2.3

Added stack command and mem command to ARM simulator debugger.

Fixed scons snapshot and ARM build, and Windows X64 build issues.

Performance improvements on all platforms.


git-svn-id: http://v8.googlecode.com/svn/trunk@4410 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index bf018ed..2c0da0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-04-14: Version 2.2.3
+
+        Added stack command and mem command to ARM simulator debugger.
+
+        Fixed scons snapshot and ARM build, and Windows X64 build issues.
+
+        Performance improvements on all platforms.
+
+
 2010-04-12: Version 2.2.2
 
         Introduced new profiler API.
diff --git a/SConstruct b/SConstruct
index efdd15c..1625b7a 100644
--- a/SConstruct
+++ b/SConstruct
@@ -52,9 +52,10 @@
     GCC_EXTRA_CCFLAGS = []
     GCC_DTOA_EXTRA_CCFLAGS = []
 
-ANDROID_FLAGS = ['-march=armv5te',
-                 '-mtune=xscale',
-                 '-msoft-float',
+ANDROID_FLAGS = ['-march=armv7-a',
+                 '-mtune=cortex-a8',
+                 '-mfloat-abi=softfp',
+                 '-mfpu=vfp',
                  '-fpic',
                  '-mthumb-interwork',
                  '-funwind-tables',
@@ -69,6 +70,8 @@
                  '-fomit-frame-pointer',
                  '-fno-strict-aliasing',
                  '-finline-limit=64',
+                 '-DCAN_USE_VFP_INSTRUCTIONS=1',
+                 '-DCAN_USE_ARMV7_INSTRUCTIONS=1',
                  '-MD']
 
 ANDROID_INCLUDES = [ANDROID_TOP + '/bionic/libc/arch-arm/include',
diff --git a/include/v8.h b/include/v8.h
index db739bb..d90289a 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -859,18 +859,23 @@
    * \return The number of bytes copied to the buffer
    * excluding the NULL terminator.
    */
-  int Write(uint16_t* buffer, int start = 0, int length = -1) const;  // UTF-16
-  int WriteAscii(char* buffer, int start = 0, int length = -1) const;  // ASCII
+  enum WriteHints {
+    NO_HINTS = 0,
+    HINT_MANY_WRITES_EXPECTED = 1
+  };
+
+  int Write(uint16_t* buffer,
+            int start = 0,
+            int length = -1,
+            WriteHints hints = NO_HINTS) const;  // UTF-16
+  int WriteAscii(char* buffer,
+                 int start = 0,
+                 int length = -1,
+                 WriteHints hints = NO_HINTS) const;  // ASCII
   int WriteUtf8(char* buffer,
                 int length = -1,
-                int* nchars_ref = NULL) const; // UTF-8
-
-  /**
-   * Flatten internal memory. Operations on the string tend to run faster
-   * after flattening especially if the string is a concatenation of many
-   * others.
-   */
-  void Flatten();
+                int* nchars_ref = NULL,
+                WriteHints hints = NO_HINTS) const; // UTF-8
 
   /**
    * A zero length string.
diff --git a/src/SConscript b/src/SConscript
index 3eaa6cb..5add999 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -306,7 +306,12 @@
   source_objs = context.ConfigureObject(env, source_files)
   non_snapshot_files = [dtoa_obj, source_objs]
 
-  # Create snapshot if necessary.
+  # Create snapshot if necessary.  For cross compilation you should either
+  # do without snapshots and take the performance hit or you should build a
+  # host VM with the simulator=arm and snapshot=on options and then take the
+  # resulting snapshot.cc file from obj/release and put it in the src
+  # directory.  Then rebuild the VM with the cross compiler and specify
+  # snapshot=nobuild on the scons command line.
   empty_snapshot_obj = context.ConfigureObject(env, 'snapshot-empty.cc')
   mksnapshot_env = env.Copy()
   mksnapshot_env.Replace(**context.flags['mksnapshot'])
@@ -316,7 +321,7 @@
     if context.build_snapshot:
       snapshot_cc = env.Snapshot('snapshot.cc', mksnapshot, LOGFILE=File('snapshot.log').abspath)
     else:
-      snapshot_cc = Command('snapshot.cc', [], [])
+      snapshot_cc = 'snapshot.cc'
     snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.'])
   else:
     snapshot_obj = empty_snapshot_obj
diff --git a/src/api.cc b/src/api.cc
index 2c7975b..47950eb 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -2641,12 +2641,20 @@
 }
 
 
-int String::WriteUtf8(char* buffer, int capacity, int* nchars_ref) const {
+int String::WriteUtf8(char* buffer,
+                      int capacity,
+                      int* nchars_ref,
+                      WriteHints hints) const {
   if (IsDeadCheck("v8::String::WriteUtf8()")) return 0;
   LOG_API("String::WriteUtf8");
   ENTER_V8;
   i::Handle<i::String> str = Utils::OpenHandle(this);
   StringTracker::RecordWrite(str);
+  if (hints & HINT_MANY_WRITES_EXPECTED) {
+    // Flatten the string for efficiency.  This applies whether we are
+    // using StringInputBuffer or Get(i) to access the characters.
+    str->TryFlatten();
+  }
   write_input_buffer.Reset(0, *str);
   int len = str->length();
   // Encode the first K - 3 bytes directly into the buffer since we
@@ -2688,16 +2696,21 @@
 }
 
 
-int String::WriteAscii(char* buffer, int start, int length) const {
+int String::WriteAscii(char* buffer,
+                       int start,
+                       int length,
+                       WriteHints hints) const {
   if (IsDeadCheck("v8::String::WriteAscii()")) return 0;
   LOG_API("String::WriteAscii");
   ENTER_V8;
   ASSERT(start >= 0 && length >= -1);
   i::Handle<i::String> str = Utils::OpenHandle(this);
   StringTracker::RecordWrite(str);
-  // Flatten the string for efficiency.  This applies whether we are
-  // using StringInputBuffer or Get(i) to access the characters.
-  str->TryFlatten();
+  if (hints & HINT_MANY_WRITES_EXPECTED) {
+    // Flatten the string for efficiency.  This applies whether we are
+    // using StringInputBuffer or Get(i) to access the characters.
+    str->TryFlatten();
+  }
   int end = length;
   if ( (length == -1) || (length > str->length() - start) )
     end = str->length() - start;
@@ -2715,13 +2728,21 @@
 }
 
 
-int String::Write(uint16_t* buffer, int start, int length) const {
+int String::Write(uint16_t* buffer,
+                  int start,
+                  int length,
+                  WriteHints hints) const {
   if (IsDeadCheck("v8::String::Write()")) return 0;
   LOG_API("String::Write");
   ENTER_V8;
   ASSERT(start >= 0 && length >= -1);
   i::Handle<i::String> str = Utils::OpenHandle(this);
   StringTracker::RecordWrite(str);
+  if (hints & HINT_MANY_WRITES_EXPECTED) {
+    // Flatten the string for efficiency.  This applies whether we are
+    // using StringInputBuffer or Get(i) to access the characters.
+    str->TryFlatten();
+  }
   int end = length;
   if ( (length == -1) || (length > str->length() - start) )
     end = str->length() - start;
@@ -2733,13 +2754,6 @@
 }
 
 
-void v8::String::Flatten() {
-  if (IsDeadCheck("v8::String::Flatten()")) return;
-  i::Handle<i::String> str = Utils::OpenHandle(this);
-  i::FlattenString(str);
-}
-
-
 bool v8::String::IsExternal() const {
   EnsureInitialized("v8::String::IsExternal()");
   i::Handle<i::String> str = Utils::OpenHandle(this);
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 92dcdd1..0fc7b6d 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -4021,6 +4021,100 @@
 }
 
 
+void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) {
+  // No stub. This code only occurs a few times in regexp.js.
+  const int kMaxInlineLength = 100;
+  ASSERT_EQ(3, args->length());
+  Load(args->at(0));  // Size of array, smi.
+  Load(args->at(1));  // "index" property value.
+  Load(args->at(2));  // "input" property value.
+  {
+    VirtualFrame::SpilledScope spilled_scope(frame_);
+    Label slowcase;
+    Label done;
+    __ ldr(r1, MemOperand(sp, kPointerSize * 2));
+    STATIC_ASSERT(kSmiTag == 0);
+    STATIC_ASSERT(kSmiTagSize == 1);
+    __ tst(r1, Operand(kSmiTagMask));
+    __ b(ne, &slowcase);
+    __ cmp(r1, Operand(Smi::FromInt(kMaxInlineLength)));
+    __ b(hi, &slowcase);
+    // Smi-tagging is equivalent to multiplying by 2.
+    // Allocate RegExpResult followed by FixedArray with size in ebx.
+    // JSArray:   [Map][empty properties][Elements][Length-smi][index][input]
+    // Elements:  [Map][Length][..elements..]
+    // Size of JSArray with two in-object properties and the header of a
+    // FixedArray.
+    int objects_size =
+        (JSRegExpResult::kSize + FixedArray::kHeaderSize) / kPointerSize;
+    __ mov(r5, Operand(r1, LSR, kSmiTagSize + kSmiShiftSize));
+    __ add(r2, r5, Operand(objects_size));
+    __ AllocateInNewSpace(r2,  // In: Size, in words.
+                          r0,  // Out: Start of allocation (tagged).
+                          r3,  // Scratch register.
+                          r4,  // Scratch register.
+                          &slowcase,
+                          TAG_OBJECT);
+    // r0: Start of allocated area, object-tagged.
+    // r1: Number of elements in array, as smi.
+    // r5: Number of elements, untagged.
+
+    // Set JSArray map to global.regexp_result_map().
+    // Set empty properties FixedArray.
+    // Set elements to point to FixedArray allocated right after the JSArray.
+    // Interleave operations for better latency.
+    __ ldr(r2, ContextOperand(cp, Context::GLOBAL_INDEX));
+    __ add(r3, r0, Operand(JSRegExpResult::kSize));
+    __ mov(r4, Operand(Factory::empty_fixed_array()));
+    __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset));
+    __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset));
+    __ ldr(r2, ContextOperand(r2, Context::REGEXP_RESULT_MAP_INDEX));
+    __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
+    __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
+
+    // Set input, index and length fields from arguments.
+    __ ldm(ia_w, sp, static_cast<RegList>(r2.bit() | r4.bit()));
+    __ str(r1, FieldMemOperand(r0, JSArray::kLengthOffset));
+    __ add(sp, sp, Operand(kPointerSize));
+    __ str(r4, FieldMemOperand(r0, JSRegExpResult::kIndexOffset));
+    __ str(r2, FieldMemOperand(r0, JSRegExpResult::kInputOffset));
+
+    // Fill out the elements FixedArray.
+    // r0: JSArray, tagged.
+    // r3: FixedArray, tagged.
+    // r5: Number of elements in array, untagged.
+
+    // Set map.
+    __ mov(r2, Operand(Factory::fixed_array_map()));
+    __ str(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
+    // Set FixedArray length.
+    __ str(r5, FieldMemOperand(r3, FixedArray::kLengthOffset));
+    // Fill contents of fixed-array with the-hole.
+    __ mov(r2, Operand(Factory::the_hole_value()));
+    __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+    // Fill fixed array elements with hole.
+    // r0: JSArray, tagged.
+    // r2: the hole.
+    // r3: Start of elements in FixedArray.
+    // r5: Number of elements to fill.
+    Label loop;
+    __ tst(r5, Operand(r5));
+    __ bind(&loop);
+    __ b(le, &done);  // Jump if r1 is negative or zero.
+    __ sub(r5, r5, Operand(1), SetCC);
+    __ str(r2, MemOperand(r3, r5, LSL, kPointerSizeLog2));
+    __ jmp(&loop);
+
+    __ bind(&slowcase);
+    __ CallRuntime(Runtime::kRegExpConstructResult, 3);
+
+    __ bind(&done);
+  }
+  frame_->Forget(3);
+  frame_->EmitPush(r0);
+}
+
+
 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
   ASSERT_EQ(args->length(), 1);
 
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 62e9fe4..74aed1d 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -407,6 +407,8 @@
   // Support for direct calls from JavaScript to native RegExp code.
   void GenerateRegExpExec(ZoneList<Expression*>* args);
 
+  void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
+
   // Fast support for number to string.
   void GenerateNumberToString(ZoneList<Expression*>* args);
 
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index 8a6588b..b18fd79 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -150,7 +150,11 @@
     *value = GetRegisterValue(regnum);
     return true;
   } else {
-    return SScanF(desc, "%i", value) == 1;
+    if (strncmp(desc, "0x", 2) == 0) {
+      return SScanF(desc + 2, "%x", reinterpret_cast<uint32_t*>(value)) == 1;
+    } else {
+      return SScanF(desc, "%u", reinterpret_cast<uint32_t*>(value)) == 1;
+    }
   }
   return false;
 }
@@ -231,6 +235,7 @@
   char cmd[COMMAND_SIZE + 1];
   char arg1[ARG_SIZE + 1];
   char arg2[ARG_SIZE + 1];
+  char* argv[3] = { cmd, arg1, arg2 };
 
   // make sure to have a proper terminating character if reaching the limit
   cmd[COMMAND_SIZE] = 0;
@@ -258,7 +263,7 @@
     } else {
       // Use sscanf to parse the individual parts of the command line. At the
       // moment no command expects more than two parameters.
-      int args = SScanF(line,
+      int argc = SScanF(line,
                         "%" XSTR(COMMAND_SIZE) "s "
                         "%" XSTR(ARG_SIZE) "s "
                         "%" XSTR(ARG_SIZE) "s",
@@ -271,7 +276,7 @@
         // Leave the debugger shell.
         done = true;
       } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
-        if (args == 2) {
+        if (argc == 2) {
           int32_t value;
           float svalue;
           double dvalue;
@@ -296,7 +301,7 @@
         }
       } else if ((strcmp(cmd, "po") == 0)
                  || (strcmp(cmd, "printobject") == 0)) {
-        if (args == 2) {
+        if (argc == 2) {
           int32_t value;
           if (GetValue(arg1, &value)) {
             Object* obj = reinterpret_cast<Object*>(value);
@@ -313,6 +318,37 @@
         } else {
           PrintF("printobject <value>\n");
         }
+      } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
+        int32_t* cur = NULL;
+        int32_t* end = NULL;
+        int next_arg = 1;
+
+        if (strcmp(cmd, "stack") == 0) {
+          cur = reinterpret_cast<int32_t*>(sim_->get_register(Simulator::sp));
+        } else {  // "mem"
+          int32_t value;
+          if (!GetValue(arg1, &value)) {
+            PrintF("%s unrecognized\n", arg1);
+            continue;
+          }
+          cur = reinterpret_cast<int32_t*>(value);
+          next_arg++;
+        }
+
+        int32_t words;
+        if (argc == next_arg) {
+          words = 10;
+        } else if (argc == next_arg + 1) {
+          if (!GetValue(argv[next_arg], &words)) {
+            words = 10;
+          }
+        }
+        end = cur + words;
+
+        while (cur < end) {
+          PrintF("  0x%08x:  0x%08x %10d\n", cur, *cur, *cur);
+          cur++;
+        }
       } else if (strcmp(cmd, "disasm") == 0) {
         disasm::NameConverter converter;
         disasm::Disassembler dasm(converter);
@@ -322,10 +358,10 @@
         byte* cur = NULL;
         byte* end = NULL;
 
-        if (args == 1) {
+        if (argc == 1) {
           cur = reinterpret_cast<byte*>(sim_->get_pc());
           end = cur + (10 * Instr::kInstrSize);
-        } else if (args == 2) {
+        } else if (argc == 2) {
           int32_t value;
           if (GetValue(arg1, &value)) {
             cur = reinterpret_cast<byte*>(value);
@@ -351,7 +387,7 @@
         v8::internal::OS::DebugBreak();
         PrintF("regaining control from gdb\n");
       } else if (strcmp(cmd, "break") == 0) {
-        if (args == 2) {
+        if (argc == 2) {
           int32_t value;
           if (GetValue(arg1, &value)) {
             if (!SetBreakpoint(reinterpret_cast<Instr*>(value))) {
@@ -401,6 +437,10 @@
         PrintF("  print an object from a register (alias 'po')\n");
         PrintF("flags\n");
         PrintF("  print flags\n");
+        PrintF("stack [<words>]\n");
+        PrintF("  dump stack content, default dump 10 words)\n");
+        PrintF("mem <address> [<words>]\n");
+        PrintF("  dump memory content, default dump 10 words)\n");
         PrintF("disasm [<instructions>]\n");
         PrintF("disasm [[<address>] <instructions>]\n");
         PrintF("  disassemble code, default is 10 instructions from pc\n");
@@ -414,7 +454,7 @@
         PrintF("  ignore the stop instruction at the current location");
         PrintF("  from now on\n");
         PrintF("trace (alias 't')\n");
-        PrintF("  toogle the tracing of all executed statements");
+        PrintF("  toogle the tracing of all executed statements\n");
       } else {
         PrintF("Unknown command: %s\n", cmd);
       }
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index bbffef2..62b0373 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -1389,6 +1389,36 @@
 }
 
 
+Object* LoadStubCompiler::CompileLoadNonexistent(JSObject* object) {
+  // ----------- S t a t e -------------
+  //  -- r2    : name
+  //  -- lr    : return address
+  //  -- [sp]  : receiver
+  // -----------------------------------
+  Label miss;
+
+  // Load receiver.
+  __ ldr(r0, MemOperand(sp, 0));
+
+  // Check the maps of the full prototype chain.
+  JSObject* last = object;
+  while (last->GetPrototype() != Heap::null_value()) {
+    last = JSObject::cast(last->GetPrototype());
+  }
+  CheckPrototypes(object, r0, last, r3, r1, Heap::empty_string(), &miss);
+
+  // Return undefined if maps of the full prototype chain is still the same.
+  __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
+  __ Ret();
+
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(NONEXISTENT, Heap::empty_string());
+}
+
+
 Object* LoadStubCompiler::CompileLoadField(JSObject* object,
                                            JSObject* holder,
                                            int index,
diff --git a/src/array.js b/src/array.js
index c1ba3c3..54d7e57 100644
--- a/src/array.js
+++ b/src/array.js
@@ -649,29 +649,16 @@
   function InsertionSortWithFunc(a, from, to) {
     for (var i = from + 1; i < to; i++) {
       var element = a[i];
-      // place element in a[from..i[
-      // binary search
-      var min = from;
-      var max = i;
-      // The search interval is a[min..max[
-      while (min < max) {
-        var mid = min + ((max - min) >> 1);
-        var order = %_CallFunction(global_receiver, a[mid], element, comparefn);
-        if (order == 0) {
-          min = max = mid;
+      for (var j = i - 1; j >= from; j--) {
+        var tmp = a[j];
+        var order = %_CallFunction(global_receiver, tmp, element, comparefn);
+        if (order > 0) {
+          a[j + 1] = tmp;
+        } else {
           break;
         }
-        if (order < 0) {
-          min = mid + 1;
-        } else {
-          max = mid;
-        }
       }
-      // place element at position min==max.
-      for (var j = i; j > min; j--) {
-        a[j] = a[j - 1];
-      }
-      a[min] = element;
+      a[j + 1] = element;
     }
   }
 
@@ -712,8 +699,6 @@
   }
 
   function Compare(x,y) {
-    // Assume the comparefn, if any, is a consistent comparison function.
-    // If it isn't, we are allowed arbitrary behavior by ECMA 15.4.4.11.
     if (x === y) return 0;
     if (%_IsSmi(x) && %_IsSmi(y)) {
       return %SmiLexicographicCompare(x, y);
@@ -727,32 +712,17 @@
   function InsertionSort(a, from, to) {
     for (var i = from + 1; i < to; i++) {
       var element = a[i];
-      // Pre-convert the element to a string for comparison if we know
-      // it will happen on each compare anyway.
       var key = %_IsSmi(element) ? element : ToString(element);
-      // place element in a[from..i[
-      // binary search
-      var min = from;
-      var max = i;
-      // The search interval is a[min..max[
-      while (min < max) {
-        var mid = min + ((max - min) >> 1);
-        var order = Compare(a[mid], key);
-        if (order == 0) {
-          min = max = mid;
+      for (var j = i - 1; j >= from; j--) {
+        var tmp = a[j];
+        var order = Compare(tmp, key);
+        if (order > 0) {
+          a[j + 1] = tmp;
+        } else {
           break;
         }
-        if (order < 0) {
-          min = mid + 1;
-        } else {
-          max = mid;
-        }
       }
-      // place element at position min==max.
-      for (var j = i; j > min; j--) {
-        a[j] = a[j - 1];
-      }
-      a[min] = element;
+      a[j + 1] = element;
     }
   }
 
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 82a63f0..d88c8e7 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1237,6 +1237,62 @@
     apply->shared()->set_length(2);
   }
 
+  // Create a constructor for RegExp results (a variant of Array that
+  // predefines the two properties index and match).
+  {
+    // RegExpResult initial map.
+
+    // Find global.Array.prototype to inherit from.
+    Handle<JSFunction> array_constructor(global_context()->array_function());
+    Handle<JSObject> array_prototype(
+        JSObject::cast(array_constructor->instance_prototype()));
+
+    // Add initial map.
+    Handle<Map> initial_map =
+        Factory::NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
+    initial_map->set_constructor(*array_constructor);
+
+    // Set prototype on map.
+    initial_map->set_non_instance_prototype(false);
+    initial_map->set_prototype(*array_prototype);
+
+    // Update map with length accessor from Array and add "index" and "input".
+    Handle<Map> array_map(global_context()->js_array_map());
+    Handle<DescriptorArray> array_descriptors(
+        array_map->instance_descriptors());
+    ASSERT_EQ(1, array_descriptors->number_of_descriptors());
+
+    Handle<DescriptorArray> reresult_descriptors =
+        Factory::NewDescriptorArray(3);
+
+    reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
+
+    int enum_index = 0;
+    {
+      FieldDescriptor index_field(Heap::index_symbol(),
+                                  JSRegExpResult::kIndexIndex,
+                                  NONE,
+                                  enum_index++);
+      reresult_descriptors->Set(1, &index_field);
+    }
+
+    {
+      FieldDescriptor input_field(Heap::input_symbol(),
+                                  JSRegExpResult::kInputIndex,
+                                  NONE,
+                                  enum_index++);
+      reresult_descriptors->Set(2, &input_field);
+    }
+    reresult_descriptors->Sort();
+
+    initial_map->set_inobject_properties(2);
+    initial_map->set_pre_allocated_property_fields(2);
+    initial_map->set_unused_property_fields(0);
+    initial_map->set_instance_descriptors(*reresult_descriptors);
+
+    global_context()->set_regexp_result_map(*initial_map);
+  }
+
 #ifdef DEBUG
   builtins->Verify();
 #endif
diff --git a/src/circular-queue-inl.h b/src/circular-queue-inl.h
index 962b069..90ab0f5 100644
--- a/src/circular-queue-inl.h
+++ b/src/circular-queue-inl.h
@@ -38,7 +38,8 @@
 CircularQueue<Record>::CircularQueue(int desired_buffer_size_in_bytes)
     : buffer_(NewArray<Record>(desired_buffer_size_in_bytes / sizeof(Record))),
       buffer_end_(buffer_ + desired_buffer_size_in_bytes / sizeof(Record)),
-      enqueue_semaphore_(OS::CreateSemaphore((buffer_end_ - buffer_) - 1)),
+      enqueue_semaphore_(
+          OS::CreateSemaphore(static_cast<int>(buffer_end_ - buffer_) - 1)),
       enqueue_pos_(buffer_),
       dequeue_pos_(buffer_) {
   // To be able to distinguish between a full and an empty queue
diff --git a/src/circular-queue.cc b/src/circular-queue.cc
index a7c2532..af650de 100644
--- a/src/circular-queue.cc
+++ b/src/circular-queue.cc
@@ -58,8 +58,10 @@
   // updates of positions by different processor cores.
   const int positions_size =
       RoundUp(1, kProcessorCacheLineSize) +
-      RoundUp(sizeof(ProducerPosition), kProcessorCacheLineSize) +
-      RoundUp(sizeof(ConsumerPosition), kProcessorCacheLineSize);
+      RoundUp(static_cast<int>(sizeof(ProducerPosition)),
+              kProcessorCacheLineSize) +
+      RoundUp(static_cast<int>(sizeof(ConsumerPosition)),
+              kProcessorCacheLineSize);
   positions_ = NewArray<byte>(positions_size);
 
   producer_pos_ = reinterpret_cast<ProducerPosition*>(
diff --git a/src/codegen.h b/src/codegen.h
index d4518e6..d56d4ee 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -123,6 +123,7 @@
   F(SubString, 3, 1)                                                         \
   F(StringCompare, 2, 1)                                                     \
   F(RegExpExec, 4, 1)                                                        \
+  F(RegExpConstructResult, 3, 1)                                             \
   F(NumberToString, 1, 1)                                                    \
   F(MathPow, 2, 1)                                                           \
   F(MathSin, 1, 1)                                                           \
diff --git a/src/contexts.h b/src/contexts.h
index 44c90b6..ce112f3 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -76,6 +76,7 @@
   V(FUNCTION_MAP_INDEX, Map, function_map) \
   V(FUNCTION_INSTANCE_MAP_INDEX, Map, function_instance_map) \
   V(JS_ARRAY_MAP_INDEX, Map, js_array_map)\
+  V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map)\
   V(ARGUMENTS_BOILERPLATE_INDEX, JSObject, arguments_boilerplate) \
   V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
   V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
@@ -175,6 +176,7 @@
     SECURITY_TOKEN_INDEX,
     ARGUMENTS_BOILERPLATE_INDEX,
     JS_ARRAY_MAP_INDEX,
+    REGEXP_RESULT_MAP_INDEX,
     FUNCTION_MAP_INDEX,
     FUNCTION_INSTANCE_MAP_INDEX,
     INITIAL_OBJECT_PROTOTYPE_INDEX,
diff --git a/src/d8-posix.cc b/src/d8-posix.cc
index 2535ce0..335bd2b 100644
--- a/src/d8-posix.cc
+++ b/src/d8-posix.cc
@@ -663,10 +663,28 @@
 }
 
 
+Handle<Value> Shell::UnsetEnvironment(const Arguments& args) {
+  if (args.Length() != 1) {
+    const char* message = "unsetenv() takes one argument";
+    return ThrowException(String::New(message));
+  }
+  String::Utf8Value var(args[0]);
+  if (*var == NULL) {
+    const char* message =
+        "os.setenv(): String conversion of variable name failed.";
+    return ThrowException(String::New(message));
+  }
+  unsetenv(*var);
+  return v8::Undefined();
+}
+
+
 void Shell::AddOSMethods(Handle<ObjectTemplate> os_templ) {
   os_templ->Set(String::New("system"), FunctionTemplate::New(System));
   os_templ->Set(String::New("chdir"), FunctionTemplate::New(ChangeDirectory));
   os_templ->Set(String::New("setenv"), FunctionTemplate::New(SetEnvironment));
+  os_templ->Set(String::New("unsetenv"),
+                FunctionTemplate::New(UnsetEnvironment));
   os_templ->Set(String::New("umask"), FunctionTemplate::New(SetUMask));
   os_templ->Set(String::New("mkdirp"), FunctionTemplate::New(MakeDirectory));
   os_templ->Set(String::New("rmdir"), FunctionTemplate::New(RemoveDirectory));
diff --git a/src/d8.h b/src/d8.h
index c93ea46..9df291b 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -175,6 +175,7 @@
   static Handle<Value> System(const Arguments& args);
   static Handle<Value> ChangeDirectory(const Arguments& args);
   static Handle<Value> SetEnvironment(const Arguments& args);
+  static Handle<Value> UnsetEnvironment(const Arguments& args);
   static Handle<Value> SetUMask(const Arguments& args);
   static Handle<Value> MakeDirectory(const Arguments& args);
   static Handle<Value> RemoveDirectory(const Arguments& args);
diff --git a/src/execution.cc b/src/execution.cc
index 2068413..e8b0d94 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -221,8 +221,8 @@
 
 void StackGuard::EnableInterrupts() {
   ExecutionAccess access;
-  if (IsSet(access)) {
-    set_limits(kInterruptLimit, access);
+  if (has_pending_interrupts(access)) {
+    set_interrupt_limits(access);
   }
 }
 
@@ -249,11 +249,6 @@
 }
 
 
-bool StackGuard::IsSet(const ExecutionAccess& lock) {
-  return thread_local_.interrupt_flags_ != 0;
-}
-
-
 bool StackGuard::IsInterrupted() {
   ExecutionAccess access;
   return thread_local_.interrupt_flags_ & INTERRUPT;
@@ -263,7 +258,7 @@
 void StackGuard::Interrupt() {
   ExecutionAccess access;
   thread_local_.interrupt_flags_ |= INTERRUPT;
-  set_limits(kInterruptLimit, access);
+  set_interrupt_limits(access);
 }
 
 
@@ -276,7 +271,7 @@
 void StackGuard::Preempt() {
   ExecutionAccess access;
   thread_local_.interrupt_flags_ |= PREEMPT;
-  set_limits(kInterruptLimit, access);
+  set_interrupt_limits(access);
 }
 
 
@@ -289,7 +284,7 @@
 void StackGuard::TerminateExecution() {
   ExecutionAccess access;
   thread_local_.interrupt_flags_ |= TERMINATE;
-  set_limits(kInterruptLimit, access);
+  set_interrupt_limits(access);
 }
 
 
@@ -303,7 +298,7 @@
 void StackGuard::DebugBreak() {
   ExecutionAccess access;
   thread_local_.interrupt_flags_ |= DEBUGBREAK;
-  set_limits(kInterruptLimit, access);
+  set_interrupt_limits(access);
 }
 
 
@@ -317,7 +312,7 @@
   if (FLAG_debugger_auto_break) {
     ExecutionAccess access;
     thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
-    set_limits(kInterruptLimit, access);
+    set_interrupt_limits(access);
   }
 }
 #endif
@@ -325,7 +320,7 @@
 void StackGuard::Continue(InterruptFlag after_what) {
   ExecutionAccess access;
   thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
-  if (thread_local_.interrupt_flags_ == 0) {
+  if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
     reset_limits(access);
   }
 }
diff --git a/src/execution.h b/src/execution.h
index 10683d6..e683e12 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -199,12 +199,24 @@
 
  private:
   // You should hold the ExecutionAccess lock when calling this method.
-  static bool IsSet(const ExecutionAccess& lock);
+  static bool has_pending_interrupts(const ExecutionAccess& lock) {
+    // Sanity check: We shouldn't be asking about pending interrupts
+    // unless we're not postponing them anymore.
+    ASSERT(!should_postpone_interrupts(lock));
+    return thread_local_.interrupt_flags_ != 0;
+  }
 
   // You should hold the ExecutionAccess lock when calling this method.
-  static void set_limits(uintptr_t value, const ExecutionAccess& lock) {
-    thread_local_.jslimit_ = value;
-    thread_local_.climit_ = value;
+  static bool should_postpone_interrupts(const ExecutionAccess& lock) {
+    return thread_local_.postpone_interrupts_nesting_ > 0;
+  }
+
+  // You should hold the ExecutionAccess lock when calling this method.
+  static void set_interrupt_limits(const ExecutionAccess& lock) {
+    // Ignore attempts to interrupt when interrupts are postponed.
+    if (should_postpone_interrupts(lock)) return;
+    thread_local_.jslimit_ = kInterruptLimit;
+    thread_local_.climit_ = kInterruptLimit;
     Heap::SetStackLimits();
   }
 
diff --git a/src/globals.h b/src/globals.h
index 3d48e2d..410cb3f 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -428,7 +428,11 @@
   CONSTANT_TRANSITION = 6,  // only in fast mode
   NULL_DESCRIPTOR     = 7,  // only in fast mode
   // All properties before MAP_TRANSITION are real.
-  FIRST_PHANTOM_PROPERTY_TYPE = MAP_TRANSITION
+  FIRST_PHANTOM_PROPERTY_TYPE = MAP_TRANSITION,
+  // There are no IC stubs for NULL_DESCRIPTORS. Therefore,
+  // NULL_DESCRIPTOR can be used as the type flag for IC stubs for
+  // nonexistent properties.
+  NONEXISTENT = NULL_DESCRIPTOR
 };
 
 
diff --git a/src/heap-inl.h b/src/heap-inl.h
index ba4850e..bf9c535 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -240,6 +240,27 @@
 }
 
 
+void Heap::MoveBlock(Object** dst, Object** src, size_t byte_size) {
+  ASSERT(IsAligned<size_t>(byte_size, kPointerSize));
+
+  int size_in_words = byte_size / kPointerSize;
+
+  if ((dst < src) || (dst >= (src + size_in_words))) {
+    ASSERT((dst >= (src + size_in_words)) ||
+           ((OffsetFrom(reinterpret_cast<Address>(src)) -
+             OffsetFrom(reinterpret_cast<Address>(dst))) >= kPointerSize));
+
+    Object** end = src + size_in_words;
+
+    while (src != end) {
+      *dst++ = *src++;
+    }
+  } else {
+    memmove(dst, src, byte_size);
+  }
+}
+
+
 void Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
   ASSERT(InFromSpace(object));
 
diff --git a/src/heap.cc b/src/heap.cc
index 4693e40..7a5188f 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -562,23 +562,18 @@
 
   EnsureFromSpaceIsCommitted();
 
-  // Perform mark-sweep with optional compaction.
   if (collector == MARK_COMPACTOR) {
+    // Perform mark-sweep with optional compaction.
     MarkCompact(tracer);
-  }
 
-  // Always perform a scavenge to make room in new space.
-  Scavenge();
-
-  // Update the old space promotion limits after the scavenge due to
-  // promotions during scavenge.
-  if (collector == MARK_COMPACTOR) {
     int old_gen_size = PromotedSpaceSize();
     old_gen_promotion_limit_ =
         old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3);
     old_gen_allocation_limit_ =
         old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2);
     old_gen_exhausted_ = false;
+  } else {
+    Scavenge();
   }
 
   Counters::objs_since_last_young.Set(0);
@@ -764,6 +759,17 @@
 #endif
 
 
+void Heap::CheckNewSpaceExpansionCriteria() {
+  if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
+      survived_since_last_expansion_ > new_space_.Capacity()) {
+    // Grow the size of new space if there is room to grow and enough
+    // data has survived scavenge since the last expansion.
+    new_space_.Grow();
+    survived_since_last_expansion_ = 0;
+  }
+}
+
+
 void Heap::Scavenge() {
 #ifdef DEBUG
   if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers();
@@ -780,13 +786,7 @@
   // Used for updating survived_since_last_expansion_ at function end.
   int survived_watermark = PromotedSpaceSize();
 
-  if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
-      survived_since_last_expansion_ > new_space_.Capacity()) {
-    // Grow the size of new space if there is room to grow and enough
-    // data has survived scavenge since the last expansion.
-    new_space_.Grow();
-    survived_since_last_expansion_ = 0;
-  }
+  CheckNewSpaceExpansionCriteria();
 
   // Flip the semispaces.  After flipping, to space is empty, from space has
   // live objects.
@@ -837,15 +837,17 @@
 
   new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
 
-  ScavengeExternalStringTable();
+  UpdateNewSpaceReferencesInExternalStringTable(
+      &UpdateNewSpaceReferenceInExternalStringTableEntry);
+
   ASSERT(new_space_front == new_space_.top());
 
   // Set age mark.
   new_space_.set_age_mark(new_space_.top());
 
   // Update how much has survived scavenge.
-  survived_since_last_expansion_ +=
-      (PromotedSpaceSize() - survived_watermark) + new_space_.Size();
+  IncrementYoungSurvivorsCounter(
+      (PromotedSpaceSize() - survived_watermark) + new_space_.Size());
 
   LOG(ResourceEvent("scavenge", "end"));
 
@@ -853,7 +855,22 @@
 }
 
 
-void Heap::ScavengeExternalStringTable() {
+String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Object** p) {
+  MapWord first_word = HeapObject::cast(*p)->map_word();
+
+  if (!first_word.IsForwardingAddress()) {
+    // Unreachable external string can be finalized.
+    FinalizeExternalString(String::cast(*p));
+    return NULL;
+  }
+
+  // String is still reachable.
+  return String::cast(first_word.ToForwardingAddress());
+}
+
+
+void Heap::UpdateNewSpaceReferencesInExternalStringTable(
+    ExternalStringTableUpdaterCallback updater_func) {
   ExternalStringTable::Verify();
 
   if (ExternalStringTable::new_space_strings_.is_empty()) return;
@@ -864,16 +881,10 @@
 
   for (Object** p = start; p < end; ++p) {
     ASSERT(Heap::InFromSpace(*p));
-    MapWord first_word = HeapObject::cast(*p)->map_word();
+    String* target = updater_func(p);
 
-    if (!first_word.IsForwardingAddress()) {
-      // Unreachable external string can be finalized.
-      FinalizeExternalString(String::cast(*p));
-      continue;
-    }
+    if (target == NULL) continue;
 
-    // String is still reachable.
-    String* target = String::cast(first_word.ToForwardingAddress());
     ASSERT(target->IsExternalString());
 
     if (Heap::InNewSpace(target)) {
@@ -1487,10 +1498,9 @@
 }
 
 
-Object* Heap::CreateOddball(Map* map,
-                            const char* to_string,
+Object* Heap::CreateOddball(const char* to_string,
                             Object* to_number) {
-  Object* result = Allocate(map, OLD_DATA_SPACE);
+  Object* result = Allocate(oddball_map(), OLD_DATA_SPACE);
   if (result->IsFailure()) return result;
   return Oddball::cast(result)->Initialize(to_string, to_number);
 }
@@ -1594,34 +1604,27 @@
   Oddball::cast(undefined_value())->set_to_string(String::cast(symbol));
   Oddball::cast(undefined_value())->set_to_number(nan_value());
 
-  // Assign the print strings for oddballs after creating symboltable.
-  symbol = LookupAsciiSymbol("null");
-  if (symbol->IsFailure()) return false;
-  Oddball::cast(null_value())->set_to_string(String::cast(symbol));
-  Oddball::cast(null_value())->set_to_number(Smi::FromInt(0));
-
   // Allocate the null_value
   obj = Oddball::cast(null_value())->Initialize("null", Smi::FromInt(0));
   if (obj->IsFailure()) return false;
 
-  obj = CreateOddball(oddball_map(), "true", Smi::FromInt(1));
+  obj = CreateOddball("true", Smi::FromInt(1));
   if (obj->IsFailure()) return false;
   set_true_value(obj);
 
-  obj = CreateOddball(oddball_map(), "false", Smi::FromInt(0));
+  obj = CreateOddball("false", Smi::FromInt(0));
   if (obj->IsFailure()) return false;
   set_false_value(obj);
 
-  obj = CreateOddball(oddball_map(), "hole", Smi::FromInt(-1));
+  obj = CreateOddball("hole", Smi::FromInt(-1));
   if (obj->IsFailure()) return false;
   set_the_hole_value(obj);
 
-  obj = CreateOddball(
-      oddball_map(), "no_interceptor_result_sentinel", Smi::FromInt(-2));
+  obj = CreateOddball("no_interceptor_result_sentinel", Smi::FromInt(-2));
   if (obj->IsFailure()) return false;
   set_no_interceptor_result_sentinel(obj);
 
-  obj = CreateOddball(oddball_map(), "termination_exception", Smi::FromInt(-3));
+  obj = CreateOddball("termination_exception", Smi::FromInt(-3));
   if (obj->IsFailure()) return false;
   set_termination_exception(obj);
 
@@ -2315,7 +2318,8 @@
 
   Address old_addr = code->address();
 
-  int relocation_offset = code->relocation_start() - old_addr;
+  size_t relocation_offset =
+      static_cast<size_t>(code->relocation_start() - old_addr);
 
   Object* result;
   if (new_obj_size > MaxObjectSizeInPagedSpace()) {
diff --git a/src/heap.h b/src/heap.h
index 3b1d3ce..fbd77ff 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -153,6 +153,8 @@
   V(global_symbol, "global")                                             \
   V(ignore_case_symbol, "ignoreCase")                                    \
   V(multiline_symbol, "multiline")                                       \
+  V(input_symbol, "input")                                               \
+  V(index_symbol, "index")                                               \
   V(last_index_symbol, "lastIndex")                                      \
   V(object_symbol, "object")                                             \
   V(prototype_symbol, "prototype")                                       \
@@ -200,6 +202,9 @@
 class HeapStats;
 
 
+typedef String* (*ExternalStringTableUpdaterCallback)(Object** pointer);
+
+
 // The all static Heap captures the interface to the global object heap.
 // All JavaScript contexts by this process share the same object heap.
 
@@ -944,6 +949,30 @@
 
   static void RecordStats(HeapStats* stats);
 
+  // Copy block of memory from src to dst. Size of block should be aligned
+  // by pointer size.
+  static inline void CopyBlock(Object** dst, Object** src, int byte_size);
+
+  // Optimized version of memmove for blocks with pointer size aligned sizes and
+  // pointer size aligned addresses.
+  static inline void MoveBlock(Object** dst, Object** src, size_t byte_size);
+
+  // Check new space expansion criteria and expand semispaces if it was hit.
+  static void CheckNewSpaceExpansionCriteria();
+
+  static inline void IncrementYoungSurvivorsCounter(int survived) {
+    survived_since_last_expansion_ += survived;
+  }
+
+  static void UpdateNewSpaceReferencesInExternalStringTable(
+      ExternalStringTableUpdaterCallback updater_func);
+
+  // Helper function that governs the promotion policy from new space to
+  // old.  If the object's old address lies below the new space's age
+  // mark or if we've already filled the bottom 1/16th of the to space,
+  // we try to promote this object.
+  static inline bool ShouldBePromoted(Address old_address, int object_size);
+
   static int MaxObjectSizeInNewSpace() { return kMaxObjectSizeInNewSpace; }
 
  private:
@@ -1131,16 +1160,17 @@
 
   static void CreateFixedStubs();
 
-  static Object* CreateOddball(Map* map,
-                               const char* to_string,
-                               Object* to_number);
+  static Object* CreateOddball(const char* to_string, Object* to_number);
 
   // Allocate empty fixed array.
   static Object* AllocateEmptyFixedArray();
 
   // Performs a minor collection in new generation.
   static void Scavenge();
-  static void ScavengeExternalStringTable();
+
+  static String* UpdateNewSpaceReferenceInExternalStringTableEntry(
+      Object** pointer);
+
   static Address DoScavenge(ObjectVisitor* scavenge_visitor,
                             Address new_space_front);
 
@@ -1158,11 +1188,6 @@
                                           HeapObject* target,
                                           int size);
 
-  // Helper function that governs the promotion policy from new space to
-  // old.  If the object's old address lies below the new space's age
-  // mark or if we've already filled the bottom 1/16th of the to space,
-  // we try to promote this object.
-  static inline bool ShouldBePromoted(Address old_address, int object_size);
 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
   // Record the copy of an object in the NewSpace's statistics.
   static void RecordCopiedObject(HeapObject* obj);
@@ -1181,9 +1206,6 @@
   // Slow part of scavenge object.
   static void ScavengeObjectSlow(HeapObject** p, HeapObject* object);
 
-  // Copy memory from src to dst.
-  static inline void CopyBlock(Object** dst, Object** src, int byte_size);
-
   // Initializes a function with a shared part and prototype.
   // Returns the function.
   // Note: this code was factored out of AllocateFunction such that
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index bbbcd3a..bac4ee5 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -2432,7 +2432,8 @@
     left_side_constant_null = left_side.handle()->IsNull();
     left_side_constant_1_char_string =
         (left_side.handle()->IsString() &&
-         (String::cast(*left_side.handle())->length() == 1));
+         String::cast(*left_side.handle())->length() == 1 &&
+         String::cast(*left_side.handle())->IsAsciiRepresentation());
   }
   bool right_side_constant_smi = false;
   bool right_side_constant_null = false;
@@ -2442,7 +2443,8 @@
     right_side_constant_null = right_side.handle()->IsNull();
     right_side_constant_1_char_string =
         (right_side.handle()->IsString() &&
-         (String::cast(*right_side.handle())->length() == 1));
+         String::cast(*right_side.handle())->length() == 1 &&
+         String::cast(*right_side.handle())->IsAsciiRepresentation());
   }
 
   if (left_side_constant_smi || right_side_constant_smi) {
@@ -2631,6 +2633,7 @@
       JumpTarget is_not_string, is_string;
       Register left_reg = left_side.reg();
       Handle<Object> right_val = right_side.handle();
+      ASSERT(StringShape(String::cast(*right_val)).IsSymbol());
       __ test(left_side.reg(), Immediate(kSmiTagMask));
       is_not_string.Branch(zero, &left_side);
       Result temp = allocator_->Allocate();
@@ -2655,7 +2658,7 @@
         dest->false_target()->Branch(not_equal);
         __ bind(&not_a_symbol);
       }
-      // If the receiver is not a string of the type we handle call the stub.
+      // Call the compare stub if the left side is not a flat ascii string.
       __ and_(temp.reg(),
           kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask);
       __ cmp(temp.reg(), kStringTag | kSeqStringTag | kAsciiStringTag);
@@ -2673,7 +2676,7 @@
       dest->false_target()->Jump();
 
       is_string.Bind(&left_side);
-      // Here we know we have a sequential ASCII string.
+      // left_side is a sequential ASCII string.
       left_side = Result(left_reg);
       right_side = Result(right_val);
       Result temp2 = allocator_->Allocate();
@@ -2685,7 +2688,7 @@
                Immediate(1));
         __ j(not_equal, &comparison_done);
         uint8_t char_value =
-            static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
+            static_cast<uint8_t>(String::cast(*right_val)->Get(0));
         __ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
                 char_value);
         __ bind(&comparison_done);
@@ -2694,17 +2697,17 @@
                FieldOperand(left_side.reg(), String::kLengthOffset));
         __ sub(Operand(temp2.reg()), Immediate(1));
         Label comparison;
-        // If the length is 0 then our subtraction gave -1 which compares less
+        // If the length is 0 then the subtraction gave -1 which compares less
         // than any character.
         __ j(negative, &comparison);
         // Otherwise load the first character.
         __ movzx_b(temp2.reg(),
                    FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize));
         __ bind(&comparison);
-        // Compare the first character of the string with out constant
-        // 1-character string.
+        // Compare the first character of the string with the
+        // constant 1-character string.
         uint8_t char_value =
-            static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
+            static_cast<uint8_t>(String::cast(*right_val)->Get(0));
         __ cmp(Operand(temp2.reg()), Immediate(char_value));
         Label characters_were_different;
         __ j(not_equal, &characters_were_different);
@@ -6523,7 +6526,7 @@
 
 
 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
-  ASSERT_EQ(args->length(), 4);
+  ASSERT_EQ(4, args->length());
 
   // Load the arguments on the stack and call the stub.
   Load(args->at(0));
@@ -6536,6 +6539,95 @@
 }
 
 
+void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) {
+  // No stub. This code only occurs a few times in regexp.js.
+  const int kMaxInlineLength = 100;
+  ASSERT_EQ(3, args->length());
+  Load(args->at(0));  // Size of array, smi.
+  Load(args->at(1));  // "index" property value.
+  Load(args->at(2));  // "input" property value.
+  {
+    VirtualFrame::SpilledScope spilled_scope;
+
+    Label slowcase;
+    Label done;
+    __ mov(ebx, Operand(esp, kPointerSize * 2));
+    __ test(ebx, Immediate(kSmiTagMask));
+    __ j(not_zero, &slowcase);
+    __ cmp(Operand(ebx), Immediate(Smi::FromInt(kMaxInlineLength)));
+    __ j(above, &slowcase);
+    // Smi-tagging is equivalent to multiplying by 2.
+    STATIC_ASSERT(kSmiTag == 0);
+    STATIC_ASSERT(kSmiTagSize == 1);
+    // Allocate RegExpResult followed by FixedArray with size in ebx.
+    // JSArray:   [Map][empty properties][Elements][Length-smi][index][input]
+    // Elements:  [Map][Length][..elements..]
+    __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
+                          times_half_pointer_size,
+                          ebx,  // In: Number of elements (times 2, being a smi)
+                          eax,  // Out: Start of allocation (tagged).
+                          ecx,  // Out: End of allocation.
+                          edx,  // Scratch register
+                          &slowcase,
+                          TAG_OBJECT);
+    // eax: Start of allocated area, object-tagged.
+
+    // Set JSArray map to global.regexp_result_map().
+    // Set empty properties FixedArray.
+    // Set elements to point to FixedArray allocated right after the JSArray.
+    // Interleave operations for better latency.
+    __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
+    __ mov(ecx, Immediate(Factory::empty_fixed_array()));
+    __ lea(ebx, Operand(eax, JSRegExpResult::kSize));
+    __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
+    __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
+    __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx);
+    __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX));
+    __ mov(FieldOperand(eax, HeapObject::kMapOffset), edx);
+
+    // Set input, index and length fields from arguments.
+    __ pop(FieldOperand(eax, JSRegExpResult::kInputOffset));
+    __ pop(FieldOperand(eax, JSRegExpResult::kIndexOffset));
+    __ pop(ecx);
+    __ mov(FieldOperand(eax, JSArray::kLengthOffset), ecx);
+
+    // Fill out the elements FixedArray.
+    // eax: JSArray.
+    // ebx: FixedArray.
+    // ecx: Number of elements in array, as smi.
+
+    // Set map.
+    __ mov(FieldOperand(ebx, HeapObject::kMapOffset),
+           Immediate(Factory::fixed_array_map()));
+    // Set length.
+    __ SmiUntag(ecx);
+    __ mov(FieldOperand(ebx, FixedArray::kLengthOffset), ecx);
+    // Fill contents of fixed-array with the-hole.
+    __ mov(edx, Immediate(Factory::the_hole_value()));
+    __ lea(ebx, FieldOperand(ebx, FixedArray::kHeaderSize));
+    // Fill fixed array elements with hole.
+    // eax: JSArray.
+    // ecx: Number of elements to fill.
+    // ebx: Start of elements in FixedArray.
+    // edx: the hole.
+    Label loop;
+    __ test(ecx, Operand(ecx));
+    __ bind(&loop);
+    __ j(less_equal, &done);  // Jump if ecx is negative or zero.
+    __ sub(Operand(ecx), Immediate(1));
+    __ mov(Operand(ebx, ecx, times_pointer_size, 0), edx);
+    __ jmp(&loop);
+
+    __ bind(&slowcase);
+    __ CallRuntime(Runtime::kRegExpConstructResult, 3);
+
+    __ bind(&done);
+  }
+  frame_->Forget(3);
+  frame_->Push(eax);
+}
+
+
 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
   ASSERT_EQ(args->length(), 1);
 
@@ -11082,62 +11174,94 @@
 }
 
 
+static int NegativeComparisonResult(Condition cc) {
+  ASSERT(cc != equal);
+  ASSERT((cc == less) || (cc == less_equal)
+      || (cc == greater) || (cc == greater_equal));
+  return (cc == greater || cc == greater_equal) ? LESS : GREATER;
+}
+
+
 void CompareStub::Generate(MacroAssembler* masm) {
   Label call_builtin, done;
 
   // NOTICE! This code is only reached after a smi-fast-case check, so
   // it is certain that at least one operand isn't a smi.
 
-  if (cc_ == equal) {  // Both strict and non-strict.
-    Label slow;  // Fallthrough label.
-    // Equality is almost reflexive (everything but NaN), so start by testing
-    // for "identity and not NaN".
-    {
-      Label not_identical;
-      __ cmp(eax, Operand(edx));
-      __ j(not_equal, &not_identical);
-      // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
-      // so we do the second best thing - test it ourselves.
+  // Identical objects can be compared fast, but there are some tricky cases
+  // for NaN and undefined.
+  {
+    Label not_identical;
+    __ cmp(eax, Operand(edx));
+    __ j(not_equal, &not_identical);
 
-      if (never_nan_nan_) {
-        __ Set(eax, Immediate(0));
-        __ ret(0);
-      } else {
-        Label return_equal;
-        Label heap_number;
-        // If it's not a heap number, then return equal.
-        __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
-               Immediate(Factory::heap_number_map()));
-        __ j(equal, &heap_number);
-        __ bind(&return_equal);
-        __ Set(eax, Immediate(0));
-        __ ret(0);
+    if (cc_ != equal) {
+      // Check for undefined.  undefined OP undefined is false even though
+      // undefined == undefined.
+      Label check_for_nan;
+      __ cmp(edx, Factory::undefined_value());
+      __ j(not_equal, &check_for_nan);
+      __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
+      __ ret(0);
+      __ bind(&check_for_nan);
+    }
 
-        __ bind(&heap_number);
-        // It is a heap number, so return non-equal if it's NaN and equal if
-        // it's not NaN.
-        // The representation of NaN values has all exponent bits (52..62) set,
-        // and not all mantissa bits (0..51) clear.
-        // We only accept QNaNs, which have bit 51 set.
-        // Read top bits of double representation (second word of value).
+    // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
+    // so we do the second best thing - test it ourselves.
+    // Note: if cc_ != equal, never_nan_nan_ is not used.
+    if (never_nan_nan_ && (cc_ == equal)) {
+      __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
+      __ ret(0);
+    } else {
+      Label return_equal;
+      Label heap_number;
+      // If it's not a heap number, then return equal.
+      __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
+             Immediate(Factory::heap_number_map()));
+      __ j(equal, &heap_number);
+      __ bind(&return_equal);
+      __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
+      __ ret(0);
 
-        // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
-        // all bits in the mask are set. We only need to check the word
-        // that contains the exponent and high bit of the mantissa.
-        ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
-        __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
-        __ xor_(eax, Operand(eax));
-        // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
-        // bits.
-        __ add(edx, Operand(edx));
-        __ cmp(edx, kQuietNaNHighBitsMask << 1);
+      __ bind(&heap_number);
+      // It is a heap number, so return non-equal if it's NaN and equal if
+      // it's not NaN.
+      // The representation of NaN values has all exponent bits (52..62) set,
+      // and not all mantissa bits (0..51) clear.
+      // We only accept QNaNs, which have bit 51 set.
+      // Read top bits of double representation (second word of value).
+
+      // Value is a QNaN if value & kQuietNaNMask == kQuietNaNMask, i.e.,
+      // all bits in the mask are set. We only need to check the word
+      // that contains the exponent and high bit of the mantissa.
+      ASSERT_NE(0, (kQuietNaNHighBitsMask << 1) & 0x80000000u);
+      __ mov(edx, FieldOperand(edx, HeapNumber::kExponentOffset));
+      __ xor_(eax, Operand(eax));
+      // Shift value and mask so kQuietNaNHighBitsMask applies to topmost
+      // bits.
+      __ add(edx, Operand(edx));
+      __ cmp(edx, kQuietNaNHighBitsMask << 1);
+      if (cc_ == equal) {
+        ASSERT_NE(1, EQUAL);
         __ setcc(above_equal, eax);
         __ ret(0);
+      } else {
+        Label nan;
+        __ j(above_equal, &nan);
+        __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
+        __ ret(0);
+        __ bind(&nan);
+        __ Set(eax, Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
+        __ ret(0);
       }
-
-      __ bind(&not_identical);
     }
 
+    __ bind(&not_identical);
+  }
+
+  if (cc_ == equal) {  // Both strict and non-strict.
+    Label slow;  // Fallthrough label.
+
     // If we're doing a strict equality comparison, we don't have to do
     // type conversion, so we generate code to do fast comparison for objects
     // and oddballs. Non-smi numbers and strings still go through the usual
@@ -11327,14 +11451,7 @@
     builtin = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
   } else {
     builtin = Builtins::COMPARE;
-    int ncr;  // NaN compare result
-    if (cc_ == less || cc_ == less_equal) {
-      ncr = GREATER;
-    } else {
-      ASSERT(cc_ == greater || cc_ == greater_equal);  // remaining cases
-      ncr = LESS;
-    }
-    __ push(Immediate(Smi::FromInt(ncr)));
+    __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc_))));
   }
 
   // Restore return address on the stack.
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 03a0fba..a8568f0 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -628,6 +628,8 @@
   // Support for direct calls from JavaScript to native RegExp code.
   void GenerateRegExpExec(ZoneList<Expression*>* args);
 
+  void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
+
   // Fast support for number to string.
   void GenerateNumberToString(ZoneList<Expression*>* args);
 
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 315600b..396a5a3 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1948,6 +1948,32 @@
 }
 
 
+Object* LoadStubCompiler::CompileLoadNonexistent(JSObject* object) {
+  // ----------- S t a t e -------------
+  //  -- eax    : receiver
+  //  -- ecx    : name
+  //  -- esp[0] : return address
+  // -----------------------------------
+  Label miss;
+
+  // Check the maps of the full prototype chain.
+  JSObject* last = object;
+  while (last->GetPrototype() != Heap::null_value()) {
+    last = JSObject::cast(last->GetPrototype());
+  }
+  CheckPrototypes(object, eax, last, ebx, edx, Heap::empty_string(), &miss);
+
+  // Return undefined if maps of the full prototype chain is still the same.
+  __ mov(eax, Factory::undefined_value());
+  __ ret(0);
+
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(NONEXISTENT, Heap::empty_string());
+}
+
 
 Object* LoadStubCompiler::CompileLoadField(JSObject* object,
                                            JSObject* holder,
diff --git a/src/ic.cc b/src/ic.cc
index b9ca00f..410699c 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -694,8 +694,8 @@
                           State state,
                           Handle<Object> object,
                           Handle<String> name) {
-  // Bail out if we didn't find a result.
-  if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
+  // Bail out if the result is not cachable.
+  if (!lookup->IsCacheable()) return;
 
   // Loading properties from values is not common, so don't try to
   // deal with non-JS objects here.
@@ -709,6 +709,9 @@
     // Set the target to the pre monomorphic stub to delay
     // setting the monomorphic state.
     code = pre_monomorphic_stub();
+  } else if (!lookup->IsProperty()) {
+    // Nonexistent property. The result is undefined.
+    code = StubCache::ComputeLoadNonexistent(*name, *receiver);
   } else {
     // Compute monomorphic stub.
     switch (lookup->type()) {
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 8e02b5d..8c1316b 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -558,8 +558,9 @@
 
   Vector<byte> GetResult() {
     // Return the bytes from pos up to end of buffer.
-    return Vector<byte>(reloc_info_writer_.pos(),
-                        buffer_ + buffer_size_ - reloc_info_writer_.pos());
+    int result_size =
+        static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer_.pos());
+    return Vector<byte>(reloc_info_writer_.pos(), result_size);
   }
 
  private:
@@ -581,7 +582,8 @@
     byte* new_buffer = NewArray<byte>(new_buffer_size);
 
     // Copy the data.
-    int curently_used_size = buffer_ + buffer_size_ - reloc_info_writer_.pos();
+    int curently_used_size =
+        static_cast<int>(buffer_ + buffer_size_ - reloc_info_writer_.pos());
     memmove(new_buffer + new_buffer_size - curently_used_size,
             reloc_info_writer_.pos(), curently_used_size);
 
@@ -986,7 +988,7 @@
       DropActivationsInActiveThread(shared_info_array, result, do_drop);
   if (error_message != NULL) {
     // Add error message as an array extra element.
-    Vector<const char> vector_message(error_message, strlen(error_message));
+    Vector<const char> vector_message(error_message, StrLength(error_message));
     Handle<String> str = Factory::NewStringFromAscii(vector_message);
     SetElement(result, len, str);
   }
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 2dfe3cc..80ad389 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -53,13 +53,13 @@
 // Counters used for debugging the marking phase of mark-compact or mark-sweep
 // collection.
 int MarkCompactCollector::live_bytes_ = 0;
-int MarkCompactCollector::live_young_objects_ = 0;
-int MarkCompactCollector::live_old_data_objects_ = 0;
-int MarkCompactCollector::live_old_pointer_objects_ = 0;
-int MarkCompactCollector::live_code_objects_ = 0;
-int MarkCompactCollector::live_map_objects_ = 0;
-int MarkCompactCollector::live_cell_objects_ = 0;
-int MarkCompactCollector::live_lo_objects_ = 0;
+int MarkCompactCollector::live_young_objects_size_ = 0;
+int MarkCompactCollector::live_old_data_objects_size_ = 0;
+int MarkCompactCollector::live_old_pointer_objects_size_ = 0;
+int MarkCompactCollector::live_code_objects_size_ = 0;
+int MarkCompactCollector::live_map_objects_size_ = 0;
+int MarkCompactCollector::live_cell_objects_size_ = 0;
+int MarkCompactCollector::live_lo_objects_size_ = 0;
 #endif
 
 void MarkCompactCollector::CollectGarbage() {
@@ -136,13 +136,13 @@
 
 #ifdef DEBUG
   live_bytes_ = 0;
-  live_young_objects_ = 0;
-  live_old_pointer_objects_ = 0;
-  live_old_data_objects_ = 0;
-  live_code_objects_ = 0;
-  live_map_objects_ = 0;
-  live_cell_objects_ = 0;
-  live_lo_objects_ = 0;
+  live_young_objects_size_ = 0;
+  live_old_pointer_objects_size_ = 0;
+  live_old_data_objects_size_ = 0;
+  live_code_objects_size_ = 0;
+  live_map_objects_size_ = 0;
+  live_cell_objects_size_ = 0;
+  live_lo_objects_size_ = 0;
 #endif
 }
 
@@ -742,21 +742,21 @@
 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) {
   live_bytes_ += obj->Size();
   if (Heap::new_space()->Contains(obj)) {
-    live_young_objects_++;
+    live_young_objects_size_ += obj->Size();
   } else if (Heap::map_space()->Contains(obj)) {
     ASSERT(obj->IsMap());
-    live_map_objects_++;
+    live_map_objects_size_ += obj->Size();
   } else if (Heap::cell_space()->Contains(obj)) {
     ASSERT(obj->IsJSGlobalPropertyCell());
-    live_cell_objects_++;
+    live_cell_objects_size_ += obj->Size();
   } else if (Heap::old_pointer_space()->Contains(obj)) {
-    live_old_pointer_objects_++;
+    live_old_pointer_objects_size_ += obj->Size();
   } else if (Heap::old_data_space()->Contains(obj)) {
-    live_old_data_objects_++;
+    live_old_data_objects_size_ += obj->Size();
   } else if (Heap::code_space()->Contains(obj)) {
-    live_code_objects_++;
+    live_code_objects_size_ += obj->Size();
   } else if (Heap::lo_space()->Contains(obj)) {
-    live_lo_objects_++;
+    live_lo_objects_size_ += obj->Size();
   } else {
     UNREACHABLE();
   }
@@ -1068,31 +1068,210 @@
 }
 
 
-static void SweepSpace(NewSpace* space) {
+// We scavange new space simultaneously with sweeping. This is done in two
+// passes.
+// The first pass migrates all alive objects from one semispace to another or
+// promotes them to old space. Forwading address is written directly into
+// first word of object without any encoding. If object is dead we are writing
+// NULL as a forwarding address.
+// The second pass updates pointers to new space in all spaces. It is possible
+// to encounter pointers to dead objects during traversal of remembered set for
+// map space because remembered set bits corresponding to dead maps are cleared
+// later during map space sweeping.
+static void MigrateObject(Address dst, Address src, int size) {
+  Heap::CopyBlock(reinterpret_cast<Object**>(dst),
+                  reinterpret_cast<Object**>(src),
+                  size);
+
+  Memory::Address_at(src) = dst;
+}
+
+
+// Visitor for updating pointers from live objects in old spaces to new space.
+// It does not expect to encounter pointers to dead objects.
+class PointersToNewGenUpdatingVisitor: public ObjectVisitor {
+ public:
+  void VisitPointer(Object** p) {
+    UpdatePointer(p);
+  }
+
+  void VisitPointers(Object** start, Object** end) {
+    for (Object** p = start; p < end; p++) UpdatePointer(p);
+  }
+
+  void VisitCodeTarget(RelocInfo* rinfo) {
+    ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
+    Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
+    VisitPointer(&target);
+    rinfo->set_target_address(Code::cast(target)->instruction_start());
+  }
+
+  void VisitDebugTarget(RelocInfo* rinfo) {
+    ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) &&
+           rinfo->IsPatchedReturnSequence());
+    Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
+    VisitPointer(&target);
+    rinfo->set_call_address(Code::cast(target)->instruction_start());
+  }
+
+ private:
+  void UpdatePointer(Object** p) {
+    if (!(*p)->IsHeapObject()) return;
+
+    HeapObject* obj = HeapObject::cast(*p);
+    Address old_addr = obj->address();
+
+    if (Heap::new_space()->Contains(obj)) {
+      ASSERT(Heap::InFromSpace(*p));
+      *p = HeapObject::FromAddress(Memory::Address_at(old_addr));
+    }
+  }
+};
+
+// Visitor for updating pointers from live objects in old spaces to new space.
+// It can encounter pointers to dead objects in new space when traversing map
+// space (see comment for MigrateObject).
+static void UpdatePointerToNewGen(HeapObject** p) {
+  if (!(*p)->IsHeapObject()) return;
+
+  Address old_addr = (*p)->address();
+  ASSERT(Heap::InFromSpace(*p));
+
+  Address new_addr = Memory::Address_at(old_addr);
+
+  // Object pointed by *p is dead. Update is not required.
+  if (new_addr == NULL) return;
+
+  *p = HeapObject::FromAddress(new_addr);
+}
+
+
+static String* UpdateNewSpaceReferenceInExternalStringTableEntry(Object **p) {
+  Address old_addr = HeapObject::cast(*p)->address();
+  Address new_addr = Memory::Address_at(old_addr);
+  return String::cast(HeapObject::FromAddress(new_addr));
+}
+
+
+static bool TryPromoteObject(HeapObject* object, int object_size) {
+  Object* result;
+
+  if (object_size > Heap::MaxObjectSizeInPagedSpace()) {
+    result = Heap::lo_space()->AllocateRawFixedArray(object_size);
+    if (!result->IsFailure()) {
+      HeapObject* target = HeapObject::cast(result);
+      MigrateObject(target->address(), object->address(), object_size);
+      Heap::UpdateRSet(target);
+      return true;
+    }
+  } else {
+    OldSpace* target_space = Heap::TargetSpace(object);
+
+    ASSERT(target_space == Heap::old_pointer_space() ||
+           target_space == Heap::old_data_space());
+    result = target_space->AllocateRaw(object_size);
+    if (!result->IsFailure()) {
+      HeapObject* target = HeapObject::cast(result);
+      MigrateObject(target->address(), object->address(), object_size);
+      if (target_space == Heap::old_pointer_space()) {
+        Heap::UpdateRSet(target);
+      }
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+static void SweepNewSpace(NewSpace* space) {
+  Heap::CheckNewSpaceExpansionCriteria();
+
+  Address from_bottom = space->bottom();
+  Address from_top = space->top();
+
+  // Flip the semispaces.  After flipping, to space is empty, from space has
+  // live objects.
+  space->Flip();
+  space->ResetAllocationInfo();
+
+  int size = 0;
+  int survivors_size = 0;
+
+  // First pass: traverse all objects in inactive semispace, remove marks,
+  // migrate live objects and write forwarding addresses.
+  for (Address current = from_bottom; current < from_top; current += size) {
+    HeapObject* object = HeapObject::FromAddress(current);
+
+    if (object->IsMarked()) {
+      object->ClearMark();
+      MarkCompactCollector::tracer()->decrement_marked_count();
+
+      size = object->Size();
+      survivors_size += size;
+
+      if (Heap::ShouldBePromoted(current, size) &&
+          TryPromoteObject(object, size)) {
+        continue;
+      }
+
+      // Promotion either failed or not required.
+      // Copy the content of the object.
+      Object* target = space->AllocateRaw(size);
+
+      // Allocation cannot fail at this point: semispaces are of equal size.
+      ASSERT(!target->IsFailure());
+
+      MigrateObject(HeapObject::cast(target)->address(), current, size);
+    } else {
+      size = object->Size();
+      Memory::Address_at(current) = NULL;
+    }
+  }
+
+  // Second pass: find pointers to new space and update them.
+  PointersToNewGenUpdatingVisitor updating_visitor;
+
+  // Update pointers in to space.
   HeapObject* object;
   for (Address current = space->bottom();
        current < space->top();
        current += object->Size()) {
     object = HeapObject::FromAddress(current);
-    if (object->IsMarked()) {
-      object->ClearMark();
-      MarkCompactCollector::tracer()->decrement_marked_count();
-    } else {
-      // We give non-live objects a map that will correctly give their size,
-      // since their existing map might not be live after the collection.
-      int size = object->Size();
-      if (size >= ByteArray::kHeaderSize) {
-        object->set_map(Heap::raw_unchecked_byte_array_map());
-        ByteArray::cast(object)->set_length(ByteArray::LengthFor(size));
-      } else {
-        ASSERT(size == kPointerSize);
-        object->set_map(Heap::raw_unchecked_one_pointer_filler_map());
-      }
-      ASSERT(object->Size() == size);
-    }
-    // The object is now unmarked for the call to Size() at the top of the
-    // loop.
+
+    object->IterateBody(object->map()->instance_type(),
+                        object->Size(),
+                        &updating_visitor);
   }
+
+  // Update roots.
+  Heap::IterateRoots(&updating_visitor, VISIT_ALL_IN_SCAVENGE);
+
+  // Update pointers in old spaces.
+  Heap::IterateRSet(Heap::old_pointer_space(), &UpdatePointerToNewGen);
+  Heap::IterateRSet(Heap::map_space(), &UpdatePointerToNewGen);
+  Heap::lo_space()->IterateRSet(&UpdatePointerToNewGen);
+
+  // Update pointers from cells.
+  HeapObjectIterator cell_iterator(Heap::cell_space());
+  for (HeapObject* cell = cell_iterator.next();
+       cell != NULL;
+       cell = cell_iterator.next()) {
+    if (cell->IsJSGlobalPropertyCell()) {
+      Address value_address =
+          reinterpret_cast<Address>(cell) +
+          (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag);
+      updating_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
+    }
+  }
+
+  // Update pointers from external string table.
+  Heap::UpdateNewSpaceReferencesInExternalStringTable(
+      &UpdateNewSpaceReferenceInExternalStringTableEntry);
+
+  // All pointers were updated. Update auxiliary allocation info.
+  Heap::IncrementYoungSurvivorsCounter(survivors_size);
+  space->set_age_mark(space->top());
 }
 
 
@@ -1382,10 +1561,12 @@
     ASSERT(FreeListNode::IsFreeListNode(vacant_map));
     ASSERT(map_to_evacuate->IsMap());
 
-    memcpy(
-        reinterpret_cast<void*>(vacant_map->address()),
-        reinterpret_cast<void*>(map_to_evacuate->address()),
-        Map::kSize);
+    ASSERT(Map::kSize % 4 == 0);
+
+    Heap::CopyBlock(reinterpret_cast<Object**>(vacant_map->address()),
+                    reinterpret_cast<Object**>(map_to_evacuate->address()),
+                    Map::kSize);
+
     ASSERT(vacant_map->IsMap());  // Due to memcpy above.
 
     MapWord forwarding_map_word = MapWord::FromMap(vacant_map);
@@ -1465,10 +1646,11 @@
   SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock);
   SweepSpace(Heap::code_space(), &DeallocateCodeBlock);
   SweepSpace(Heap::cell_space(), &DeallocateCellBlock);
-  SweepSpace(Heap::new_space());
+  SweepNewSpace(Heap::new_space());
   SweepSpace(Heap::map_space(), &DeallocateMapBlock);
-  int live_maps = Heap::map_space()->Size() / Map::kSize;
-  ASSERT(live_map_objects_ == live_maps);
+  int live_maps_size = Heap::map_space()->Size();
+  int live_maps = live_maps_size / Map::kSize;
+  ASSERT(live_map_objects_size_ == live_maps_size);
 
   if (Heap::map_space()->NeedsCompaction(live_maps)) {
     MapCompact map_compact(live_maps);
@@ -1500,7 +1682,7 @@
     Address start,
     Address end,
     HeapObjectCallback size_func) {
-  int live_objects = 0;
+  int live_objects_size = 0;
   Address current = start;
   while (current < end) {
     uint32_t encoded_map = Memory::uint32_at(current);
@@ -1509,11 +1691,12 @@
     } else if (encoded_map == kMultiFreeEncoding) {
       current += Memory::int_at(current + kIntSize);
     } else {
-      live_objects++;
-      current += size_func(HeapObject::FromAddress(current));
+      int size = size_func(HeapObject::FromAddress(current));
+      current += size;
+      live_objects_size += size;
     }
   }
-  return live_objects;
+  return live_objects_size;
 }
 
 
@@ -1639,36 +1822,36 @@
   Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
   GlobalHandles::IterateWeakRoots(&updating_visitor);
 
-  int live_maps = IterateLiveObjects(Heap::map_space(),
-                                     &UpdatePointersInOldObject);
-  int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
-                                             &UpdatePointersInOldObject);
-  int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
+  int live_maps_size = IterateLiveObjects(Heap::map_space(),
                                           &UpdatePointersInOldObject);
-  int live_codes = IterateLiveObjects(Heap::code_space(),
-                                      &UpdatePointersInOldObject);
-  int live_cells = IterateLiveObjects(Heap::cell_space(),
-                                      &UpdatePointersInOldObject);
-  int live_news = IterateLiveObjects(Heap::new_space(),
-                                     &UpdatePointersInNewObject);
+  int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
+                                                  &UpdatePointersInOldObject);
+  int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
+                                               &UpdatePointersInOldObject);
+  int live_codes_size = IterateLiveObjects(Heap::code_space(),
+                                           &UpdatePointersInOldObject);
+  int live_cells_size = IterateLiveObjects(Heap::cell_space(),
+                                           &UpdatePointersInOldObject);
+  int live_news_size = IterateLiveObjects(Heap::new_space(),
+                                          &UpdatePointersInNewObject);
 
   // Large objects do not move, the map word can be updated directly.
   LargeObjectIterator it(Heap::lo_space());
   for (HeapObject* obj = it.next(); obj != NULL; obj = it.next())
     UpdatePointersInNewObject(obj);
 
-  USE(live_maps);
-  USE(live_pointer_olds);
-  USE(live_data_olds);
-  USE(live_codes);
-  USE(live_cells);
-  USE(live_news);
-  ASSERT(live_maps == live_map_objects_);
-  ASSERT(live_data_olds == live_old_data_objects_);
-  ASSERT(live_pointer_olds == live_old_pointer_objects_);
-  ASSERT(live_codes == live_code_objects_);
-  ASSERT(live_cells == live_cell_objects_);
-  ASSERT(live_news == live_young_objects_);
+  USE(live_maps_size);
+  USE(live_pointer_olds_size);
+  USE(live_data_olds_size);
+  USE(live_codes_size);
+  USE(live_cells_size);
+  USE(live_news_size);
+  ASSERT(live_maps_size == live_map_objects_size_);
+  ASSERT(live_data_olds_size == live_old_data_objects_size_);
+  ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
+  ASSERT(live_codes_size == live_code_objects_size_);
+  ASSERT(live_cells_size == live_cell_objects_size_);
+  ASSERT(live_news_size == live_young_objects_size_);
 }
 
 
@@ -1783,27 +1966,31 @@
 #endif
   // Relocates objects, always relocate map objects first. Relocating
   // objects in other space relies on map objects to get object size.
-  int live_maps = IterateLiveObjects(Heap::map_space(), &RelocateMapObject);
-  int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),
-                                             &RelocateOldPointerObject);
-  int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
-                                          &RelocateOldDataObject);
-  int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject);
-  int live_cells = IterateLiveObjects(Heap::cell_space(), &RelocateCellObject);
-  int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject);
+  int live_maps_size = IterateLiveObjects(Heap::map_space(),
+                                          &RelocateMapObject);
+  int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
+                                                  &RelocateOldPointerObject);
+  int live_data_olds_size = IterateLiveObjects(Heap::old_data_space(),
+                                               &RelocateOldDataObject);
+  int live_codes_size = IterateLiveObjects(Heap::code_space(),
+                                           &RelocateCodeObject);
+  int live_cells_size = IterateLiveObjects(Heap::cell_space(),
+                                           &RelocateCellObject);
+  int live_news_size = IterateLiveObjects(Heap::new_space(),
+                                          &RelocateNewObject);
 
-  USE(live_maps);
-  USE(live_data_olds);
-  USE(live_pointer_olds);
-  USE(live_codes);
-  USE(live_cells);
-  USE(live_news);
-  ASSERT(live_maps == live_map_objects_);
-  ASSERT(live_data_olds == live_old_data_objects_);
-  ASSERT(live_pointer_olds == live_old_pointer_objects_);
-  ASSERT(live_codes == live_code_objects_);
-  ASSERT(live_cells == live_cell_objects_);
-  ASSERT(live_news == live_young_objects_);
+  USE(live_maps_size);
+  USE(live_pointer_olds_size);
+  USE(live_data_olds_size);
+  USE(live_codes_size);
+  USE(live_cells_size);
+  USE(live_news_size);
+  ASSERT(live_maps_size == live_map_objects_size_);
+  ASSERT(live_data_olds_size == live_old_data_objects_size_);
+  ASSERT(live_pointer_olds_size == live_old_pointer_objects_size_);
+  ASSERT(live_codes_size == live_code_objects_size_);
+  ASSERT(live_cells_size == live_cell_objects_size_);
+  ASSERT(live_news_size == live_young_objects_size_);
 
   // Flip from and to spaces
   Heap::new_space()->Flip();
@@ -1821,6 +2008,9 @@
   PagedSpaces spaces;
   for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next())
     space->MCCommitRelocationInfo();
+
+  Heap::CheckNewSpaceExpansionCriteria();
+  Heap::IncrementYoungSurvivorsCounter(live_news_size);
 }
 
 
@@ -1840,7 +2030,10 @@
   Address old_addr = obj->address();
 
   if (new_addr != old_addr) {
-    memmove(new_addr, old_addr, Map::kSize);  // copy contents
+    // Move contents.
+    Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
+                    reinterpret_cast<Object**>(old_addr),
+                    Map::kSize);
   }
 
 #ifdef DEBUG
@@ -1896,7 +2089,10 @@
   Address old_addr = obj->address();
 
   if (new_addr != old_addr) {
-    memmove(new_addr, old_addr, obj_size);  // Copy contents
+    // Move contents.
+    Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
+                    reinterpret_cast<Object**>(old_addr),
+                    obj_size);
   }
 
   ASSERT(!HeapObject::FromAddress(new_addr)->IsCode());
@@ -1940,7 +2136,10 @@
   Address old_addr = obj->address();
 
   if (new_addr != old_addr) {
-    memmove(new_addr, old_addr, obj_size);  // Copy contents.
+    // Move contents.
+    Heap::MoveBlock(reinterpret_cast<Object**>(new_addr),
+                    reinterpret_cast<Object**>(old_addr),
+                    obj_size);
   }
 
   HeapObject* copied_to = HeapObject::FromAddress(new_addr);
@@ -1976,9 +2175,9 @@
 #endif
 
   // New and old addresses cannot overlap.
-  memcpy(reinterpret_cast<void*>(new_addr),
-         reinterpret_cast<void*>(old_addr),
-         obj_size);
+  Heap::CopyBlock(reinterpret_cast<Object**>(new_addr),
+                  reinterpret_cast<Object**>(old_addr),
+                  obj_size);
 
 #ifdef DEBUG
   if (FLAG_gc_verbose) {
diff --git a/src/mark-compact.h b/src/mark-compact.h
index ab572f6..27335f2 100644
--- a/src/mark-compact.h
+++ b/src/mark-compact.h
@@ -407,26 +407,26 @@
   // Counters used for debugging the marking phase of mark-compact or
   // mark-sweep collection.
 
-  // Number of live objects in Heap::to_space_.
-  static int live_young_objects_;
+  // Size of live objects in Heap::to_space_.
+  static int live_young_objects_size_;
 
-  // Number of live objects in Heap::old_pointer_space_.
-  static int live_old_pointer_objects_;
+  // Size of live objects in Heap::old_pointer_space_.
+  static int live_old_pointer_objects_size_;
 
-  // Number of live objects in Heap::old_data_space_.
-  static int live_old_data_objects_;
+  // Size of live objects in Heap::old_data_space_.
+  static int live_old_data_objects_size_;
 
-  // Number of live objects in Heap::code_space_.
-  static int live_code_objects_;
+  // Size of live objects in Heap::code_space_.
+  static int live_code_objects_size_;
 
-  // Number of live objects in Heap::map_space_.
-  static int live_map_objects_;
+  // Size of live objects in Heap::map_space_.
+  static int live_map_objects_size_;
 
-  // Number of live objects in Heap::cell_space_.
-  static int live_cell_objects_;
+  // Size of live objects in Heap::cell_space_.
+  static int live_cell_objects_size_;
 
-  // Number of live objects in Heap::lo_space_.
-  static int live_lo_objects_;
+  // Size of live objects in Heap::lo_space_.
+  static int live_lo_objects_size_;
 
   // Number of live bytes in this collection.
   static int live_bytes_;
diff --git a/src/objects.h b/src/objects.h
index 9197466..b07792c 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4632,6 +4632,26 @@
 };
 
 
+// JSRegExpResult is just a JSArray with a specific initial map.
+// This initial map adds in-object properties for "index" and "input"
+// properties, as assigned by RegExp.prototype.exec, which allows
+// faster creation of RegExp exec results.
+// This class just holds constants used when creating the result.
+// After creation the result must be treated as a JSArray in all regards.
+class JSRegExpResult: public JSArray {
+ public:
+  // Offsets of object fields.
+  static const int kIndexOffset = JSArray::kSize;
+  static const int kInputOffset = kIndexOffset + kPointerSize;
+  static const int kSize = kInputOffset + kPointerSize;
+  // Indices of in-object properties.
+  static const int kIndexIndex = 0;
+  static const int kInputIndex = 1;
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult);
+};
+
+
 // An accessor must have a getter, but can have no setter.
 //
 // When setting a property, V8 searches accessors in prototypes.
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 46e7aab..b809aab 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -327,7 +327,7 @@
 
 
 CpuProfile* CpuProfilesCollection::StopProfiling(const char* title) {
-  const int title_len = strlen(title);
+  const int title_len = StrLength(title);
   CpuProfile* profile = NULL;
   current_profiles_semaphore_->Wait();
   for (int i = current_profiles_.length() - 1; i >= 0; --i) {
diff --git a/src/regexp.js b/src/regexp.js
index c76b09d..9929b11 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -135,19 +135,52 @@
 var regExpCache = new RegExpCache();
 
 
-function CloneRegexpAnswer(array) {
+function CloneRegExpResult(array) {
   if (array == null) return null; 
-  var len = array.length;
-  var answer = new $Array(len);
-  for (var i = 0; i < len; i++) {
+  var length = array.length;
+  var answer = %_RegExpConstructResult(length, array.index, array.input);
+  for (var i = 0; i < length; i++) {
     answer[i] = array[i];
   }
-  answer.index = array.index;
-  answer.input = array.input;
   return answer;
 }
 
 
+function BuildResultFromMatchInfo(lastMatchInfo, s) {
+  var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
+  var result = %_RegExpConstructResult(numResults, lastMatchInfo[CAPTURE0], s);
+  if (numResults === 1) {
+    var matchStart = lastMatchInfo[CAPTURE(0)];
+    var matchEnd = lastMatchInfo[CAPTURE(1)];
+    result[0] = SubString(s, matchStart, matchEnd);
+  } else {
+    for (var i = 0; i < numResults; i++) {
+      var matchStart = lastMatchInfo[CAPTURE(i << 1)];
+      var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)];
+      if (matchStart != -1 && matchEnd != -1) {
+        result[i] = SubString(s, matchStart, matchEnd);
+      } else {
+        // Make sure the element is present. Avoid reading the undefined
+        // property from the global object since this may change.
+        result[i] = void 0;
+      }
+    }
+  }
+  return result;
+}
+
+
+function RegExpExecNoTests(regexp, string, start) {
+  // Must be called with RegExp, string and positive integer as arguments.
+  var matchInfo = DoRegExpExec(regexp, string, start);
+  var result = null;
+  if (matchInfo !== null) {
+    result = BuildResultFromMatchInfo(matchInfo, string);
+  }
+  return result;
+}
+
+
 function RegExpExec(string) {
   if (!IS_REGEXP(this)) {
     throw MakeTypeError('incompatible_method_receiver',
@@ -162,7 +195,7 @@
       %_ObjectEquals(cache.regExp, this) &&
       %_ObjectEquals(cache.subject, string)) {
     if (cache.answerSaved) {
-      return CloneRegexpAnswer(cache.answer);
+      return CloneRegExpResult(cache.answer);
     } else {
       saveAnswer = true;
     }
@@ -205,36 +238,15 @@
     return matchIndices;        // No match.
   }
 
-  var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
-  var result;
-  if (numResults === 1) {
-    var matchStart = lastMatchInfo[CAPTURE(0)];
-    var matchEnd = lastMatchInfo[CAPTURE(1)];
-    result = [SubString(s, matchStart, matchEnd)];
-  } else {
-    result = new $Array(numResults);
-    for (var i = 0; i < numResults; i++) {
-      var matchStart = lastMatchInfo[CAPTURE(i << 1)];
-      var matchEnd = lastMatchInfo[CAPTURE((i << 1) + 1)];
-      if (matchStart != -1 && matchEnd != -1) {
-        result[i] = SubString(s, matchStart, matchEnd);
-      } else {
-        // Make sure the element is present. Avoid reading the undefined
-        // property from the global object since this may change.
-        result[i] = void 0;
-      }
-    }
-  }
+  var result = BuildResultFromMatchInfo(matchIndices, s);
 
-  result.index = lastMatchInfo[CAPTURE0];
-  result.input = s;
   if (this.global) {
     this.lastIndex = lastMatchInfo[CAPTURE1];
   } else {
     cache.regExp = this;
     cache.subject = s;
     cache.lastIndex = lastIndex;
-    if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
+    if (saveAnswer) cache.answer = CloneRegExpResult(result);
     cache.answerSaved = saveAnswer;
     cache.type = 'exec';
   }
diff --git a/src/runtime.cc b/src/runtime.cc
index dc0e9c8..3d112b0 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1228,6 +1228,36 @@
 }
 
 
+static Object* Runtime_RegExpConstructResult(Arguments args) {
+  ASSERT(args.length() == 3);
+  CONVERT_SMI_CHECKED(elements_count, args[0]);
+  if (elements_count > JSArray::kMaxFastElementsLength) {
+    return Top::ThrowIllegalOperation();
+  }
+  Object* new_object = Heap::AllocateFixedArrayWithHoles(elements_count);
+  if (new_object->IsFailure()) return new_object;
+  FixedArray* elements = FixedArray::cast(new_object);
+  new_object = Heap::AllocateRaw(JSRegExpResult::kSize,
+                                 NEW_SPACE,
+                                 OLD_POINTER_SPACE);
+  if (new_object->IsFailure()) return new_object;
+  {
+    AssertNoAllocation no_gc;
+    HandleScope scope;
+    reinterpret_cast<HeapObject*>(new_object)->
+        set_map(Top::global_context()->regexp_result_map());
+  }
+  JSArray* array = JSArray::cast(new_object);
+  array->set_properties(Heap::empty_fixed_array());
+  array->set_elements(elements);
+  array->set_length(Smi::FromInt(elements_count));
+  // Write in-object properties after the length of the array.
+  array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
+  array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
+  return array;
+}
+
+
 static Object* Runtime_RegExpInitializeObject(Arguments args) {
   AssertNoAllocation no_alloc;
   ASSERT(args.length() == 5);
@@ -2512,7 +2542,7 @@
                pattern_char,
                string.length() - start_index));
     if (pos == NULL) return -1;
-    return pos - string.start();
+    return static_cast<int>(pos - string.start());
   }
   for (int i = start_index, n = string.length(); i < n; i++) {
     if (pattern_char == string[i]) {
@@ -2570,7 +2600,7 @@
         *complete = true;
         return -1;
       }
-      i = pos - subject.start();
+      i = static_cast<int>(pos - subject.start());
     } else {
       if (subject[i] != pattern_first_char) continue;
     }
@@ -2604,7 +2634,7 @@
                  pattern_first_char,
                  n - i + 1));
       if (pos == NULL) return -1;
-      i = pos - subject.start();
+      i = static_cast<int>(pos - subject.start());
     } else {
       if (subject[i] != pattern_first_char) continue;
     }
@@ -6336,7 +6366,7 @@
 static inline void DateYMDFromTimeAfter1970(int date,
                                             int& year, int& month, int& day) {
 #ifdef DEBUG
-  int save_date = date;  // Need this for ASSERT in the end.
+  int save_date = date;  // Need this for ASSERT in the end.
 #endif
 
   year = 1970 + (4 * date + 2) / kDaysIn4Years;
@@ -6352,7 +6382,7 @@
 static inline void DateYMDFromTimeSlow(int date,
                                        int& year, int& month, int& day) {
 #ifdef DEBUG
-  int save_date = date;  // Need this for ASSERT in the end.
+  int save_date = date;  // Need this for ASSERT in the end.
 #endif
 
   date += kDaysOffset;
@@ -9749,7 +9779,8 @@
     // Check if this break point is closer that what was previously found.
     if (source_position <= statement_position &&
         statement_position - source_position < distance) {
-      closest_pc = it.rinfo()->pc() - code->instruction_start();
+      closest_pc =
+          static_cast<int>(it.rinfo()->pc() - code->instruction_start());
       distance = statement_position - source_position;
       // Check whether we can't get any closer.
       if (distance == 0) break;
diff --git a/src/runtime.h b/src/runtime.h
index 870cfa6..69acd04 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -157,6 +157,7 @@
   F(RegExpExec, 4, 1) \
   F(RegExpExecMultiple, 4, 1) \
   F(RegExpInitializeObject, 5, 1) \
+  F(RegExpConstructResult, 3, 1) \
   \
   /* Strings */ \
   F(StringCharCodeAt, 2, 1) \
diff --git a/src/string.js b/src/string.js
index 300baf9..7ddc467 100644
--- a/src/string.js
+++ b/src/string.js
@@ -149,6 +149,16 @@
 }
 
 
+function CloneDenseArray(array) {
+  if (array === null) return null;
+  var clone = new $Array(array.length);
+  for (var i = 0; i < array.length; i++) {
+    clone[i] = array[i];
+  }
+  return clone;
+}
+
+
 // ECMA-262 section 15.5.4.9
 //
 // This function is implementation specific.  For now, we do not
@@ -164,33 +174,37 @@
 
 // ECMA-262 section 15.5.4.10
 function StringMatch(regexp) {
-  if (!IS_REGEXP(regexp)) regexp = new $RegExp(regexp);
   var subject = TO_STRING_INLINE(this);
+  if (IS_REGEXP(regexp)) { 
+    if (!regexp.global) return regexp.exec(subject); 
+    
+    var cache = regExpCache;
+    var saveAnswer = false;
 
-  if (!regexp.global) return regexp.exec(subject);
-
-  var cache = regExpCache;
-  var saveAnswer = false;
-
-  if (%_ObjectEquals(cache.type, 'match') &&
-      %_ObjectEquals(cache.regExp, regexp) &&
-      %_ObjectEquals(cache.subject, subject)) {
-    if (cache.answerSaved) {
-      return CloneRegexpAnswer(cache.answer);
-    } else {
-      saveAnswer = true;
+    if (%_ObjectEquals(cache.type, 'match') &&
+        %_ObjectEquals(cache.regExp, regexp) &&
+        %_ObjectEquals(cache.subject, subject)) {
+      if (cache.answerSaved) {
+        return CloneDenseArray(cache.answer);
+      } else {
+        saveAnswer = true;
+      }
     }
+    %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
+    // lastMatchInfo is defined in regexp.js.
+    var result = %StringMatch(subject, regexp, lastMatchInfo);
+    cache.type = 'match';
+    cache.regExp = regexp;
+    cache.subject = subject;
+    if (saveAnswer) cache.answer = CloneDenseArray(result);
+    cache.answerSaved = saveAnswer;
+    return result;
   }
-
-  %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
-  // lastMatchInfo is defined in regexp.js.
-  var result = %StringMatch(subject, regexp, lastMatchInfo);
-  cache.type = 'match';
-  cache.regExp = regexp;
-  cache.subject = subject;
-  if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
-  cache.answerSaved = saveAnswer;
-  return result;
+  // Non-regexp argument.
+  regexp = new $RegExp(regexp);
+  // Don't check regexp exec cache, since the regexp is new.
+  // TODO(lrn): Change this if we start caching regexps here.
+  return RegExpExecNoTests(regexp, subject, 0);
 }
 
 
@@ -599,7 +613,7 @@
       %_ObjectEquals(cache.regExp, separator) &&
       %_ObjectEquals(cache.subject, subject)) {
     if (cache.answerSaved) {
-      return CloneRegexpAnswer(cache.answer);
+      return CloneDenseArray(cache.answer);
     } else {
       saveAnswer = true;
     }
@@ -665,10 +679,9 @@
 
     startIndex = currentIndex = endIndex;
   }
-  if (saveAnswer) cache.answer = CloneRegexpAnswer(result);
+  if (saveAnswer) cache.answer = CloneDenseArray(result);
   cache.answerSaved = saveAnswer;
   return result;
-  
 }
 
 
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 95877fb..d77dc25 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -93,6 +93,28 @@
 }
 
 
+Object* StubCache::ComputeLoadNonexistent(String* name, JSObject* receiver) {
+  // The code stub for loading nonexistent properties can be reused
+  // for all names, so we use the empty_string as the name in the map
+  // code cache.
+  Code::Flags flags =
+      Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT);
+  Object* code = receiver->map()->FindInCodeCache(Heap::empty_string(), flags);
+  if (code->IsUndefined()) {
+    LoadStubCompiler compiler;
+    code = compiler.CompileLoadNonexistent(receiver);
+    if (code->IsFailure()) return code;
+    PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG,
+                            Code::cast(code),
+                            Heap::empty_string()));
+    Object* result = receiver->map()->UpdateCodeCache(Heap::empty_string(),
+                                                      Code::cast(code));
+    if (result->IsFailure()) return result;
+  }
+  return Set(name, receiver->map(), Code::cast(code));
+}
+
+
 Object* StubCache::ComputeLoadField(String* name,
                                     JSObject* receiver,
                                     JSObject* holder,
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 0ca37e7..8a68977 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -56,6 +56,8 @@
 
   // Computes the right stub matching. Inserts the result in the
   // cache before returning.  This might compile a stub if needed.
+  static Object* ComputeLoadNonexistent(String* name, JSObject* receiver);
+
   static Object* ComputeLoadField(String* name,
                                   JSObject* receiver,
                                   JSObject* holder,
@@ -461,18 +463,23 @@
 
 class LoadStubCompiler: public StubCompiler {
  public:
+  Object* CompileLoadNonexistent(JSObject* object);
+
   Object* CompileLoadField(JSObject* object,
                            JSObject* holder,
                            int index,
                            String* name);
+
   Object* CompileLoadCallback(String* name,
                               JSObject* object,
                               JSObject* holder,
                               AccessorInfo* callback);
+
   Object* CompileLoadConstant(JSObject* object,
                               JSObject* holder,
                               Object* value,
                               String* name);
+
   Object* CompileLoadInterceptor(JSObject* object,
                                  JSObject* holder,
                                  String* name);
@@ -494,17 +501,21 @@
                            JSObject* object,
                            JSObject* holder,
                            int index);
+
   Object* CompileLoadCallback(String* name,
                               JSObject* object,
                               JSObject* holder,
                               AccessorInfo* callback);
+
   Object* CompileLoadConstant(String* name,
                               JSObject* object,
                               JSObject* holder,
                               Object* value);
+
   Object* CompileLoadInterceptor(JSObject* object,
                                  JSObject* holder,
                                  String* name);
+
   Object* CompileLoadArrayLength(String* name);
   Object* CompileLoadStringLength(String* name);
   Object* CompileLoadFunctionPrototype(String* name);
diff --git a/src/utils.h b/src/utils.h
index b123057..fa24947 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -657,7 +657,7 @@
   return dest;
 }
 
-
 } }  // namespace v8::internal
 
+
 #endif  // V8_UTILS_H_
diff --git a/src/version.cc b/src/version.cc
index 7980ecc..a79dbd7 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     2
 #define MINOR_VERSION     2
-#define BUILD_NUMBER      2
+#define BUILD_NUMBER      3
 #define PATCH_LEVEL       0
 #define CANDIDATE_VERSION false
 
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 0c5d481..6d332b7 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -1240,7 +1240,7 @@
 
   // Set up the roots register.
   ExternalReference roots_address = ExternalReference::roots_address();
-  __ movq(r13, roots_address);
+  __ movq(kRootRegister, roots_address);
 
   // Current stack contents:
   // [rsp + 2 * kPointerSize ... ]: Internal frame
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 87ad4b0..1c26521 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -1494,6 +1494,26 @@
 }
 
 
+void CodeGenerator::SetTypeForStackSlot(Slot* slot, TypeInfo info) {
+  ASSERT(slot->type() == Slot::LOCAL || slot->type() == Slot::PARAMETER);
+  if (slot->type() == Slot::LOCAL) {
+    frame_->SetTypeForLocalAt(slot->index(), info);
+  } else {
+    frame_->SetTypeForParamAt(slot->index(), info);
+  }
+  if (FLAG_debug_code && info.IsSmi()) {
+    if (slot->type() == Slot::LOCAL) {
+      frame_->PushLocalAt(slot->index());
+    } else {
+      frame_->PushParameterAt(slot->index());
+    }
+    Result var = frame_->Pop();
+    var.ToRegister();
+    __ AbortIfNotSmi(var.reg(), "Non-smi value in smi-typed stack slot.");
+  }
+}
+
+
 void CodeGenerator::VisitForStatement(ForStatement* node) {
   ASSERT(!in_spilled_code());
   Comment cmnt(masm_, "[ ForStatement");
@@ -1587,6 +1607,17 @@
   }
 
   CheckStack();  // TODO(1222600): ignore if body contains calls.
+
+  // We know that the loop index is a smi if it is not modified in the
+  // loop body and it is checked against a constant limit in the loop
+  // condition.  In this case, we reset the static type information of the
+  // loop index to smi before compiling the body, the update expression, and
+  // the bottom check of the loop condition.
+  if (node->is_fast_smi_loop()) {
+    // Set number type of the loop variable to smi.
+    SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
+  }
+
   Visit(node->body());
 
   // If there is an update expression, compile it if necessary.
@@ -1606,6 +1637,13 @@
     }
   }
 
+  // Set the type of the loop variable to smi before compiling the test
+  // expression if we are in a fast smi loop condition.
+  if (node->is_fast_smi_loop() && has_valid_frame()) {
+    // Set number type of the loop variable to smi.
+    SetTypeForStackSlot(node->loop_variable()->slot(), TypeInfo::Smi());
+  }
+
   // Based on the condition analysis, compile the backward jump as
   // necessary.
   switch (info) {
@@ -4130,6 +4168,97 @@
 }
 
 
+void CodeGenerator::GenerateRegExpConstructResult(ZoneList<Expression*>* args) {
+  // No stub. This code only occurs a few times in regexp.js.
+  const int kMaxInlineLength = 100;
+  ASSERT_EQ(3, args->length());
+  Load(args->at(0));  // Size of array, smi.
+  Load(args->at(1));  // "index" property value.
+  Load(args->at(2));  // "input" property value.
+  {
+    VirtualFrame::SpilledScope spilled_scope;
+
+    Label slowcase;
+    Label done;
+    __ movq(r8, Operand(rsp, kPointerSize * 2));
+    __ JumpIfNotSmi(r8, &slowcase);
+    __ SmiToInteger32(rbx, r8);
+    __ cmpl(rbx, Immediate(kMaxInlineLength));
+    __ j(above, &slowcase);
+    // Smi-tagging is equivalent to multiplying by 2.
+    STATIC_ASSERT(kSmiTag == 0);
+    STATIC_ASSERT(kSmiTagSize == 1);
+    // Allocate RegExpResult followed by FixedArray with size in ebx.
+    // JSArray:   [Map][empty properties][Elements][Length-smi][index][input]
+    // Elements:  [Map][Length][..elements..]
+    __ AllocateInNewSpace(JSRegExpResult::kSize + FixedArray::kHeaderSize,
+                          times_pointer_size,
+                          rbx,  // In: Number of elements.
+                          rax,  // Out: Start of allocation (tagged).
+                          rcx,  // Out: End of allocation.
+                          rdx,  // Scratch register
+                          &slowcase,
+                          TAG_OBJECT);
+    // rax: Start of allocated area, object-tagged.
+    // rbx: Number of array elements as int32.
+    // r8: Number of array elements as smi.
+
+    // Set JSArray map to global.regexp_result_map().
+    __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_INDEX));
+    __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset));
+    __ movq(rdx, ContextOperand(rdx, Context::REGEXP_RESULT_MAP_INDEX));
+    __ movq(FieldOperand(rax, HeapObject::kMapOffset), rdx);
+
+    // Set empty properties FixedArray.
+    __ Move(FieldOperand(rax, JSObject::kPropertiesOffset),
+            Factory::empty_fixed_array());
+
+    // Set elements to point to FixedArray allocated right after the JSArray.
+    __ lea(rcx, Operand(rax, JSRegExpResult::kSize));
+    __ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);
+
+    // Set input, index and length fields from arguments.
+    __ pop(FieldOperand(rax, JSRegExpResult::kInputOffset));
+    __ pop(FieldOperand(rax, JSRegExpResult::kIndexOffset));
+    __ lea(rsp, Operand(rsp, kPointerSize));
+    __ movq(FieldOperand(rax, JSArray::kLengthOffset), r8);
+
+    // Fill out the elements FixedArray.
+    // rax: JSArray.
+    // rcx: FixedArray.
+    // rbx: Number of elements in array as int32.
+
+    // Set map.
+    __ Move(FieldOperand(rcx, HeapObject::kMapOffset),
+            Factory::fixed_array_map());
+    // Set length.
+    __ movq(FieldOperand(rcx, FixedArray::kLengthOffset), rbx);
+    // Fill contents of fixed-array with the-hole.
+    __ Move(rdx, Factory::the_hole_value());
+    __ lea(rcx, FieldOperand(rcx, FixedArray::kHeaderSize));
+    // Fill fixed array elements with hole.
+    // rax: JSArray.
+    // rbx: Number of elements in array that remains to be filled, as int32.
+    // rcx: Start of elements in FixedArray.
+    // rdx: the hole.
+    Label loop;
+    __ testl(rbx, rbx);
+    __ bind(&loop);
+    __ j(less_equal, &done);  // Jump if ecx is negative or zero.
+    __ subl(rbx, Immediate(1));
+    __ movq(Operand(rcx, rbx, times_pointer_size, 0), rdx);
+    __ jmp(&loop);
+
+    __ bind(&slowcase);
+    __ CallRuntime(Runtime::kRegExpConstructResult, 3);
+
+    __ bind(&done);
+  }
+  frame_->Forget(3);
+  frame_->Push(rax);
+}
+
+
 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
   ASSERT_EQ(args->length(), 1);
 
@@ -5112,14 +5241,28 @@
   ASSERT(cc == less || cc == equal || cc == greater_equal);
 
   // If either side is a constant smi, optimize the comparison.
-  bool left_side_constant_smi =
-      left_side.is_constant() && left_side.handle()->IsSmi();
-  bool right_side_constant_smi =
-      right_side.is_constant() && right_side.handle()->IsSmi();
-  bool left_side_constant_null =
-      left_side.is_constant() && left_side.handle()->IsNull();
-  bool right_side_constant_null =
-      right_side.is_constant() && right_side.handle()->IsNull();
+  bool left_side_constant_smi = false;
+  bool left_side_constant_null = false;
+  bool left_side_constant_1_char_string = false;
+  if (left_side.is_constant()) {
+    left_side_constant_smi = left_side.handle()->IsSmi();
+    left_side_constant_null = left_side.handle()->IsNull();
+    left_side_constant_1_char_string =
+        (left_side.handle()->IsString() &&
+         String::cast(*left_side.handle())->length() == 1 &&
+         String::cast(*left_side.handle())->IsAsciiRepresentation());
+  }
+  bool right_side_constant_smi = false;
+  bool right_side_constant_null = false;
+  bool right_side_constant_1_char_string = false;
+  if (right_side.is_constant()) {
+    right_side_constant_smi = right_side.handle()->IsSmi();
+    right_side_constant_null = right_side.handle()->IsNull();
+    right_side_constant_1_char_string =
+        (right_side.handle()->IsString() &&
+         String::cast(*right_side.handle())->length() == 1 &&
+         String::cast(*right_side.handle())->IsAsciiRepresentation());
+  }
 
   if (left_side_constant_smi || right_side_constant_smi) {
     if (left_side_constant_smi && right_side_constant_smi) {
@@ -5259,6 +5402,141 @@
       operand.Unuse();
       dest->Split(not_zero);
     }
+  } else if (left_side_constant_1_char_string ||
+             right_side_constant_1_char_string) {
+    if (left_side_constant_1_char_string && right_side_constant_1_char_string) {
+      // Trivial case, comparing two constants.
+      int left_value = String::cast(*left_side.handle())->Get(0);
+      int right_value = String::cast(*right_side.handle())->Get(0);
+      switch (cc) {
+        case less:
+          dest->Goto(left_value < right_value);
+          break;
+        case equal:
+          dest->Goto(left_value == right_value);
+          break;
+        case greater_equal:
+          dest->Goto(left_value >= right_value);
+          break;
+        default:
+          UNREACHABLE();
+      }
+    } else {
+      // Only one side is a constant 1 character string.
+      // If left side is a constant 1-character string, reverse the operands.
+      // Since one side is a constant string, conversion order does not matter.
+      if (left_side_constant_1_char_string) {
+        Result temp = left_side;
+        left_side = right_side;
+        right_side = temp;
+        cc = ReverseCondition(cc);
+        // This may reintroduce greater or less_equal as the value of cc.
+        // CompareStub and the inline code both support all values of cc.
+      }
+      // Implement comparison against a constant string, inlining the case
+      // where both sides are strings.
+      left_side.ToRegister();
+
+      // Here we split control flow to the stub call and inlined cases
+      // before finally splitting it to the control destination.  We use
+      // a jump target and branching to duplicate the virtual frame at
+      // the first split.  We manually handle the off-frame references
+      // by reconstituting them on the non-fall-through path.
+      JumpTarget is_not_string, is_string;
+      Register left_reg = left_side.reg();
+      Handle<Object> right_val = right_side.handle();
+      ASSERT(StringShape(String::cast(*right_val)).IsSymbol());
+      Condition is_smi = masm()->CheckSmi(left_reg);
+      is_not_string.Branch(is_smi, &left_side);
+      Result temp = allocator_->Allocate();
+      ASSERT(temp.is_valid());
+      __ movq(temp.reg(),
+              FieldOperand(left_reg, HeapObject::kMapOffset));
+      __ movzxbl(temp.reg(),
+                 FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
+      // If we are testing for equality then make use of the symbol shortcut.
+      // Check if the left hand side has the same type as the right hand
+      // side (which is always a symbol).
+      if (cc == equal) {
+        Label not_a_symbol;
+        ASSERT(kSymbolTag != 0);
+        // Ensure that no non-strings have the symbol bit set.
+        ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
+        __ testb(temp.reg(), Immediate(kIsSymbolMask));  // Test the symbol bit.
+        __ j(zero, &not_a_symbol);
+        // They are symbols, so do identity compare.
+        __ Cmp(left_reg, right_side.handle());
+        dest->true_target()->Branch(equal);
+        dest->false_target()->Branch(not_equal);
+        __ bind(&not_a_symbol);
+      }
+      // Call the compare stub if the left side is not a flat ascii string.
+      __ andb(temp.reg(),
+              Immediate(kIsNotStringMask |
+                        kStringRepresentationMask |
+                        kStringEncodingMask));
+      __ cmpb(temp.reg(),
+              Immediate(kStringTag | kSeqStringTag | kAsciiStringTag));
+      temp.Unuse();
+      is_string.Branch(equal, &left_side);
+
+      // Setup and call the compare stub.
+      is_not_string.Bind(&left_side);
+      CompareStub stub(cc, strict, kCantBothBeNaN);
+      Result result = frame_->CallStub(&stub, &left_side, &right_side);
+      result.ToRegister();
+      __ SmiCompare(result.reg(), Smi::FromInt(0));
+      result.Unuse();
+      dest->true_target()->Branch(cc);
+      dest->false_target()->Jump();
+
+      is_string.Bind(&left_side);
+      // left_side is a sequential ASCII string.
+      ASSERT(left_side.reg().is(left_reg));
+      right_side = Result(right_val);
+      Result temp2 = allocator_->Allocate();
+      ASSERT(temp2.is_valid());
+      // Test string equality and comparison.
+      if (cc == equal) {
+        Label comparison_done;
+        __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
+                Immediate(1));
+        __ j(not_equal, &comparison_done);
+        uint8_t char_value =
+            static_cast<uint8_t>(String::cast(*right_val)->Get(0));
+        __ cmpb(FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize),
+                Immediate(char_value));
+        __ bind(&comparison_done);
+      } else {
+        __ movl(temp2.reg(),
+                FieldOperand(left_side.reg(), String::kLengthOffset));
+        __ subl(temp2.reg(), Immediate(1));
+        Label comparison;
+        // If the length is 0 then the subtraction gave -1 which compares less
+        // than any character.
+        __ j(negative, &comparison);
+        // Otherwise load the first character.
+        __ movzxbl(temp2.reg(),
+                   FieldOperand(left_side.reg(), SeqAsciiString::kHeaderSize));
+        __ bind(&comparison);
+        // Compare the first character of the string with the
+        // constant 1-character string.
+        uint8_t char_value =
+            static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0));
+        __ cmpb(temp2.reg(), Immediate(char_value));
+        Label characters_were_different;
+        __ j(not_equal, &characters_were_different);
+        // If the first character is the same then the long string sorts after
+        // the short one.
+        __ cmpl(FieldOperand(left_side.reg(), String::kLengthOffset),
+               Immediate(1));
+        __ bind(&characters_were_different);
+      }
+      temp2.Unuse();
+      left_side.Unuse();
+      right_side.Unuse();
+      dest->Split(cc);
+    }
   } else {  // Neither side is a constant Smi or null.
     // If either side is a non-smi constant, skip the smi check.
     bool known_non_smi =
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 081a8a8..dff8dc2 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -582,6 +582,8 @@
   // Support for direct calls from JavaScript to native RegExp code.
   void GenerateRegExpExec(ZoneList<Expression*>* args);
 
+  void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
+
   // Fast support for number to string.
   void GenerateNumberToString(ZoneList<Expression*>* args);
 
@@ -611,6 +613,8 @@
   void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
   void CodeForSourcePosition(int pos);
 
+  void SetTypeForStackSlot(Slot* slot, TypeInfo info);
+
 #ifdef DEBUG
   // True if the registers are valid for entry to a block.  There should
   // be no frame-external references to (non-reserved) registers.
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 2781a84..2c47cf8 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -46,17 +46,17 @@
 
 
 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
-  movq(destination, Operand(r13, index << kPointerSizeLog2));
+  movq(destination, Operand(kRootRegister, index << kPointerSizeLog2));
 }
 
 
 void MacroAssembler::PushRoot(Heap::RootListIndex index) {
-  push(Operand(r13, index << kPointerSizeLog2));
+  push(Operand(kRootRegister, index << kPointerSizeLog2));
 }
 
 
 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
-  cmpq(with, Operand(r13, index << kPointerSizeLog2));
+  cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2));
 }
 
 
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index b5bb636..dabb764 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -37,6 +37,7 @@
 // a spare register). The register isn't callee save, and not used by the
 // function calling convention.
 static const Register kScratchRegister = { 10 };  // r10.
+static const Register kRootRegister = { 13 };     // r13
 
 // Convenience for platform-independent signatures.
 typedef Operand MemOperand;
diff --git a/src/x64/register-allocator-x64-inl.h b/src/x64/register-allocator-x64-inl.h
index d630b33..c7c18b3 100644
--- a/src/x64/register-allocator-x64-inl.h
+++ b/src/x64/register-allocator-x64-inl.h
@@ -38,7 +38,7 @@
 
 bool RegisterAllocator::IsReserved(Register reg) {
   return reg.is(rsp) || reg.is(rbp) || reg.is(rsi) ||
-      reg.is(kScratchRegister);
+      reg.is(kScratchRegister) || reg.is(kRootRegister);
 }
 
 
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 03b21a5..cd9a86d 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -1144,6 +1144,36 @@
 }
 
 
+Object* LoadStubCompiler::CompileLoadNonexistent(JSObject* object) {
+  // ----------- S t a t e -------------
+  //  -- rcx    : name
+  //  -- rsp[0] : return address
+  //  -- rsp[8] : receiver
+  // -----------------------------------
+  Label miss;
+
+  // Load receiver.
+  __ movq(rax, Operand(rsp, kPointerSize));
+
+  // Check the maps of the full prototype chain.
+  JSObject* last = object;
+  while (last->GetPrototype() != Heap::null_value()) {
+    last = JSObject::cast(last->GetPrototype());
+  }
+  CheckPrototypes(object, rax, last, rbx, rdx, Heap::empty_string(), &miss);
+
+  // Return undefined if maps of the full prototype chain is still the same.
+  __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
+  __ ret(0);
+
+  __ bind(&miss);
+  GenerateLoadMiss(masm(), Code::LOAD_IC);
+
+  // Return the generated code.
+  return GetCode(NONEXISTENT, Heap::empty_string());
+}
+
+
 Object* LoadStubCompiler::CompileLoadField(JSObject* object,
                                            JSObject* holder,
                                            int index,
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 4e4cf28..81d981e 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -95,7 +95,7 @@
   i::HandleScope scope;
   const char* aaa_str = "aaa";
   i::Handle<i::String> aaa_name = i::Factory::NewStringFromAscii(
-      i::Vector<const char>(aaa_str, strlen(aaa_str)));
+      i::Vector<const char>(aaa_str, i::StrLength(aaa_str)));
   processor.CodeCreateEvent(i::Logger::FUNCTION_TAG,
                             *aaa_name,
                             i::Heap::empty_string(),
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index bfadd20..41be8c0 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -821,19 +821,20 @@
   Page* page = Page::FromAddress(current_top);
   Address current_page = page->address();
   Address next_page = current_page + Page::kPageSize;
-  int bytes_to_page = next_page - current_top;
+  int bytes_to_page = static_cast<int>(next_page - current_top);
   if (bytes_to_page <= FixedArray::kHeaderSize) {
     // Alas, need to cross another page to be able to
     // put desired value.
     next_page += Page::kPageSize;
-    bytes_to_page = next_page - current_top;
+    bytes_to_page = static_cast<int>(next_page - current_top);
   }
   CHECK(bytes_to_page > FixedArray::kHeaderSize);
 
   int* is_normal_page_ptr = &Page::FromAddress(next_page)->is_normal_page;
   Address is_normal_page_addr = reinterpret_cast<Address>(is_normal_page_ptr);
 
-  int bytes_to_allocate = (is_normal_page_addr - current_top) + kPointerSize;
+  int bytes_to_allocate =
+      static_cast<int>(is_normal_page_addr - current_top) + kPointerSize;
 
   int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) /
       kPointerSize;
@@ -917,7 +918,7 @@
   }
 
   // Step 3: now allocate fixed array and JSObject to fill the whole new space.
-  int to_fill = *limit_addr - *top_addr - object_size;
+  int to_fill = static_cast<int>(*limit_addr - *top_addr - object_size);
   int fixed_array_len = LenFromSize(to_fill);
   CHECK(fixed_array_len < FixedArray::kMaxLength);
 
@@ -935,7 +936,7 @@
   // Create a reference to object in new space in jsobject.
   jsobject->FastPropertyAtPut(-1, array);
 
-  CHECK_EQ(0L, (*limit_addr - *top_addr));
+  CHECK_EQ(0, static_cast<int>(*limit_addr - *top_addr));
 
   // Step 4: clone jsobject, but force always allocate first to create a clone
   // in old pointer space.
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index aadb7d0..0e30092 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -347,38 +347,6 @@
 }
 
 
-TEST(StringConcatFlatten) {
-  InitializeVM();
-  v8::HandleScope handle_scope;
-
-  const char* stringA = "0123456789";
-  const char* stringB = "ABCDEFGHIJ";
-
-  v8::Local<v8::String> a = v8::String::New(stringA);
-  v8::Local<v8::String> b = v8::String::New(stringB);
-
-  v8::Local<v8::String> cons = v8::String::Concat(a, b);
-
-  i::Handle<i::String> str = v8::Utils::OpenHandle(*cons);
-  CHECK(!str->IsFlat());
-
-  cons->Flatten();
-
-  CHECK(str->IsFlat());
-
-  char buffer[21];
-  cons->WriteUtf8(buffer);
-
-  for (int i = 0; i < 10; i++) {
-    CHECK_EQ(stringA[i], buffer[i]);
-  }
-
-  for (int i = 0; i < 10; i++) {
-    CHECK_EQ(stringB[i], buffer[i + 10]);
-  }
-}
-
-
 TEST(ExternalShortStringAdd) {
   ZoneScope zone(DELETE_ON_EXIT);
 
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index a1a5821..f1c2462 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -163,6 +163,12 @@
   // Performance critical function which cannot afford type checks.
   "_CallFunction": true,
 
+  // Tries to allocate based on argument, and (correctly) throws
+  // out-of-memory if the request is too large. In practice, the
+  // size will be the number of captures of a RegExp.
+  "RegExpConstructResult": true,
+  "_RegExpConstructResult": true,
+
   // LiveEdit feature is under development currently and has fragile input.
   "LiveEditFindSharedFunctionInfosForScript": true,
   "LiveEditGatherCompileInfo": true,
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index bc795f3..9e4c069 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -128,7 +128,6 @@
 		89A88E250E71A6C20043BA31 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
 		89A88E260E71A6C90043BA31 /* top.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1900E719B8F00D62E90 /* top.cc */; };
 		89A88E270E71A6CB0043BA31 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
-		89A88E280E71A6CC0043BA31 /* usage-analyzer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1950E719B8F00D62E90 /* usage-analyzer.cc */; };
 		89A88E290E71A6CE0043BA31 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
 		89A88E2A0E71A6D00043BA31 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
 		89A88E2B0E71A6D10043BA31 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
@@ -189,7 +188,6 @@
 		89F23C790E78D5B2006B2466 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
 		89F23C7A0E78D5B2006B2466 /* top.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1900E719B8F00D62E90 /* top.cc */; };
 		89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1930E719B8F00D62E90 /* unicode.cc */; };
-		89F23C7C0E78D5B2006B2466 /* usage-analyzer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1950E719B8F00D62E90 /* usage-analyzer.cc */; };
 		89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1970E719B8F00D62E90 /* utils.cc */; };
 		89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1990E719B8F00D62E90 /* v8-counters.cc */; };
 		89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF19B0E719B8F00D62E90 /* v8.cc */; };
@@ -222,7 +220,27 @@
 		9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
 		9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
 		9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
-		9FBE03DE10BD409900F8BFBA /* fast-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */; };
+		9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
+		9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
+		9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
+		9FA38BB61175B2D200C4CD55 /* flow-graph.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA31175B2D200C4CD55 /* flow-graph.cc */; };
+		9FA38BB71175B2D200C4CD55 /* full-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */; };
+		9FA38BB81175B2D200C4CD55 /* liveedit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA91175B2D200C4CD55 /* liveedit.cc */; };
+		9FA38BB91175B2D200C4CD55 /* type-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BAE1175B2D200C4CD55 /* type-info.cc */; };
+		9FA38BBA1175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
+		9FA38BBB1175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
+		9FA38BBC1175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
+		9FA38BBD1175B2D200C4CD55 /* flow-graph.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA31175B2D200C4CD55 /* flow-graph.cc */; };
+		9FA38BBE1175B2D200C4CD55 /* full-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA51175B2D200C4CD55 /* full-codegen.cc */; };
+		9FA38BBF1175B2D200C4CD55 /* liveedit.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA91175B2D200C4CD55 /* liveedit.cc */; };
+		9FA38BC01175B2D200C4CD55 /* type-info.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BAE1175B2D200C4CD55 /* type-info.cc */; };
+		9FA38BC51175B2E500C4CD55 /* full-codegen-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */; };
+		9FA38BC61175B2E500C4CD55 /* jump-target-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC31175B2E500C4CD55 /* jump-target-ia32.cc */; };
+		9FA38BC71175B2E500C4CD55 /* virtual-frame-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC41175B2E500C4CD55 /* virtual-frame-ia32.cc */; };
+		9FA38BCE1175B30400C4CD55 /* assembler-thumb2.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BC91175B30400C4CD55 /* assembler-thumb2.cc */; };
+		9FA38BCF1175B30400C4CD55 /* full-codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */; };
+		9FA38BD01175B30400C4CD55 /* jump-target-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BCC1175B30400C4CD55 /* jump-target-arm.cc */; };
+		9FA38BD11175B30400C4CD55 /* virtual-frame-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BCD1175B30400C4CD55 /* virtual-frame-arm.cc */; };
 		9FBE03DF10BD409900F8BFBA /* fast-codegen.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */; };
 		9FBE03E210BD40EA00F8BFBA /* fast-codegen-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03E110BD40EA00F8BFBA /* fast-codegen-ia32.cc */; };
 		9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FBE03E410BD412600F8BFBA /* fast-codegen-arm.cc */; };
@@ -496,8 +514,6 @@
 		897FF1920E719B8F00D62E90 /* unicode-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "unicode-inl.h"; sourceTree = "<group>"; };
 		897FF1930E719B8F00D62E90 /* unicode.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = unicode.cc; sourceTree = "<group>"; };
 		897FF1940E719B8F00D62E90 /* unicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unicode.h; sourceTree = "<group>"; };
-		897FF1950E719B8F00D62E90 /* usage-analyzer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "usage-analyzer.cc"; sourceTree = "<group>"; };
-		897FF1960E719B8F00D62E90 /* usage-analyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "usage-analyzer.h"; sourceTree = "<group>"; };
 		897FF1970E719B8F00D62E90 /* utils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = utils.cc; sourceTree = "<group>"; };
 		897FF1980E719B8F00D62E90 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; };
 		897FF1990E719B8F00D62E90 /* v8-counters.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "v8-counters.cc"; sourceTree = "<group>"; };
@@ -575,6 +591,40 @@
 		9FA37332116DD9F000C4CD55 /* vm-state-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state-inl.h"; sourceTree = "<group>"; };
 		9FA37333116DD9F000C4CD55 /* vm-state.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "vm-state.cc"; sourceTree = "<group>"; };
 		9FA37334116DD9F000C4CD55 /* vm-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state.h"; sourceTree = "<group>"; };
+		9FA38B9B1175B2D200C4CD55 /* cached-powers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cached-powers.h"; sourceTree = "<group>"; };
+		9FA38B9C1175B2D200C4CD55 /* data-flow.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "data-flow.cc"; sourceTree = "<group>"; };
+		9FA38B9D1175B2D200C4CD55 /* data-flow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "data-flow.h"; sourceTree = "<group>"; };
+		9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "diy-fp.cc"; sourceTree = "<group>"; };
+		9FA38B9F1175B2D200C4CD55 /* diy-fp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "diy-fp.h"; sourceTree = "<group>"; };
+		9FA38BA01175B2D200C4CD55 /* double.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = double.h; sourceTree = "<group>"; };
+		9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fast-dtoa.cc"; sourceTree = "<group>"; };
+		9FA38BA21175B2D200C4CD55 /* fast-dtoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fast-dtoa.h"; sourceTree = "<group>"; };
+		9FA38BA31175B2D200C4CD55 /* flow-graph.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "flow-graph.cc"; sourceTree = "<group>"; };
+		9FA38BA41175B2D200C4CD55 /* flow-graph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "flow-graph.h"; sourceTree = "<group>"; };
+		9FA38BA51175B2D200C4CD55 /* full-codegen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "full-codegen.cc"; sourceTree = "<group>"; };
+		9FA38BA61175B2D200C4CD55 /* full-codegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "full-codegen.h"; sourceTree = "<group>"; };
+		9FA38BA71175B2D200C4CD55 /* jump-target-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "jump-target-inl.h"; sourceTree = "<group>"; };
+		9FA38BA81175B2D200C4CD55 /* jump-target-light-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "jump-target-light-inl.h"; sourceTree = "<group>"; };
+		9FA38BA91175B2D200C4CD55 /* liveedit.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = liveedit.cc; sourceTree = "<group>"; };
+		9FA38BAA1175B2D200C4CD55 /* liveedit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = liveedit.h; sourceTree = "<group>"; };
+		9FA38BAB1175B2D200C4CD55 /* powers-ten.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "powers-ten.h"; sourceTree = "<group>"; };
+		9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "splay-tree-inl.h"; sourceTree = "<group>"; };
+		9FA38BAD1175B2D200C4CD55 /* splay-tree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "splay-tree.h"; sourceTree = "<group>"; };
+		9FA38BAE1175B2D200C4CD55 /* type-info.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "type-info.cc"; sourceTree = "<group>"; };
+		9FA38BAF1175B2D200C4CD55 /* type-info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "type-info.h"; sourceTree = "<group>"; };
+		9FA38BB01175B2D200C4CD55 /* virtual-frame-heavy-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "virtual-frame-heavy-inl.h"; sourceTree = "<group>"; };
+		9FA38BB11175B2D200C4CD55 /* virtual-frame-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "virtual-frame-inl.h"; sourceTree = "<group>"; };
+		9FA38BB21175B2D200C4CD55 /* virtual-frame-light-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "virtual-frame-light-inl.h"; sourceTree = "<group>"; };
+		9FA38BC11175B2E500C4CD55 /* fast-codegen-ia32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "fast-codegen-ia32.h"; path = "ia32/fast-codegen-ia32.h"; sourceTree = "<group>"; };
+		9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "full-codegen-ia32.cc"; path = "ia32/full-codegen-ia32.cc"; sourceTree = "<group>"; };
+		9FA38BC31175B2E500C4CD55 /* jump-target-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "jump-target-ia32.cc"; path = "ia32/jump-target-ia32.cc"; sourceTree = "<group>"; };
+		9FA38BC41175B2E500C4CD55 /* virtual-frame-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "virtual-frame-ia32.cc"; path = "ia32/virtual-frame-ia32.cc"; sourceTree = "<group>"; };
+		9FA38BC81175B30400C4CD55 /* assembler-thumb2-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-thumb2-inl.h"; path = "arm/assembler-thumb2-inl.h"; sourceTree = "<group>"; };
+		9FA38BC91175B30400C4CD55 /* assembler-thumb2.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "assembler-thumb2.cc"; path = "arm/assembler-thumb2.cc"; sourceTree = "<group>"; };
+		9FA38BCA1175B30400C4CD55 /* assembler-thumb2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "assembler-thumb2.h"; path = "arm/assembler-thumb2.h"; sourceTree = "<group>"; };
+		9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "full-codegen-arm.cc"; path = "arm/full-codegen-arm.cc"; sourceTree = "<group>"; };
+		9FA38BCC1175B30400C4CD55 /* jump-target-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "jump-target-arm.cc"; path = "arm/jump-target-arm.cc"; sourceTree = "<group>"; };
+		9FA38BCD1175B30400C4CD55 /* virtual-frame-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "virtual-frame-arm.cc"; path = "arm/virtual-frame-arm.cc"; sourceTree = "<group>"; };
 		9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "fast-codegen.cc"; sourceTree = "<group>"; };
 		9FBE03DD10BD409900F8BFBA /* fast-codegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "fast-codegen.h"; sourceTree = "<group>"; };
 		9FBE03E110BD40EA00F8BFBA /* fast-codegen-ia32.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "fast-codegen-ia32.cc"; path = "ia32/fast-codegen-ia32.cc"; sourceTree = "<group>"; };
@@ -628,8 +678,8 @@
 		8915B8660E719336009C4E19 = {
 			isa = PBXGroup;
 			children = (
-				897FF0CF0E71996900D62E90 /* v8 */,
 				897FF1C00E719CB600D62E90 /* Products */,
+				897FF0CF0E71996900D62E90 /* v8 */,
 			);
 			sourceTree = "<group>";
 		};
@@ -637,8 +687,8 @@
 			isa = PBXGroup;
 			children = (
 				897FF0D10E71999E00D62E90 /* include */,
-				897FF0D00E71999800D62E90 /* src */,
 				897FF1B30E719BCE00D62E90 /* samples */,
+				897FF0D00E71999800D62E90 /* src */,
 				897FF1B40E719BE800D62E90 /* tools */,
 			);
 			name = v8;
@@ -649,9 +699,9 @@
 			isa = PBXGroup;
 			children = (
 				897FF0D70E719AB300D62E90 /* C++ */,
+				89A9C1630E71C8E300BE6CCA /* generated */,
 				897FF0D80E719ABA00D62E90 /* js */,
 				897FF0DE0E719B3400D62E90 /* third_party */,
-				89A9C1630E71C8E300BE6CCA /* generated */,
 			);
 			path = src;
 			sourceTree = "<group>";
@@ -669,6 +719,7 @@
 		897FF0D70E719AB300D62E90 /* C++ */ = {
 			isa = PBXGroup;
 			children = (
+				897FF1750E719B8F00D62E90 /* SConscript */,
 				897FF0F60E719B8F00D62E90 /* accessors.cc */,
 				897FF0F70E719B8F00D62E90 /* accessors.h */,
 				897FF0F80E719B8F00D62E90 /* allocation.cc */,
@@ -683,6 +734,9 @@
 				897FF1000E719B8F00D62E90 /* assembler-ia32-inl.h */,
 				897FF1010E719B8F00D62E90 /* assembler-ia32.cc */,
 				897FF1020E719B8F00D62E90 /* assembler-ia32.h */,
+				9FA38BC81175B30400C4CD55 /* assembler-thumb2-inl.h */,
+				9FA38BC91175B30400C4CD55 /* assembler-thumb2.cc */,
+				9FA38BCA1175B30400C4CD55 /* assembler-thumb2.h */,
 				897FF1030E719B8F00D62E90 /* assembler.cc */,
 				897FF1040E719B8F00D62E90 /* assembler.h */,
 				897FF1050E719B8F00D62E90 /* ast.cc */,
@@ -694,6 +748,7 @@
 				897FF10B0E719B8F00D62E90 /* builtins.cc */,
 				897FF10C0E719B8F00D62E90 /* builtins.h */,
 				89A15C630EE4661A00B48DEB /* bytecodes-irregexp.h */,
+				9FA38B9B1175B2D200C4CD55 /* cached-powers.h */,
 				897FF10D0E719B8F00D62E90 /* char-predicates-inl.h */,
 				897FF10E0E719B8F00D62E90 /* char-predicates.h */,
 				897FF10F0E719B8F00D62E90 /* checks.cc */,
@@ -728,36 +783,46 @@
 				897FF1220E719B8F00D62E90 /* counters.h */,
 				897FF1230E719B8F00D62E90 /* cpu-arm.cc */,
 				897FF1240E719B8F00D62E90 /* cpu-ia32.cc */,
-				897FF1250E719B8F00D62E90 /* cpu.h */,
 				9F2B37231152CEA0007CDAF4 /* cpu-profiler-inl.h */,
 				9F2B37241152CEA0007CDAF4 /* cpu-profiler.cc */,
 				9F2B37251152CEA0007CDAF4 /* cpu-profiler.h */,
+				897FF1250E719B8F00D62E90 /* cpu.h */,
+				9FA38B9C1175B2D200C4CD55 /* data-flow.cc */,
+				9FA38B9D1175B2D200C4CD55 /* data-flow.h */,
 				893A722A0F7B4A3200303DD2 /* dateparser-inl.h */,
 				897FF1260E719B8F00D62E90 /* dateparser.cc */,
 				897FF1270E719B8F00D62E90 /* dateparser.h */,
+				8956B6CD0F5D86570033B5A2 /* debug-agent.cc */,
+				8956B6CE0F5D86570033B5A2 /* debug-agent.h */,
 				898BD20C0EF6CC850068B00A /* debug-arm.cc */,
 				898BD20D0EF6CC850068B00A /* debug-ia32.cc */,
 				897FF1280E719B8F00D62E90 /* debug.cc */,
 				897FF1290E719B8F00D62E90 /* debug.h */,
-				8956B6CD0F5D86570033B5A2 /* debug-agent.cc */,
-				8956B6CE0F5D86570033B5A2 /* debug-agent.h */,
 				897FF12A0E719B8F00D62E90 /* disasm-arm.cc */,
 				897FF12B0E719B8F00D62E90 /* disasm-ia32.cc */,
 				897FF12C0E719B8F00D62E90 /* disasm.h */,
 				897FF12D0E719B8F00D62E90 /* disassembler.cc */,
 				897FF12E0E719B8F00D62E90 /* disassembler.h */,
+				9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */,
+				9FA38B9F1175B2D200C4CD55 /* diy-fp.h */,
+				9FA38BA01175B2D200C4CD55 /* double.h */,
 				897FF12F0E719B8F00D62E90 /* dtoa-config.c */,
 				897FF1300E719B8F00D62E90 /* execution.cc */,
 				897FF1310E719B8F00D62E90 /* execution.h */,
 				897FF1320E719B8F00D62E90 /* factory.cc */,
 				897FF1330E719B8F00D62E90 /* factory.h */,
-				9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */,
-				9FBE03DD10BD409900F8BFBA /* fast-codegen.h */,
 				9FBE03E410BD412600F8BFBA /* fast-codegen-arm.cc */,
 				9FBE03E110BD40EA00F8BFBA /* fast-codegen-ia32.cc */,
+				9FA38BC11175B2E500C4CD55 /* fast-codegen-ia32.h */,
+				9FBE03DC10BD409900F8BFBA /* fast-codegen.cc */,
+				9FBE03DD10BD409900F8BFBA /* fast-codegen.h */,
+				9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */,
+				9FA38BA21175B2D200C4CD55 /* fast-dtoa.h */,
 				89471C7F0EB23EE400B6874B /* flag-definitions.h */,
 				897FF1350E719B8F00D62E90 /* flags.cc */,
 				897FF1360E719B8F00D62E90 /* flags.h */,
+				9FA38BA31175B2D200C4CD55 /* flow-graph.cc */,
+				9FA38BA41175B2D200C4CD55 /* flow-graph.h */,
 				8981F5FE1010500F00D1520E /* frame-element.cc */,
 				8981F5FF1010500F00D1520E /* frame-element.h */,
 				897FF1370E719B8F00D62E90 /* frames-arm.cc */,
@@ -767,6 +832,10 @@
 				897FF13B0E719B8F00D62E90 /* frames-inl.h */,
 				897FF13C0E719B8F00D62E90 /* frames.cc */,
 				897FF13D0E719B8F00D62E90 /* frames.h */,
+				9FA38BCB1175B30400C4CD55 /* full-codegen-arm.cc */,
+				9FA38BC21175B2E500C4CD55 /* full-codegen-ia32.cc */,
+				9FA38BA51175B2D200C4CD55 /* full-codegen.cc */,
+				9FA38BA61175B2D200C4CD55 /* full-codegen.h */,
 				9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */,
 				9F92FAA80F8F28AD0089F02C /* func-name-inferrer.h */,
 				897FF13E0E719B8F00D62E90 /* global-handles.cc */,
@@ -778,10 +847,10 @@
 				897FF1440E719B8F00D62E90 /* hashmap.cc */,
 				897FF1450E719B8F00D62E90 /* hashmap.h */,
 				897FF1460E719B8F00D62E90 /* heap-inl.h */,
-				897FF1470E719B8F00D62E90 /* heap.cc */,
-				897FF1480E719B8F00D62E90 /* heap.h */,
 				9F11D99E105AF0A300EBE5B2 /* heap-profiler.cc */,
 				9F11D99F105AF0A300EBE5B2 /* heap-profiler.h */,
+				897FF1470E719B8F00D62E90 /* heap.cc */,
+				897FF1480E719B8F00D62E90 /* heap.h */,
 				897FF1490E719B8F00D62E90 /* ic-arm.cc */,
 				897FF14A0E719B8F00D62E90 /* ic-ia32.cc */,
 				897FF14B0E719B8F00D62E90 /* ic-inl.h */,
@@ -791,22 +860,28 @@
 				89A15C670EE4665300B48DEB /* interpreter-irregexp.h */,
 				897FF14E0E719B8F00D62E90 /* jsregexp.cc */,
 				897FF14F0E719B8F00D62E90 /* jsregexp.h */,
+				9FA38BCC1175B30400C4CD55 /* jump-target-arm.cc */,
 				895FA720107FFB15006F39D4 /* jump-target-heavy-inl.h */,
 				895FA720107FFB15006F39D4 /* jump-target-heavy-inl.h */,
 				895FA720107FFB15006F39D4 /* jump-target-heavy-inl.h */,
-				58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
-				58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
 				58950D4F0F55514900F3E8BA /* jump-target-heavy.cc */,
 				58950D4F0F55514900F3E8BA /* jump-target-heavy.cc */,
+				9FA38BC31175B2E500C4CD55 /* jump-target-ia32.cc */,
+				9FA38BA71175B2D200C4CD55 /* jump-target-inl.h */,
+				9FA38BA81175B2D200C4CD55 /* jump-target-light-inl.h */,
+				58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
+				58950D4E0F55514900F3E8BA /* jump-target-light.cc */,
 				58950D500F55514900F3E8BA /* jump-target.cc */,
 				58950D510F55514900F3E8BA /* jump-target.h */,
 				897FF1500E719B8F00D62E90 /* list-inl.h */,
 				897FF1510E719B8F00D62E90 /* list.h */,
-				897FF1520E719B8F00D62E90 /* log.cc */,
-				897FF1530E719B8F00D62E90 /* log.h */,
+				9FA38BA91175B2D200C4CD55 /* liveedit.cc */,
+				9FA38BAA1175B2D200C4CD55 /* liveedit.h */,
 				22A76C900FF259E600FDC694 /* log-inl.h */,
 				9F4B7B870FCC877A00DC4117 /* log-utils.cc */,
 				9F4B7B880FCC877A00DC4117 /* log-utils.h */,
+				897FF1520E719B8F00D62E90 /* log.cc */,
+				897FF1530E719B8F00D62E90 /* log.h */,
 				897FF1540E719B8F00D62E90 /* macro-assembler-arm.cc */,
 				897FF1550E719B8F00D62E90 /* macro-assembler-arm.h */,
 				897FF1560E719B8F00D62E90 /* macro-assembler-ia32.cc */,
@@ -834,6 +909,7 @@
 				893A72230F7B0FF200303DD2 /* platform-posix.cc */,
 				897FF1690E719B8F00D62E90 /* platform-win32.cc */,
 				897FF16A0E719B8F00D62E90 /* platform.h */,
+				9FA38BAB1175B2D200C4CD55 /* powers-ten.h */,
 				897FF16B0E719B8F00D62E90 /* prettyprinter.cc */,
 				897FF16C0E719B8F00D62E90 /* prettyprinter.h */,
 				9F73E3AE114E61A100F84A5A /* profile-generator-inl.h */,
@@ -869,7 +945,6 @@
 				897FF1720E719B8F00D62E90 /* runtime.h */,
 				897FF1730E719B8F00D62E90 /* scanner.cc */,
 				897FF1740E719B8F00D62E90 /* scanner.h */,
-				897FF1750E719B8F00D62E90 /* SConscript */,
 				897FF1760E719B8F00D62E90 /* scopeinfo.cc */,
 				897FF1770E719B8F00D62E90 /* scopeinfo.h */,
 				897FF1780E719B8F00D62E90 /* scopes.cc */,
@@ -888,6 +963,8 @@
 				897FF1850E719B8F00D62E90 /* spaces-inl.h */,
 				897FF1860E719B8F00D62E90 /* spaces.cc */,
 				897FF1870E719B8F00D62E90 /* spaces.h */,
+				9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */,
+				9FA38BAD1175B2D200C4CD55 /* splay-tree.h */,
 				897FF1880E719B8F00D62E90 /* string-stream.cc */,
 				897FF1890E719B8F00D62E90 /* string-stream.h */,
 				897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */,
@@ -898,11 +975,11 @@
 				897FF18F0E719B8F00D62E90 /* token.h */,
 				897FF1900E719B8F00D62E90 /* top.cc */,
 				897FF1910E719B8F00D62E90 /* top.h */,
+				9FA38BAE1175B2D200C4CD55 /* type-info.cc */,
+				9FA38BAF1175B2D200C4CD55 /* type-info.h */,
 				897FF1920E719B8F00D62E90 /* unicode-inl.h */,
 				897FF1930E719B8F00D62E90 /* unicode.cc */,
 				897FF1940E719B8F00D62E90 /* unicode.h */,
-				897FF1950E719B8F00D62E90 /* usage-analyzer.cc */,
-				897FF1960E719B8F00D62E90 /* usage-analyzer.h */,
 				897FF1970E719B8F00D62E90 /* utils.cc */,
 				897FF1980E719B8F00D62E90 /* utils.h */,
 				897FF1990E719B8F00D62E90 /* v8-counters.cc */,
@@ -915,12 +992,17 @@
 				897FF1A00E719B8F00D62E90 /* variables.h */,
 				897FF32F0FAA0ED200136CF6 /* version.cc */,
 				897FF3300FAA0ED200136CF6 /* version.h */,
-				58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
-				58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
+				9FA38BCD1175B30400C4CD55 /* virtual-frame-arm.cc */,
 				58950D570F55514900F3E8BA /* virtual-frame-arm.h */,
+				9FA38BB01175B2D200C4CD55 /* virtual-frame-heavy-inl.h */,
 				58950D580F55514900F3E8BA /* virtual-frame-heavy.cc */,
 				58950D580F55514900F3E8BA /* virtual-frame-heavy.cc */,
+				9FA38BC41175B2E500C4CD55 /* virtual-frame-ia32.cc */,
 				58950D590F55514900F3E8BA /* virtual-frame-ia32.h */,
+				9FA38BB11175B2D200C4CD55 /* virtual-frame-inl.h */,
+				9FA38BB21175B2D200C4CD55 /* virtual-frame-light-inl.h */,
+				58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
+				58950D560F55514900F3E8BA /* virtual-frame-light.cc */,
 				58950D5A0F55514900F3E8BA /* virtual-frame.cc */,
 				58950D5B0F55514900F3E8BA /* virtual-frame.h */,
 				9FA37332116DD9F000C4CD55 /* vm-state-inl.h */,
@@ -973,10 +1055,10 @@
 		897FF1B30E719BCE00D62E90 /* samples */ = {
 			isa = PBXGroup;
 			children = (
-				89A15C910EE46A1700B48DEB /* d8-readline.cc */,
 				893988150F2A3686007D5254 /* d8-debug.cc */,
 				893A72320F7B4AD700303DD2 /* d8-debug.h */,
 				89FB0E360F8E531900B04B3C /* d8-posix.cc */,
+				89A15C910EE46A1700B48DEB /* d8-readline.cc */,
 				89FB0E370F8E531900B04B3C /* d8-windows.cc */,
 				89A15C920EE46A1700B48DEB /* d8.cc */,
 				89A15C930EE46A1700B48DEB /* d8.h */,
@@ -999,11 +1081,11 @@
 		897FF1C00E719CB600D62E90 /* Products */ = {
 			isa = PBXGroup;
 			children = (
-				8970F2F00E719FB2006AE7B5 /* libv8.a */,
 				897F767A0E71B4CC007ACF34 /* v8_shell */,
-				89F23C870E78D5B2006B2466 /* libv8-arm.a */,
-				89F23C950E78D5B6006B2466 /* v8_shell-arm */,
 				8939880B0F2A35FA007D5254 /* v8_shell */,
+				89F23C950E78D5B6006B2466 /* v8_shell-arm */,
+				89F23C870E78D5B2006B2466 /* libv8-arm.a */,
+				8970F2F00E719FB2006AE7B5 /* libv8.a */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -1154,7 +1236,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-delay.js\"\\\n\" mirror-delay.js\"\\\n\" date-delay.js\"\\\n\" json-delay.js\"\\\n\" regexp-delay.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"${LIBRARIES_EMPTY_CC}.new\" \\\n  \"CORE\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n  rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
+			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-debugger.js\"\\\n\" liveedit-debugger.js\"\\\n\" mirror-debugger.js\"\\\n\" date.js\"\\\n\" json.js\"\\\n\" regexp.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"${LIBRARIES_EMPTY_CC}.new\" \\\n  \"CORE\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n  rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
 		};
 		89F23C3D0E78D5B2006B2466 /* ShellScript */ = {
 			isa = PBXShellScriptBuildPhase;
@@ -1167,7 +1249,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-delay.js\"\\\n\" mirror-delay.js\"\\\n\" date-delay.js\"\\\n\" json-delay.js\"\\\n\" regexp-delay.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"${LIBRARIES_EMPTY_CC}.new\" \\\n  \"CORE\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n  rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
+			shellScript = "set -ex\nJS_FILES=\"runtime.js\"\\\n\" v8natives.js\"\\\n\" array.js\"\\\n\" string.js\"\\\n\" uri.js\"\\\n\" math.js\"\\\n\" messages.js\"\\\n\" apinatives.js\"\\\n\" debug-debugger.js\"\\\n\" liveedit-debugger.js\"\\\n\" mirror-debugger.js\"\\\n\" date.js\"\\\n\" json.js\"\\\n\" regexp.js\"\\\n\" macros.py\"\n\nV8ROOT=\"${SRCROOT}/..\"\n\nSRC_DIR=\"${V8ROOT}/src\"\n\nNATIVE_JS_FILES=\"\"\n\nfor i in ${JS_FILES} ; do\n  NATIVE_JS_FILES+=\"${SRC_DIR}/${i} \"\ndone\n\nV8_GENERATED_SOURCES_DIR=\"${CONFIGURATION_TEMP_DIR}/generated\"\nmkdir -p \"${V8_GENERATED_SOURCES_DIR}\"\n\nLIBRARIES_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries.cc\"\nLIBRARIES_EMPTY_CC=\"${V8_GENERATED_SOURCES_DIR}/libraries-empty.cc\"\n\npython \"${V8ROOT}/tools/js2c.py\" \\\n  \"${LIBRARIES_CC}.new\" \\\n  \"${LIBRARIES_EMPTY_CC}.new\" \\\n  \"CORE\" \\\n  ${NATIVE_JS_FILES}\n\n# Only use the new files if they're different from the existing files (if any),\n# preserving the existing files' timestamps when there are no changes.  This\n# minimizes unnecessary build activity for a no-change build.\n\nif ! diff -q \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_CC}.new\" \"${LIBRARIES_CC}\"\nelse\n  rm \"${LIBRARIES_CC}.new\"\nfi\n\nif ! diff -q \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\" >& /dev/null ; then\n  mv \"${LIBRARIES_EMPTY_CC}.new\" \"${LIBRARIES_EMPTY_CC}\"\nelse\n  rm \"${LIBRARIES_EMPTY_CC}.new\"\nfi\n";
 		};
 /* End PBXShellScriptBuildPhase section */
 
@@ -1176,10 +1258,10 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				8939880D0F2A362A007D5254 /* d8.cc in Sources */,
 				893988160F2A3688007D5254 /* d8-debug.cc in Sources */,
 				893988330F2A3B8F007D5254 /* d8-js.cc in Sources */,
 				89FB0E3A0F8E533F00B04B3C /* d8-posix.cc in Sources */,
+				8939880D0F2A362A007D5254 /* d8.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1197,6 +1279,7 @@
 				89A88DF40E71A6160043BA31 /* builtins-ia32.cc in Sources */,
 				89A88DF50E71A6170043BA31 /* builtins.cc in Sources */,
 				89A88DF60E71A61C0043BA31 /* checks.cc in Sources */,
+				9F2B3712114FF62D007CDAF4 /* circular-queue.cc in Sources */,
 				893CCE640E71D83700357A03 /* code-stubs.cc in Sources */,
 				89A88DF70E71A6240043BA31 /* codegen-ia32.cc in Sources */,
 				89A88DF80E71A6260043BA31 /* codegen.cc in Sources */,
@@ -1206,31 +1289,44 @@
 				89A88DFB0E71A6440043BA31 /* conversions.cc in Sources */,
 				89A88DFC0E71A6460043BA31 /* counters.cc in Sources */,
 				89A88DFD0E71A6470043BA31 /* cpu-ia32.cc in Sources */,
+				9F2B37271152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+				9FA38BBA1175B2D200C4CD55 /* data-flow.cc in Sources */,
 				89A88DFE0E71A6480043BA31 /* dateparser.cc in Sources */,
 				8956B6CF0F5D86730033B5A2 /* debug-agent.cc in Sources */,
 				898BD20E0EF6CC930068B00A /* debug-ia32.cc in Sources */,
 				89A88DFF0E71A6530043BA31 /* debug.cc in Sources */,
 				89A88E000E71A6540043BA31 /* disasm-ia32.cc in Sources */,
 				89A88E010E71A6550043BA31 /* disassembler.cc in Sources */,
+				9FA38BBB1175B2D200C4CD55 /* diy-fp.cc in Sources */,
 				89A88E020E71A65A0043BA31 /* dtoa-config.c in Sources */,
 				89A88E030E71A65B0043BA31 /* execution.cc in Sources */,
 				89A88E040E71A65D0043BA31 /* factory.cc in Sources */,
+				9FBE03E210BD40EA00F8BFBA /* fast-codegen-ia32.cc in Sources */,
+				9FA38BBC1175B2D200C4CD55 /* fast-dtoa.cc in Sources */,
 				89A88E050E71A65D0043BA31 /* flags.cc in Sources */,
+				9FA38BBD1175B2D200C4CD55 /* flow-graph.cc in Sources */,
+				8981F6001010501900D1520E /* frame-element.cc in Sources */,
 				89A88E060E71A6600043BA31 /* frames-ia32.cc in Sources */,
 				89A88E070E71A6610043BA31 /* frames.cc in Sources */,
+				9FA38BC51175B2E500C4CD55 /* full-codegen-ia32.cc in Sources */,
+				9FA38BBE1175B2D200C4CD55 /* full-codegen.cc in Sources */,
 				9F92FAA90F8F28AD0089F02C /* func-name-inferrer.cc in Sources */,
 				89A88E080E71A6620043BA31 /* global-handles.cc in Sources */,
 				89A88E090E71A6640043BA31 /* handles.cc in Sources */,
 				89A88E0A0E71A6650043BA31 /* hashmap.cc in Sources */,
+				9F11D9A0105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
 				89A88E0B0E71A66C0043BA31 /* heap.cc in Sources */,
 				89A88E0C0E71A66D0043BA31 /* ic-ia32.cc in Sources */,
 				89A88E0D0E71A66E0043BA31 /* ic.cc in Sources */,
 				89A15C850EE4678B00B48DEB /* interpreter-irregexp.cc in Sources */,
 				89A88E0E0E71A66F0043BA31 /* jsregexp.cc in Sources */,
+				58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
+				58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
+				9FA38BC61175B2E500C4CD55 /* jump-target-ia32.cc in Sources */,
 				58950D5E0F55519800F3E8BA /* jump-target.cc in Sources */,
-				58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
-				58950D5F0F55519D00F3E8BA /* jump-target-heavy.cc in Sources */,
 				8900116C0E71CA2300F91F35 /* libraries.cc in Sources */,
+				9FA38BBF1175B2D200C4CD55 /* liveedit.cc in Sources */,
+				9F4B7B890FCC877A00DC4117 /* log-utils.cc in Sources */,
 				89A88E0F0E71A6740043BA31 /* log.cc in Sources */,
 				89A88E100E71A6770043BA31 /* macro-assembler-ia32.cc in Sources */,
 				89A88E110E71A6780043BA31 /* mark-compact.cc in Sources */,
@@ -1239,9 +1335,10 @@
 				89A88E140E71A6870043BA31 /* objects.cc in Sources */,
 				9FC86ABD0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */,
 				89A88E150E71A68C0043BA31 /* parser.cc in Sources */,
-				893A72240F7B101400303DD2 /* platform-posix.cc in Sources */,
 				89A88E160E71A68E0043BA31 /* platform-macos.cc in Sources */,
+				893A72240F7B101400303DD2 /* platform-posix.cc in Sources */,
 				89A88E170E71A6950043BA31 /* prettyprinter.cc in Sources */,
+				9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */,
 				89A88E180E71A6960043BA31 /* property.cc in Sources */,
 				89A15C7B0EE466EB00B48DEB /* regexp-macro-assembler-ia32.cc in Sources */,
 				89A15C830EE4675E00B48DEB /* regexp-macro-assembler-irregexp.cc in Sources */,
@@ -1264,27 +1361,20 @@
 				89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */,
 				89A88E250E71A6C20043BA31 /* token.cc in Sources */,
 				89A88E260E71A6C90043BA31 /* top.cc in Sources */,
+				9FA38BC01175B2D200C4CD55 /* type-info.cc in Sources */,
 				89A88E270E71A6CB0043BA31 /* unicode.cc in Sources */,
-				89A88E280E71A6CC0043BA31 /* usage-analyzer.cc in Sources */,
 				89A88E290E71A6CE0043BA31 /* utils.cc in Sources */,
 				89A88E2A0E71A6D00043BA31 /* v8-counters.cc in Sources */,
 				89A88E2B0E71A6D10043BA31 /* v8.cc in Sources */,
 				89A88E2C0E71A6D20043BA31 /* v8threads.cc in Sources */,
 				89A88E2D0E71A6D50043BA31 /* variables.cc in Sources */,
 				89B933AF0FAA0F9600201304 /* version.cc in Sources */,
-				58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
-				58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
 				58950D670F5551C400F3E8BA /* virtual-frame-heavy.cc in Sources */,
-				89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */,
-				9F4B7B890FCC877A00DC4117 /* log-utils.cc in Sources */,
-				8981F6001010501900D1520E /* frame-element.cc in Sources */,
-				9F11D9A0105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
-				9FBE03DE10BD409900F8BFBA /* fast-codegen.cc in Sources */,
-				9FBE03E210BD40EA00F8BFBA /* fast-codegen-ia32.cc in Sources */,
-				9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */,
-				9F2B3712114FF62D007CDAF4 /* circular-queue.cc in Sources */,
-				9F2B37271152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+				9FA38BC71175B2E500C4CD55 /* virtual-frame-ia32.cc in Sources */,
+				58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
+				58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
 				9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */,
+				89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1304,12 +1394,14 @@
 				89F23C400E78D5B2006B2466 /* allocation.cc in Sources */,
 				89F23C410E78D5B2006B2466 /* api.cc in Sources */,
 				89F23C970E78D5E3006B2466 /* assembler-arm.cc in Sources */,
+				9FA38BCE1175B30400C4CD55 /* assembler-thumb2.cc in Sources */,
 				89F23C430E78D5B2006B2466 /* assembler.cc in Sources */,
 				89F23C440E78D5B2006B2466 /* ast.cc in Sources */,
 				89F23C450E78D5B2006B2466 /* bootstrapper.cc in Sources */,
 				89F23C980E78D5E7006B2466 /* builtins-arm.cc in Sources */,
 				89F23C470E78D5B2006B2466 /* builtins.cc in Sources */,
 				89F23C480E78D5B2006B2466 /* checks.cc in Sources */,
+				9F2B3711114FF62D007CDAF4 /* circular-queue.cc in Sources */,
 				89F23C490E78D5B2006B2466 /* code-stubs.cc in Sources */,
 				89F23C990E78D5E9006B2466 /* codegen-arm.cc in Sources */,
 				89F23C4B0E78D5B2006B2466 /* codegen.cc in Sources */,
@@ -1320,31 +1412,45 @@
 				89F23C4E0E78D5B2006B2466 /* conversions.cc in Sources */,
 				89F23C4F0E78D5B2006B2466 /* counters.cc in Sources */,
 				89F23C9A0E78D5EC006B2466 /* cpu-arm.cc in Sources */,
+				9F2B37261152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+				9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */,
 				89F23C510E78D5B2006B2466 /* dateparser.cc in Sources */,
 				894599A30F5D8729008DA8FB /* debug-agent.cc in Sources */,
 				898BD20F0EF6CC9A0068B00A /* debug-arm.cc in Sources */,
 				89F23C520E78D5B2006B2466 /* debug.cc in Sources */,
 				89F23C9B0E78D5EE006B2466 /* disasm-arm.cc in Sources */,
 				89F23C540E78D5B2006B2466 /* disassembler.cc in Sources */,
+				9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */,
 				89F23C550E78D5B2006B2466 /* dtoa-config.c in Sources */,
 				89F23C560E78D5B2006B2466 /* execution.cc in Sources */,
 				89F23C570E78D5B2006B2466 /* factory.cc in Sources */,
+				9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */,
+				9FBE03DF10BD409900F8BFBA /* fast-codegen.cc in Sources */,
+				9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */,
 				89F23C580E78D5B2006B2466 /* flags.cc in Sources */,
+				9FA38BB61175B2D200C4CD55 /* flow-graph.cc in Sources */,
+				8981F6011010502800D1520E /* frame-element.cc in Sources */,
 				89F23C9C0E78D5F1006B2466 /* frames-arm.cc in Sources */,
 				89F23C5A0E78D5B2006B2466 /* frames.cc in Sources */,
+				9FA38BCF1175B30400C4CD55 /* full-codegen-arm.cc in Sources */,
+				9FA38BB71175B2D200C4CD55 /* full-codegen.cc in Sources */,
 				9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */,
 				89F23C5B0E78D5B2006B2466 /* global-handles.cc in Sources */,
 				89F23C5C0E78D5B2006B2466 /* handles.cc in Sources */,
 				89F23C5D0E78D5B2006B2466 /* hashmap.cc in Sources */,
+				9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
 				89F23C5E0E78D5B2006B2466 /* heap.cc in Sources */,
 				89F23C9D0E78D5FB006B2466 /* ic-arm.cc in Sources */,
 				89F23C600E78D5B2006B2466 /* ic.cc in Sources */,
 				890A13FE0EE9C47F00E49346 /* interpreter-irregexp.cc in Sources */,
 				89F23C610E78D5B2006B2466 /* jsregexp.cc in Sources */,
+				9FA38BD01175B30400C4CD55 /* jump-target-arm.cc in Sources */,
+				58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
+				58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
 				58950D600F5551A300F3E8BA /* jump-target.cc in Sources */,
-				58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
-				58950D610F5551A400F3E8BA /* jump-target-light.cc in Sources */,
 				89F23C620E78D5B2006B2466 /* libraries.cc in Sources */,
+				9FA38BB81175B2D200C4CD55 /* liveedit.cc in Sources */,
+				9F4B7B8A0FCC877A00DC4117 /* log-utils.cc in Sources */,
 				89F23C630E78D5B2006B2466 /* log.cc in Sources */,
 				89F23C9E0E78D5FD006B2466 /* macro-assembler-arm.cc in Sources */,
 				89F23C650E78D5B2006B2466 /* mark-compact.cc in Sources */,
@@ -1353,17 +1459,18 @@
 				89F23C680E78D5B2006B2466 /* objects.cc in Sources */,
 				9FC86ABE0F5FEDAC00F22668 /* oprofile-agent.cc in Sources */,
 				89F23C690E78D5B2006B2466 /* parser.cc in Sources */,
-				893A72250F7B101B00303DD2 /* platform-posix.cc in Sources */,
 				89F23C6A0E78D5B2006B2466 /* platform-macos.cc in Sources */,
+				893A72250F7B101B00303DD2 /* platform-posix.cc in Sources */,
 				89F23C6B0E78D5B2006B2466 /* prettyprinter.cc in Sources */,
+				9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */,
 				89F23C6C0E78D5B2006B2466 /* property.cc in Sources */,
 				890A14010EE9C4B000E49346 /* regexp-macro-assembler-arm.cc in Sources */,
 				890A14020EE9C4B400E49346 /* regexp-macro-assembler-irregexp.cc in Sources */,
 				890A14030EE9C4B500E49346 /* regexp-macro-assembler-tracer.cc in Sources */,
 				890A14040EE9C4B700E49346 /* regexp-macro-assembler.cc in Sources */,
 				8944AD110F1D4D570028D560 /* regexp-stack.cc in Sources */,
-				58950D640F5551B500F3E8BA /* register-allocator.cc in Sources */,
 				58950D650F5551B600F3E8BA /* register-allocator-arm.cc in Sources */,
+				58950D640F5551B500F3E8BA /* register-allocator.cc in Sources */,
 				89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */,
 				89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */,
 				89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */,
@@ -1379,27 +1486,20 @@
 				89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */,
 				89F23C790E78D5B2006B2466 /* token.cc in Sources */,
 				89F23C7A0E78D5B2006B2466 /* top.cc in Sources */,
+				9FA38BB91175B2D200C4CD55 /* type-info.cc in Sources */,
 				89F23C7B0E78D5B2006B2466 /* unicode.cc in Sources */,
-				89F23C7C0E78D5B2006B2466 /* usage-analyzer.cc in Sources */,
 				89F23C7D0E78D5B2006B2466 /* utils.cc in Sources */,
 				89F23C7E0E78D5B2006B2466 /* v8-counters.cc in Sources */,
 				89F23C7F0E78D5B2006B2466 /* v8.cc in Sources */,
 				89F23C800E78D5B2006B2466 /* v8threads.cc in Sources */,
 				89F23C810E78D5B2006B2466 /* variables.cc in Sources */,
 				89B933B00FAA0F9D00201304 /* version.cc in Sources */,
-				58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
-				58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
+				9FA38BD11175B30400C4CD55 /* virtual-frame-arm.cc in Sources */,
 				58950D690F5551CE00F3E8BA /* virtual-frame-light.cc in Sources */,
-				89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
-				9F4B7B8A0FCC877A00DC4117 /* log-utils.cc in Sources */,
-				8981F6011010502800D1520E /* frame-element.cc in Sources */,
-				9F11D9A1105AF0A300EBE5B2 /* heap-profiler.cc in Sources */,
-				9FBE03DF10BD409900F8BFBA /* fast-codegen.cc in Sources */,
-				9FBE03E510BD412600F8BFBA /* fast-codegen-arm.cc in Sources */,
-				9F73E3B1114E61A100F84A5A /* profile-generator.cc in Sources */,
-				9F2B3711114FF62D007CDAF4 /* circular-queue.cc in Sources */,
-				9F2B37261152CEA0007CDAF4 /* cpu-profiler.cc in Sources */,
+				58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
+				58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
 				9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */,
+				89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/tools/visual_studio/common.vsprops b/tools/visual_studio/common.vsprops
index e4f75a5..20bb119 100644
--- a/tools/visual_studio/common.vsprops
+++ b/tools/visual_studio/common.vsprops
@@ -8,7 +8,7 @@
 	<Tool
 		Name="VCCLCompilerTool"
 		AdditionalIncludeDirectories="$(ProjectDir)\..\..\src;$(IntDir)\DerivedSources"
-		PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;ENABLE_LOGGING_AND_PROFILING;ENABLE_DEBUGGER_SUPPORT"
+		PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;ENABLE_VMSTATE_TRACKING;ENABLE_LOGGING_AND_PROFILING;ENABLE_DEBUGGER_SUPPORT"
 		MinimalRebuild="false"
 		ExceptionHandling="0"
 		RuntimeTypeInfo="false"