Update V8 to r5780 as required by WebKit r71558

Change-Id: Ie3936550b99967a13755930d0dac0a59c3562625
diff --git a/Android.v8common.mk b/Android.v8common.mk
index 59ea39d..67b0c3c 100644
--- a/Android.v8common.mk
+++ b/Android.v8common.mk
@@ -61,6 +61,7 @@
 	src/rewriter.cc \
 	src/runtime.cc \
 	src/scanner.cc \
+	src/scanner-base.cc \
 	src/scopeinfo.cc \
 	src/scopes.cc \
 	src/serialize.cc \
diff --git a/ChangeLog b/ChangeLog
index 0785959..ea07009 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2010-11-08: Version 2.5.5
+
+        Added more aggressive GC of external objects in near out-of-memory
+        situations.
+
+        Fixed a bug that gave the incorrect result for String.split called
+        on the empty string (issue 924).
+
+
+2010-11-03: Version 2.5.4
+
+        Improved V8 VFPv3 runtime detection to address issue 914.
+
+
+2010-11-01: Version 2.5.3
+
+        Fixed a bug that prevents constants from overwriting function values
+        in object literals (issue 907).
+
+        Fixed a bug with reporting of impossible nested calls of DOM functions
+        (issue http://crbug.com/60753).
+
+
 2010-10-27: Version 2.5.2
 
         Improved sampler resolution on Linux.
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index bf2944f..f12be98 100644
--- a/V8_MERGE_REVISION
+++ b/V8_MERGE_REVISION
@@ -1,4 +1,4 @@
 We use a V8 revision that has been used for a Chromium release.
 
-http://src.chromium.org/svn/releases/9.0.569.0/DEPS
-http://v8.googlecode.com/svn/trunk@5716
+http://src.chromium.org/svn/releases/9.0.577.0/DEPS
+http://v8.googlecode.com/svn/trunk@5780
diff --git a/include/v8-debug.h b/include/v8-debug.h
index 4314727..f17b848 100755
--- a/include/v8-debug.h
+++ b/include/v8-debug.h
@@ -142,7 +142,7 @@
 
     virtual ~Message() {}
   };
-  
+
 
   /**
    * An event details object passed to the debug event listener.
@@ -300,7 +300,7 @@
   * get access to information otherwise not available during normal JavaScript
   * execution e.g. details on stack frames. Receiver of the function call will
   * be the debugger context global object, however this is a subject to change.
-  * The following example show a JavaScript function which when passed to 
+  * The following example show a JavaScript function which when passed to
   * v8::Debug::Call will return the current line of JavaScript execution.
   *
   * \code
diff --git a/include/v8.h b/include/v8.h
index 89502cb..8c730df 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -38,23 +38,9 @@
 #ifndef V8_H_
 #define V8_H_
 
-#include <stdio.h>
+#include "v8stdint.h"
 
 #ifdef _WIN32
-// When compiling on MinGW stdint.h is available.
-#ifdef __MINGW32__
-#include <stdint.h>
-#else  // __MINGW32__
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;  // NOLINT
-typedef unsigned short uint16_t;  // NOLINT
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-// intptr_t and friends are defined in crtdefs.h through stdio.h.
-#endif  // __MINGW32__
 
 // Setup for Windows DLL export/import. When building the V8 DLL the
 // BUILDING_V8_SHARED needs to be defined. When building a program which uses
@@ -76,8 +62,6 @@
 
 #else  // _WIN32
 
-#include <stdint.h>
-
 // Setup for Linux shared library export. There is no need to distinguish
 // between building or using the V8 shared library, but we should not
 // export symbols when we are building a static library.
@@ -127,7 +111,6 @@
 class Object;
 class Heap;
 class Top;
-
 }
 
 
@@ -476,10 +459,10 @@
       level = 0;
     }
   };
-  
+
   void Leave();
 
-  
+
   internal::Object** prev_next_;
   internal::Object** prev_limit_;
 
@@ -1055,7 +1038,7 @@
    */
   V8EXPORT bool IsExternalAscii() const;
 
-  class V8EXPORT ExternalStringResourceBase {
+  class V8EXPORT ExternalStringResourceBase {  // NOLINT
    public:
     virtual ~ExternalStringResourceBase() {}
 
@@ -1790,18 +1773,19 @@
   inline bool IsConstructCall() const;
   inline Local<Value> Data() const;
  private:
+  static const int kDataIndex = 0;
+  static const int kCalleeIndex = -1;
+  static const int kHolderIndex = -2;
+
   friend class ImplementationUtilities;
-  inline Arguments(Local<Value> data,
-                   Local<Object> holder,
-                   Local<Function> callee,
-                   bool is_construct_call,
-                   void** values, int length);
-  Local<Value> data_;
-  Local<Object> holder_;
-  Local<Function> callee_;
-  bool is_construct_call_;
-  void** values_;
+  inline Arguments(internal::Object** implicit_args,
+                   internal::Object** values,
+                   int length,
+                   bool is_construct_call);
+  internal::Object** implicit_args_;
+  internal::Object** values_;
   int length_;
+  bool is_construct_call_;
 };
 
 
@@ -3259,8 +3243,8 @@
 /**
  * An interface for exporting data from V8, using "push" model.
  */
-class V8EXPORT OutputStream {
-public:
+class V8EXPORT OutputStream {  // NOLINT
+ public:
   enum OutputEncoding {
     kAscii = 0  // 7-bit ASCII.
   };
@@ -3290,6 +3274,8 @@
 
 namespace internal {
 
+const int kPointerSize = sizeof(void*);  // NOLINT
+const int kIntSize = sizeof(int);  // NOLINT
 
 // Tag information for HeapObject.
 const int kHeapObjectTag = 1;
@@ -3325,19 +3311,19 @@
   }
 };
 
-const int kSmiShiftSize = SmiConstants<sizeof(void*)>::kSmiShiftSize;
-const int kSmiValueSize = SmiConstants<sizeof(void*)>::kSmiValueSize;
+const int kSmiShiftSize = SmiConstants<kPointerSize>::kSmiShiftSize;
+const int kSmiValueSize = SmiConstants<kPointerSize>::kSmiValueSize;
 
 template <size_t ptr_size> struct InternalConstants;
 
 // Internal constants for 32-bit systems.
 template <> struct InternalConstants<4> {
-  static const int kStringResourceOffset = 3 * sizeof(void*);
+  static const int kStringResourceOffset = 3 * kPointerSize;
 };
 
 // Internal constants for 64-bit systems.
 template <> struct InternalConstants<8> {
-  static const int kStringResourceOffset = 3 * sizeof(void*);
+  static const int kStringResourceOffset = 3 * kPointerSize;
 };
 
 /**
@@ -3351,12 +3337,12 @@
   // These values match non-compiler-dependent values defined within
   // the implementation of v8.
   static const int kHeapObjectMapOffset = 0;
-  static const int kMapInstanceTypeOffset = sizeof(void*) + sizeof(int);
+  static const int kMapInstanceTypeOffset = kPointerSize + kIntSize;
   static const int kStringResourceOffset =
-      InternalConstants<sizeof(void*)>::kStringResourceOffset;
+      InternalConstants<kPointerSize>::kStringResourceOffset;
 
-  static const int kProxyProxyOffset = sizeof(void*);
-  static const int kJSObjectHeaderSize = 3 * sizeof(void*);
+  static const int kProxyProxyOffset = kPointerSize;
+  static const int kJSObjectHeaderSize = 3 * kPointerSize;
   static const int kFullStringRepresentationMask = 0x07;
   static const int kExternalTwoByteRepresentationTag = 0x02;
 
@@ -3374,7 +3360,7 @@
   }
 
   static inline int SmiValue(internal::Object* value) {
-    return SmiConstants<sizeof(void*)>::SmiToInt(value);
+    return SmiConstants<kPointerSize>::SmiToInt(value);
   }
 
   static inline int GetInstanceType(internal::Object* obj) {
@@ -3403,10 +3389,9 @@
     uint8_t* addr = reinterpret_cast<uint8_t*>(ptr) + offset - kHeapObjectTag;
     return *reinterpret_cast<T*>(addr);
   }
-
 };
 
-}
+}  // namespace internal
 
 
 template <class T>
@@ -3470,14 +3455,13 @@
 }
 
 
-Arguments::Arguments(v8::Local<v8::Value> data,
-                     v8::Local<v8::Object> holder,
-                     v8::Local<v8::Function> callee,
-                     bool is_construct_call,
-                     void** values, int length)
-    : data_(data), holder_(holder), callee_(callee),
-      is_construct_call_(is_construct_call),
-      values_(values), length_(length) { }
+Arguments::Arguments(internal::Object** implicit_args,
+                     internal::Object** values, int length,
+                     bool is_construct_call)
+    : implicit_args_(implicit_args),
+      values_(values),
+      length_(length),
+      is_construct_call_(is_construct_call) { }
 
 
 Local<Value> Arguments::operator[](int i) const {
@@ -3487,7 +3471,8 @@
 
 
 Local<Function> Arguments::Callee() const {
-  return callee_;
+  return Local<Function>(reinterpret_cast<Function*>(
+      &implicit_args_[kCalleeIndex]));
 }
 
 
@@ -3497,12 +3482,13 @@
 
 
 Local<Object> Arguments::Holder() const {
-  return holder_;
+  return Local<Object>(reinterpret_cast<Object*>(
+      &implicit_args_[kHolderIndex]));
 }
 
 
 Local<Value> Arguments::Data() const {
-  return data_;
+  return Local<Value>(reinterpret_cast<Value*>(&implicit_args_[kDataIndex]));
 }
 
 
@@ -3565,7 +3551,7 @@
     // If the object is a plain JSObject, which is the common case,
     // we know where to find the internal fields and can return the
     // value directly.
-    int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index);
+    int offset = I::kJSObjectHeaderSize + (internal::kPointerSize * index);
     O* value = I::ReadField<O*>(obj, offset);
     O** result = HandleScope::CreateHandle(value);
     return Local<Value>(reinterpret_cast<Value*>(result));
@@ -3601,7 +3587,7 @@
     // If the object is a plain JSObject, which is the common case,
     // we know where to find the internal fields and can return the
     // value directly.
-    int offset = I::kJSObjectHeaderSize + (sizeof(void*) * index);
+    int offset = I::kJSObjectHeaderSize + (internal::kPointerSize * index);
     O* value = I::ReadField<O*>(obj, offset);
     return I::GetExternalPointer(value);
   }
diff --git a/include/v8stdint.h b/include/v8stdint.h
new file mode 100644
index 0000000..50b4f29
--- /dev/null
+++ b/include/v8stdint.h
@@ -0,0 +1,53 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Load definitions of standard types.
+
+#ifndef V8STDINT_H_
+#define V8STDINT_H_
+
+#include <stdio.h>
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;  // NOLINT
+typedef unsigned short uint16_t;  // NOLINT
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+// intptr_t and friends are defined in crtdefs.h through stdio.h.
+
+#else
+
+#include <stdint.h>
+
+#endif
+
+#endif  // V8STDINT_H_
diff --git a/src/SConscript b/src/SConscript
index 8995d48..596caf7 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -95,6 +95,7 @@
     register-allocator.cc
     rewriter.cc
     runtime.cc
+    scanner-base.cc
     scanner.cc
     scopeinfo.cc
     scopes.cc
diff --git a/src/api.cc b/src/api.cc
index 2df31df..ee7ad3a 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -43,7 +43,6 @@
 #include "serialize.h"
 #include "snapshot.h"
 #include "top.h"
-#include "utils.h"
 #include "v8threads.h"
 #include "version.h"
 
@@ -1155,13 +1154,13 @@
 
 ScriptData* ScriptData::PreCompile(const char* input, int length) {
   unibrow::Utf8InputBuffer<> buf(input, length);
-  return i::Parser::PreParse(i::Handle<i::String>(), &buf, NULL);
+  return i::ParserApi::PreParse(i::Handle<i::String>(), &buf, NULL);
 }
 
 
 ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
   i::Handle<i::String> str = Utils::OpenHandle(*source);
-  return i::Parser::PreParse(str, NULL, NULL);
+  return i::ParserApi::PreParse(str, NULL, NULL);
 }
 
 
diff --git a/src/apiutils.h b/src/apiutils.h
index 8c791eb..1313dda 100644
--- a/src/apiutils.h
+++ b/src/apiutils.h
@@ -29,7 +29,6 @@
 #define V8_APIUTILS_H_
 
 namespace v8 {
-
 class ImplementationUtilities {
  public:
   static v8::Handle<v8::Primitive> Undefined();
@@ -45,12 +44,21 @@
     return that->names_;
   }
 
-  static v8::Arguments NewArguments(Local<Value> data,
-                                    Local<Object> holder,
-                                    Local<Function> callee,
-                                    bool is_construct_call,
-                                    void** argv, int argc) {
-    return v8::Arguments(data, holder, callee, is_construct_call, argv, argc);
+  // Packs additional parameters for the NewArguments function. |implicit_args|
+  // is a pointer to the last element of 3-elements array controlled by GC.
+  static void PrepareArgumentsData(internal::Object** implicit_args,
+                                   internal::Object* data,
+                                   internal::JSFunction* callee,
+                                   internal::Object* holder) {
+    implicit_args[v8::Arguments::kDataIndex] = data;
+    implicit_args[v8::Arguments::kCalleeIndex] = callee;
+    implicit_args[v8::Arguments::kHolderIndex] = holder;
+  }
+
+  static v8::Arguments NewArguments(internal::Object** implicit_args,
+                                    internal::Object** argv, int argc,
+                                    bool is_construct_call) {
+    return v8::Arguments(implicit_args, argv, argc, is_construct_call);
   }
 
   // Introduce an alias for the handle scope data to allow non-friends
diff --git a/src/arguments.h b/src/arguments.h
index c17f4cf..d51c9e4 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -84,6 +84,15 @@
     values_[1] = holder;
     values_[0] = data;
   }
+
+  inline CustomArguments() {
+#ifdef DEBUG
+    for (size_t i = 0; i < ARRAY_SIZE(values_); i++) {
+      values_[i] = reinterpret_cast<Object*>(kZapValue);
+    }
+#endif
+  }
+
   void IterateInstance(ObjectVisitor* v);
   Object** end() { return values_ + ARRAY_SIZE(values_) - 1; }
  private:
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 7d368bf..72835ba 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -317,7 +317,8 @@
 static const int kMinimalBufferSize = 4*KB;
 static byte* spare_buffer_ = NULL;
 
-Assembler::Assembler(void* buffer, int buffer_size) {
+Assembler::Assembler(void* buffer, int buffer_size)
+    : positions_recorder_(this) {
   if (buffer == NULL) {
     // Do our own buffer management.
     if (buffer_size <= kMinimalBufferSize) {
@@ -354,10 +355,6 @@
   no_const_pool_before_ = 0;
   last_const_pool_end_ = 0;
   last_bound_pos_ = 0;
-  current_statement_position_ = RelocInfo::kNoPosition;
-  current_position_ = RelocInfo::kNoPosition;
-  written_statement_position_ = current_statement_position_;
-  written_position_ = current_position_;
 }
 
 
@@ -752,15 +749,15 @@
 // if they can be encoded in the ARM's 12 bits of immediate-offset instruction
 // space.  There is no guarantee that the relocated location can be similarly
 // encoded.
-static bool MustUseConstantPool(RelocInfo::Mode rmode) {
-  if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
+bool Operand::must_use_constant_pool() const {
+  if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
 #ifdef DEBUG
     if (!Serializer::enabled()) {
       Serializer::TooLateToEnableNow();
     }
 #endif  // def DEBUG
     return Serializer::enabled();
-  } else if (rmode == RelocInfo::NONE) {
+  } else if (rmode_ == RelocInfo::NONE) {
     return false;
   }
   return true;
@@ -769,7 +766,7 @@
 
 bool Operand::is_single_instruction() const {
   if (rm_.is_valid()) return true;
-  if (MustUseConstantPool(rmode_)) return false;
+  if (must_use_constant_pool()) return false;
   uint32_t dummy1, dummy2;
   return fits_shifter(imm32_, &dummy1, &dummy2, NULL);
 }
@@ -785,7 +782,7 @@
     // Immediate.
     uint32_t rotate_imm;
     uint32_t immed_8;
-    if (MustUseConstantPool(x.rmode_) ||
+    if (x.must_use_constant_pool() ||
         !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
       // The immediate operand cannot be encoded as a shifter operand, so load
       // it first to register ip and change the original instruction to use ip.
@@ -794,8 +791,7 @@
       CHECK(!rn.is(ip));  // rn should never be ip, or will be trashed
       Condition cond = static_cast<Condition>(instr & CondMask);
       if ((instr & ~CondMask) == 13*B21) {  // mov, S not set
-        if (MustUseConstantPool(x.rmode_) ||
-            !CpuFeatures::IsSupported(ARMv7)) {
+        if (x.must_use_constant_pool() || !CpuFeatures::IsSupported(ARMv7)) {
           RecordRelocInfo(x.rmode_, x.imm32_);
           ldr(rd, MemOperand(pc, 0), cond);
         } else {
@@ -806,7 +802,7 @@
       } else {
         // If this is not a mov or mvn instruction we may still be able to avoid
         // a constant pool entry by using mvn or movw.
-        if (!MustUseConstantPool(x.rmode_) &&
+        if (!x.must_use_constant_pool() &&
             (instr & kMovMvnMask) != kMovMvnPattern) {
           mov(ip, x, LeaveCC, cond);
         } else {
@@ -999,24 +995,24 @@
 
 
 void Assembler::blx(int branch_offset) {  // v5 and above
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   ASSERT((branch_offset & 1) == 0);
   int h = ((branch_offset & 2) >> 1)*B24;
   int imm24 = branch_offset >> 2;
   ASSERT(is_int24(imm24));
-  emit(15 << 28 | B27 | B25 | h | (imm24 & Imm24Mask));
+  emit(nv | B27 | B25 | h | (imm24 & Imm24Mask));
 }
 
 
 void Assembler::blx(Register target, Condition cond) {  // v5 and above
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   ASSERT(!target.is(pc));
   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | 3*B4 | target.code());
 }
 
 
 void Assembler::bx(Register target, Condition cond) {  // v5 and above, plus v4t
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   ASSERT(!target.is(pc));  // use of pc is actually allowed, but discouraged
   emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | B4 | target.code());
 }
@@ -1114,7 +1110,7 @@
 
 void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) {
   if (dst.is(pc)) {
-    WriteRecordedPositions();
+    positions_recorder()->WriteRecordedPositions();
   }
   // Don't allow nop instructions in the form mov rn, rn to be generated using
   // the mov instruction. They must be generated using nop(int)
@@ -1339,7 +1335,7 @@
     // Immediate.
     uint32_t rotate_imm;
     uint32_t immed_8;
-    if (MustUseConstantPool(src.rmode_) ||
+    if (src.must_use_constant_pool() ||
         !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) {
       // Immediate operand cannot be encoded, load it first to register ip.
       RecordRelocInfo(src.rmode_, src.imm32_);
@@ -1359,7 +1355,7 @@
 // Load/Store instructions.
 void Assembler::ldr(Register dst, const MemOperand& src, Condition cond) {
   if (dst.is(pc)) {
-    WriteRecordedPositions();
+    positions_recorder()->WriteRecordedPositions();
   }
   addrmod2(cond | B26 | L, dst, src);
 
@@ -1634,15 +1630,29 @@
 
 
 // Exception-generating instructions and debugging support.
-void Assembler::stop(const char* msg) {
+// Stops with a non-negative code less than kNumOfWatchedStops support
+// enabling/disabling and a counter feature. See simulator-arm.h .
+void Assembler::stop(const char* msg, Condition cond, int32_t code) {
 #ifndef __arm__
-  // The simulator handles these special instructions and stops execution.
-  emit(15 << 28 | ((intptr_t) msg));
+  // See constants-arm.h SoftwareInterruptCodes. Unluckily the Assembler and
+  // Simulator do not share constants declaration.
+  ASSERT(code >= kDefaultStopCode);
+  static const uint32_t kStopInterruptCode = 1 << 23;
+  static const uint32_t kMaxStopCode = kStopInterruptCode - 1;
+  // The Simulator will handle the stop instruction and get the message address.
+  // It expects to find the address just after the svc instruction.
+  BlockConstPoolFor(2);
+  if (code >= 0) {
+    svc(kStopInterruptCode + code, cond);
+  } else {
+    svc(kStopInterruptCode + kMaxStopCode, cond);
+  }
+  emit(reinterpret_cast<Instr>(msg));
 #else  // def __arm__
 #ifdef CAN_USE_ARMV5_INSTRUCTIONS
   bkpt(0);
 #else  // ndef CAN_USE_ARMV5_INSTRUCTIONS
-  swi(0x9f0001);
+  svc(0x9f0001);
 #endif  // ndef CAN_USE_ARMV5_INSTRUCTIONS
 #endif  // def __arm__
 }
@@ -1654,7 +1664,7 @@
 }
 
 
-void Assembler::swi(uint32_t imm24, Condition cond) {
+void Assembler::svc(uint32_t imm24, Condition cond) {
   ASSERT(is_uint24(imm24));
   emit(cond | 15*B24 | imm24);
 }
@@ -2363,14 +2373,14 @@
 
 // Debugging.
 void Assembler::RecordJSReturn() {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   CheckBuffer();
   RecordRelocInfo(RelocInfo::JS_RETURN);
 }
 
 
 void Assembler::RecordDebugBreakSlot() {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   CheckBuffer();
   RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
 }
@@ -2384,47 +2394,6 @@
 }
 
 
-void Assembler::RecordPosition(int pos) {
-  if (pos == RelocInfo::kNoPosition) return;
-  ASSERT(pos >= 0);
-  current_position_ = pos;
-}
-
-
-void Assembler::RecordStatementPosition(int pos) {
-  if (pos == RelocInfo::kNoPosition) return;
-  ASSERT(pos >= 0);
-  current_statement_position_ = pos;
-}
-
-
-bool Assembler::WriteRecordedPositions() {
-  bool written = false;
-
-  // Write the statement position if it is different from what was written last
-  // time.
-  if (current_statement_position_ != written_statement_position_) {
-    CheckBuffer();
-    RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
-    written_statement_position_ = current_statement_position_;
-    written = true;
-  }
-
-  // Write the position if it is different from what was written last time and
-  // also different from the written statement position.
-  if (current_position_ != written_position_ &&
-      current_position_ != written_statement_position_) {
-    CheckBuffer();
-    RecordRelocInfo(RelocInfo::POSITION, current_position_);
-    written_position_ = current_position_;
-    written = true;
-  }
-
-  // Return whether something was written.
-  return written;
-}
-
-
 void Assembler::GrowBuffer() {
   if (!own_buffer_) FATAL("external code buffer is too small");
 
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 1c4fd60..0579235 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -448,6 +448,7 @@
   // Return true of this operand fits in one instruction so that no
   // 2-instruction solution with a load into the ip register is necessary.
   bool is_single_instruction() const;
+  bool must_use_constant_pool() const;
 
   inline int32_t immediate() const {
     ASSERT(!rm_.is_valid());
@@ -904,10 +905,13 @@
   void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);
 
   // Exception-generating instructions and debugging support
-  void stop(const char* msg);
+  static const int kDefaultStopCode = -1;
+  void stop(const char* msg,
+            Condition cond = al,
+            int32_t code = kDefaultStopCode);
 
   void bkpt(uint32_t imm16);  // v5 and above
-  void swi(uint32_t imm24, Condition cond = al);
+  void svc(uint32_t imm24, Condition cond = al);
 
   // Coprocessor instructions
 
@@ -1114,13 +1118,9 @@
   // Use --debug_code to enable.
   void RecordComment(const char* msg);
 
-  void RecordPosition(int pos);
-  void RecordStatementPosition(int pos);
-  bool WriteRecordedPositions();
-
   int pc_offset() const { return pc_ - buffer_; }
-  int current_position() const { return current_position_; }
-  int current_statement_position() const { return current_statement_position_; }
+
+  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
 
   bool can_peephole_optimize(int instructions) {
     if (!FLAG_peephole_optimization) return false;
@@ -1256,12 +1256,6 @@
   // The bound position, before this we cannot do instruction elimination.
   int last_bound_pos_;
 
-  // source position information
-  int current_position_;
-  int current_statement_position_;
-  int written_position_;
-  int written_statement_position_;
-
   // Code emission
   inline void CheckBuffer();
   void GrowBuffer();
@@ -1287,8 +1281,21 @@
   friend class RelocInfo;
   friend class CodePatcher;
   friend class BlockConstPoolScope;
+
+  PositionsRecorder positions_recorder_;
+  friend class PositionsRecorder;
+  friend class EnsureSpace;
 };
 
+
+class EnsureSpace BASE_EMBEDDED {
+ public:
+  explicit EnsureSpace(Assembler* assembler) {
+    assembler->CheckBuffer();
+  }
+};
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_ARM_ASSEMBLER_ARM_H_
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 0c060f0..d7fd9a4 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -3596,6 +3596,12 @@
     frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 4);
   }
   frame_->EmitPush(r0);  // save the result
+
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  node->CalculateEmitStore();
+
   for (int i = 0; i < node->properties()->length(); i++) {
     // At the start of each iteration, the top of stack contains
     // the newly created object literal.
@@ -3612,11 +3618,15 @@
         if (key->handle()->IsSymbol()) {
           Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
           Load(value);
-          frame_->PopToR0();
-          // Fetch the object literal.
-          frame_->SpillAllButCopyTOSToR1();
-          __ mov(r2, Operand(key->handle()));
-          frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
+          if (property->emit_store()) {
+            frame_->PopToR0();
+            // Fetch the object literal.
+            frame_->SpillAllButCopyTOSToR1();
+            __ mov(r2, Operand(key->handle()));
+            frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
+          } else {
+            frame_->Drop();
+          }
           break;
         }
         // else fall through
@@ -3624,7 +3634,11 @@
         frame_->Dup();
         Load(key);
         Load(value);
-        frame_->CallRuntime(Runtime::kSetProperty, 3);
+        if (property->emit_store()) {
+          frame_->CallRuntime(Runtime::kSetProperty, 3);
+        } else {
+          frame_->Drop(3);
+        }
         break;
       }
       case ObjectLiteral::Property::SETTER: {
@@ -5482,73 +5496,6 @@
 }
 
 
-void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT_EQ(1, args->length());
-
-  Load(args->at(0));
-  frame_->PopToR0();
-  {
-    VirtualFrame::SpilledScope spilled_scope(frame_);
-
-    Label done;
-    Label call_runtime;
-    __ BranchOnSmi(r0, &done);
-
-    // Load JSRegExp map into r1. Check that argument object has this map.
-    // Arguments to this function should be results of calling RegExp exec,
-    // which is either an unmodified JSRegExpResult or null. Anything not having
-    // the unmodified JSRegExpResult map is returned unmodified.
-    // This also ensures that elements are fast.
-
-    __ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX));
-    __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset));
-    __ ldr(r1, ContextOperand(r1, Context::REGEXP_RESULT_MAP_INDEX));
-    __ ldr(ip, FieldMemOperand(r0, HeapObject::kMapOffset));
-    __ cmp(r1, Operand(ip));
-    __ b(ne, &done);
-
-    if (FLAG_debug_code) {
-      __ LoadRoot(r2, Heap::kEmptyFixedArrayRootIndex);
-      __ ldr(ip, FieldMemOperand(r0, JSObject::kPropertiesOffset));
-      __ cmp(ip, r2);
-      __ Check(eq, "JSRegExpResult: default map but non-empty properties.");
-    }
-
-    // All set, copy the contents to a new object.
-    __ AllocateInNewSpace(JSRegExpResult::kSize,
-                          r2,
-                          r3,
-                          r4,
-                          &call_runtime,
-                          NO_ALLOCATION_FLAGS);
-    // Store RegExpResult map as map of allocated object.
-    ASSERT(JSRegExpResult::kSize == 6 * kPointerSize);
-    // Copy all fields (map is already in r1) from (untagged) r0 to r2.
-    // Change map of elements array (ends up in r4) to be a FixedCOWArray.
-    __ bic(r0, r0, Operand(kHeapObjectTagMask));
-    __ ldm(ib, r0, r3.bit() | r4.bit() | r5.bit() | r6.bit() | r7.bit());
-    __ stm(ia, r2,
-           r1.bit() | r3.bit() | r4.bit() | r5.bit() | r6.bit() | r7.bit());
-    ASSERT(JSRegExp::kElementsOffset == 2 * kPointerSize);
-    // Check whether elements array is empty fixed array, and otherwise make
-    // it copy-on-write (it never should be empty unless someone is messing
-    // with the arguments to the runtime function).
-    __ LoadRoot(ip, Heap::kEmptyFixedArrayRootIndex);
-    __ add(r0, r2, Operand(kHeapObjectTag));  // Tag result and move it to r0.
-    __ cmp(r4, ip);
-    __ b(eq, &done);
-    __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex);
-    __ str(ip, FieldMemOperand(r4, HeapObject::kMapOffset));
-    __ b(&done);
-    __ bind(&call_runtime);
-    __ push(r0);
-    __ CallRuntime(Runtime::kRegExpCloneResult, 1);
-    __ bind(&done);
-  }
-  frame_->EmitPush(r0);
-}
-
-
 class DeferredSearchCache: public DeferredCode {
  public:
   DeferredSearchCache(Register dst, Register cache, Register key)
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index e6fd607..97e50b4 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -518,8 +518,6 @@
 
   void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
 
-  void GenerateRegExpCloneResult(ZoneList<Expression*>* args);
-
   // Support for fast native caches.
   void GenerateGetFromCache(ZoneList<Expression*>* args);
 
diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h
index b2b5cb5..123c5e7 100644
--- a/src/arm/constants-arm.h
+++ b/src/arm/constants-arm.h
@@ -186,12 +186,18 @@
 
 // Special Software Interrupt codes when used in the presence of the ARM
 // simulator.
+// svc (formerly swi) provides a 24bit immediate value. Use bits 22:0 for
+// standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature.
 enum SoftwareInterruptCodes {
   // transition to C code
   call_rt_redirected = 0x10,
   // break point
-  break_point = 0x20
+  break_point = 0x20,
+  // stop
+  stop = 1 << 23
 };
+static const int32_t kStopCodeMask = stop - 1;
+static const uint32_t kMaxStopCode = stop - 1;
 
 
 // Type of VFP register. Determines register encoding.
@@ -325,7 +331,7 @@
   inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
 
   // Fields used in Software interrupt instructions
-  inline SoftwareInterruptCodes SwiField() const {
+  inline SoftwareInterruptCodes SvcField() const {
     return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
   }
 
diff --git a/src/arm/cpu-arm.cc b/src/arm/cpu-arm.cc
index a3bf483..e998b6f 100644
--- a/src/arm/cpu-arm.cc
+++ b/src/arm/cpu-arm.cc
@@ -70,7 +70,7 @@
       // __arm__ may be defined in thumb mode.
       register uint32_t scno asm("r7") = __ARM_NR_cacheflush;
       asm volatile(
-          "swi 0x0"
+          "svc 0x0"
           : "=r" (beg)
           : "0" (beg), "r" (end), "r" (flg), "r" (scno));
     #else
@@ -83,7 +83,7 @@
           ".ARM            \n"
       "1:  push {r7}       \n\t"
           "mov r7, %4      \n\t"
-          "swi 0x0         \n\t"
+          "svc 0x0         \n\t"
           "pop {r7}        \n\t"
       "@   Enter THUMB Mode\n\t"
           "adr r3, 2f+1    \n\t"
@@ -98,20 +98,20 @@
     #if defined (__arm__) && !defined(__thumb__)
       // __arm__ may be defined in thumb mode.
       asm volatile(
-          "swi %1"
+          "svc %1"
           : "=r" (beg)
           : "i" (__ARM_NR_cacheflush), "0" (beg), "r" (end), "r" (flg));
     #else
       // Do not use the value of __ARM_NR_cacheflush in the inline assembly
       // below, because the thumb mode value would be used, which would be
-      // wrong, since we switch to ARM mode before executing the swi instruction
+      // wrong, since we switch to ARM mode before executing the svc instruction
       asm volatile(
       "@   Enter ARM Mode  \n\t"
           "adr r3, 1f      \n\t"
           "bx  r3          \n\t"
           ".ALIGN 4        \n\t"
           ".ARM            \n"
-      "1:  swi 0x9f0002    \n"
+      "1:  svc 0x9f0002    \n"
       "@   Enter THUMB Mode\n\t"
           "adr r3, 2f+1    \n\t"
           "bx  r3          \n\t"
diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc
index 5122f43..4e7580f 100644
--- a/src/arm/disasm-arm.cc
+++ b/src/arm/disasm-arm.cc
@@ -108,7 +108,7 @@
   void PrintShiftImm(Instr* instr);
   void PrintShiftSat(Instr* instr);
   void PrintPU(Instr* instr);
-  void PrintSoftwareInterrupt(SoftwareInterruptCodes swi);
+  void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
 
   // Handle formatting of instructions and their options.
   int FormatRegister(Instr* instr, const char* option);
@@ -126,8 +126,8 @@
   void DecodeType4(Instr* instr);
   void DecodeType5(Instr* instr);
   void DecodeType6(Instr* instr);
-  void DecodeType7(Instr* instr);
-  void DecodeUnconditional(Instr* instr);
+  // Type 7 includes special Debugger instructions.
+  int DecodeType7(Instr* instr);
   // For VFP support.
   void DecodeTypeVFP(Instr* instr);
   void DecodeType6CoprocessorIns(Instr* instr);
@@ -290,8 +290,8 @@
 
 // Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
 // the FormatOption method.
-void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes swi) {
-  switch (swi) {
+void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
+  switch (svc) {
     case call_rt_redirected:
       Print("call_rt_redirected");
       return;
@@ -299,9 +299,16 @@
       Print("break_point");
       return;
     default:
-      out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
-                                           "%d",
-                                           swi);
+      if (svc >= stop) {
+        out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+                                             "%d - 0x%x",
+                                             svc & kStopCodeMask,
+                                             svc & kStopCodeMask);
+      } else {
+        out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+                                             "%d",
+                                             svc);
+      }
       return;
   }
 }
@@ -553,9 +560,9 @@
           PrintShiftRm(instr);
           return 8;
         }
-      } else if (format[1] == 'w') {  // 'swi
-        ASSERT(STRING_STARTS_WITH(format, "swi"));
-        PrintSoftwareInterrupt(instr->SwiField());
+      } else if (format[1] == 'v') {  // 'svc
+        ASSERT(STRING_STARTS_WITH(format, "svc"));
+        PrintSoftwareInterrupt(instr->SvcField());
         return 3;
       } else if (format[1] == 'i') {  // 'sign: signed extra loads and stores
         ASSERT(STRING_STARTS_WITH(format, "sign"));
@@ -1004,72 +1011,27 @@
 }
 
 
-void Decoder::DecodeType7(Instr* instr) {
+int Decoder::DecodeType7(Instr* instr) {
   if (instr->Bit(24) == 1) {
-    Format(instr, "swi'cond 'swi");
+    if (instr->SvcField() >= stop) {
+      Format(instr, "stop'cond 'svc");
+      // Also print the stop message. Its address is encoded
+      // in the following 4 bytes.
+      out_buffer_pos_ +=
+        v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+                          "\n  %p  %08x       stop message: %s",
+                          reinterpret_cast<int32_t*>(instr + Instr::kInstrSize),
+                          *reinterpret_cast<char**>(instr + Instr::kInstrSize),
+                          *reinterpret_cast<char**>(instr + Instr::kInstrSize));
+      // We have decoded 2 * Instr::kInstrSize bytes.
+      return 2 * Instr::kInstrSize;
+    } else {
+      Format(instr, "svc'cond 'svc");
+    }
   } else {
     DecodeTypeVFP(instr);
   }
-}
-
-void Decoder::DecodeUnconditional(Instr* instr) {
-  if (instr->Bits(7, 4) == 0xB && instr->Bits(27, 25) == 0 && instr->HasL()) {
-    Format(instr, "'memop'h'pu 'rd, ");
-    bool immediate = instr->HasB();
-    switch (instr->PUField()) {
-      case 0: {
-        // Post index, negative.
-        if (instr->HasW()) {
-          Unknown(instr);
-          break;
-        }
-        if (immediate) {
-          Format(instr, "['rn], #-'imm12");
-        } else {
-          Format(instr, "['rn], -'rm");
-        }
-        break;
-      }
-      case 1: {
-        // Post index, positive.
-        if (instr->HasW()) {
-          Unknown(instr);
-          break;
-        }
-        if (immediate) {
-          Format(instr, "['rn], #+'imm12");
-        } else {
-          Format(instr, "['rn], +'rm");
-        }
-        break;
-      }
-      case 2: {
-        // Pre index or offset, negative.
-        if (immediate) {
-          Format(instr, "['rn, #-'imm12]'w");
-        } else {
-          Format(instr, "['rn, -'rm]'w");
-        }
-        break;
-      }
-      case 3: {
-        // Pre index or offset, positive.
-        if (immediate) {
-          Format(instr, "['rn, #+'imm12]'w");
-        } else {
-          Format(instr, "['rn, +'rm]'w");
-        }
-        break;
-      }
-      default: {
-        // The PU field is a 2-bit field.
-        UNREACHABLE();
-        break;
-      }
-    }
-    return;
-  }
-  Format(instr, "break 'msg");
+  return Instr::kInstrSize;
 }
 
 
@@ -1332,7 +1294,7 @@
                                        "%08x       ",
                                        instr->InstructionBits());
   if (instr->ConditionField() == special_condition) {
-    DecodeUnconditional(instr);
+    UNIMPLEMENTED();
     return Instr::kInstrSize;
   }
   switch (instr->TypeField()) {
@@ -1362,8 +1324,7 @@
       break;
     }
     case 7: {
-      DecodeType7(instr);
-      break;
+      return DecodeType7(instr);
     }
     default: {
       // The type field is 3-bits in the ARM encoding.
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 2855ca4..bf27d0c 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1169,6 +1169,11 @@
   // result_saved is false the result is in r0.
   bool result_saved = false;
 
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  expr->CalculateEmitStore();
+
   for (int i = 0; i < expr->properties()->length(); i++) {
     ObjectLiteral::Property* property = expr->properties()->at(i);
     if (property->IsCompileTimeValue()) continue;
@@ -1190,8 +1195,10 @@
           VisitForAccumulatorValue(value);
           __ mov(r2, Operand(key->handle()));
           __ ldr(r1, MemOperand(sp));
-          Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
-          EmitCallIC(ic, RelocInfo::CODE_TARGET);
+          if (property->emit_store()) {
+            Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+            EmitCallIC(ic, RelocInfo::CODE_TARGET);
+          }
           break;
         }
         // Fall through.
@@ -1201,7 +1208,11 @@
         __ push(r0);
         VisitForStackValue(key);
         VisitForStackValue(value);
-        __ CallRuntime(Runtime::kSetProperty, 3);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kSetProperty, 3);
+        } else {
+          __ Drop(3);
+        }
         break;
       case ObjectLiteral::Property::GETTER:
       case ObjectLiteral::Property::SETTER:
@@ -1677,12 +1688,14 @@
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+    __ mov(r2, Operand(name));
   }
-  __ mov(r2, Operand(name));
   // Record source position for debugger.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   // Call the IC initialization code.
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
@@ -1699,13 +1712,15 @@
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+    VisitForAccumulatorValue(key);
+    __ mov(r2, r0);
   }
-  VisitForAccumulatorValue(key);
-  __ mov(r2, r0);
   // Record source position for debugger.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   // Call the IC initialization code.
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
@@ -1721,11 +1736,13 @@
   // Code common for calls using the call stub.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
   }
   // Record source position for debugger.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
   __ CallStub(&stub);
@@ -1745,41 +1762,45 @@
     // resolve the function we need to call and the receiver of the
     // call.  Then we call the resolved function using the given
     // arguments.
-    VisitForStackValue(fun);
-    __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
-    __ push(r2);  // Reserved receiver slot.
-
-    // Push the arguments.
     ZoneList<Expression*>* args = expr->arguments();
     int arg_count = args->length();
-    for (int i = 0; i < arg_count; i++) {
-      VisitForStackValue(args->at(i));
-    }
 
-    // Push copy of the function - found below the arguments.
-    __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
-    __ push(r1);
+    { PreserveStatementPositionScope pos_scope(masm()->positions_recorder());
+      VisitForStackValue(fun);
+      __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
+      __ push(r2);  // Reserved receiver slot.
 
-    // Push copy of the first argument or undefined if it doesn't exist.
-    if (arg_count > 0) {
-      __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
+      // Push the arguments.
+      for (int i = 0; i < arg_count; i++) {
+        VisitForStackValue(args->at(i));
+      }
+
+      // Push copy of the function - found below the arguments.
+      __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
       __ push(r1);
-    } else {
-      __ push(r2);
+
+      // Push copy of the first argument or undefined if it doesn't exist.
+      if (arg_count > 0) {
+        __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
+        __ push(r1);
+      } else {
+        __ push(r2);
+      }
+
+      // Push the receiver of the enclosing function and do runtime call.
+      __ ldr(r1,
+             MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize));
+      __ push(r1);
+      __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
+
+      // The runtime call returns a pair of values in r0 (function) and
+      // r1 (receiver). Touch up the stack with the right values.
+      __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
+      __ str(r1, MemOperand(sp, arg_count * kPointerSize));
     }
 
-    // Push the receiver of the enclosing function and do runtime call.
-    __ ldr(r1, MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize));
-    __ push(r1);
-    __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
-
-    // The runtime call returns a pair of values in r0 (function) and
-    // r1 (receiver). Touch up the stack with the right values.
-    __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
-    __ str(r1, MemOperand(sp, arg_count * kPointerSize));
-
     // Record source position for debugger.
-    SetSourcePosition(expr->position());
+    SetSourcePosition(expr->position(), FORCED_POSITION);
     InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
     CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
     __ CallStub(&stub);
@@ -1796,12 +1817,14 @@
     // Call to a lookup slot (dynamically introduced variable).
     Label slow, done;
 
-    // Generate code for loading from variables potentially shadowed
-    // by eval-introduced variables.
-    EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
-                                    NOT_INSIDE_TYPEOF,
-                                    &slow,
-                                    &done);
+    { PreserveStatementPositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
+                                      NOT_INSIDE_TYPEOF,
+                                      &slow,
+                                      &done);
+    }
 
     __ bind(&slow);
     // Call the runtime to find the function to call (returned in r0)
@@ -1835,17 +1858,23 @@
     Literal* key = prop->key()->AsLiteral();
     if (key != NULL && key->handle()->IsSymbol()) {
       // Call to a named property, use call IC.
-      VisitForStackValue(prop->obj());
+      { PreserveStatementPositionScope scope(masm()->positions_recorder());
+        VisitForStackValue(prop->obj());
+      }
       EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
     } else {
       // Call to a keyed property.
       // For a synthetic property use keyed load IC followed by function call,
       // for a regular property use keyed CallIC.
-      VisitForStackValue(prop->obj());
+      { PreserveStatementPositionScope scope(masm()->positions_recorder());
+        VisitForStackValue(prop->obj());
+      }
       if (prop->is_synthetic()) {
-        VisitForAccumulatorValue(prop->key());
+        { PreserveStatementPositionScope scope(masm()->positions_recorder());
+          VisitForAccumulatorValue(prop->key());
+        }
         // Record source code position for IC call.
-        SetSourcePosition(prop->position());
+        SetSourcePosition(prop->position(), FORCED_POSITION);
         __ pop(r1);  // We do not need to keep the receiver.
 
         Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
@@ -1868,7 +1897,10 @@
         loop_depth() == 0) {
       lit->set_try_full_codegen(true);
     }
-    VisitForStackValue(fun);
+
+    { PreserveStatementPositionScope scope(masm()->positions_recorder());
+      VisitForStackValue(fun);
+    }
     // Load global receiver object.
     __ ldr(r1, CodeGenerator::GlobalObject());
     __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index c460f9c..a09afdf 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -544,7 +544,7 @@
   // Probe the stub cache.
   Code::Flags flags =
       Code::ComputeFlags(kind, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc);
-  StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg);
+  StubCache::GenerateProbe(masm, flags, r1, r2, r3, r4, r5);
 
   // If the stub cache probing failed, the receiver might be a value.
   // For value objects, we use the map of the prototype objects for
@@ -583,7 +583,7 @@
 
   // Probe the stub cache for the value object.
   __ bind(&probe);
-  StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg);
+  StubCache::GenerateProbe(masm, flags, r1, r2, r3, r4, r5);
 
   __ bind(&miss);
 }
@@ -858,7 +858,7 @@
   Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
                                          NOT_IN_LOOP,
                                          MONOMORPHIC);
-  StubCache::GenerateProbe(masm, flags, r0, r2, r3, no_reg);
+  StubCache::GenerateProbe(masm, flags, r0, r2, r3, r4, r5);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
@@ -2163,7 +2163,7 @@
   Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
                                          NOT_IN_LOOP,
                                          MONOMORPHIC);
-  StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg);
+  StubCache::GenerateProbe(masm, flags, r1, r2, r3, r4, r5);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 7f6090b..d2c22af 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -129,7 +129,7 @@
     // address is loaded. The mov method will automatically record
     // positions when pc is the target, since this is not the case here
     // we have to do it explicitly.
-    WriteRecordedPositions();
+    positions_recorder()->WriteRecordedPositions();
 
     mov(ip, Operand(target, rmode), LeaveCC, cond);
     blx(ip, cond);
@@ -220,20 +220,20 @@
 
 void MacroAssembler::And(Register dst, Register src1, const Operand& src2,
                          Condition cond) {
-  if (!CpuFeatures::IsSupported(ARMv7) || src2.is_single_instruction()) {
-    and_(dst, src1, src2, LeaveCC, cond);
-    return;
-  }
-  int32_t immediate = src2.immediate();
-  if (immediate == 0) {
+  if (!src2.is_reg() &&
+      !src2.must_use_constant_pool() &&
+      src2.immediate() == 0) {
     mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond);
-    return;
+
+  } else if (!src2.is_single_instruction() &&
+             !src2.must_use_constant_pool() &&
+             CpuFeatures::IsSupported(ARMv7) &&
+             IsPowerOf2(src2.immediate() + 1)) {
+    ubfx(dst, src1, 0, WhichPowerOf2(src2.immediate() + 1), cond);
+
+  } else {
+    and_(dst, src1, src2, LeaveCC, cond);
   }
-  if (IsPowerOf2(immediate + 1) && ((immediate & 1) != 0)) {
-    ubfx(dst, src1, 0, WhichPowerOf2(immediate + 1), cond);
-    return;
-  }
-  and_(dst, src1, src2, LeaveCC, cond);
 }
 
 
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index 534e394..cb91520 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -112,15 +112,29 @@
 
 
 void Debugger::Stop(Instr* instr) {
-  char* str = reinterpret_cast<char*>(instr->InstructionBits() & 0x0fffffff);
-  if (strlen(str) > 0) {
+  // Get the stop code.
+  uint32_t code = instr->SvcField() & kStopCodeMask;
+  // Retrieve the encoded address, which comes just after this stop.
+  char** msg_address =
+    reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
+  char* msg = *msg_address;
+  ASSERT(msg != NULL);
+
+  // Update this stop description.
+  if (isWatchedStop(code) && !watched_stops[code].desc) {
+    watched_stops[code].desc = msg;
+  }
+
+  if (strlen(msg) > 0) {
     if (coverage_log != NULL) {
-      fprintf(coverage_log, "%s\n", str);
+      fprintf(coverage_log, "%s\n", msg);
       fflush(coverage_log);
     }
-    instr->SetInstructionBits(0xe1a00000);  // Overwrite with nop.
+    // Overwrite the instruction and address with nops.
+    instr->SetInstructionBits(kNopInstr);
+    reinterpret_cast<Instr*>(msg_address)->SetInstructionBits(kNopInstr);
   }
-  sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
+  sim_->set_pc(sim_->get_pc() + 2 * Instr::kInstrSize);
 }
 
 #else  // ndef GENERATED_CODE_COVERAGE
@@ -130,9 +144,16 @@
 
 
 void Debugger::Stop(Instr* instr) {
-  const char* str = (const char*)(instr->InstructionBits() & 0x0fffffff);
-  PrintF("Simulator hit %s\n", str);
-  sim_->set_pc(sim_->get_pc() + Instr::kInstrSize);
+  // Get the stop code.
+  uint32_t code = instr->SvcField() & kStopCodeMask;
+  // Retrieve the encoded address, which comes just after this stop.
+  char* msg = *reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize);
+  // Update this stop description.
+  if (sim_->isWatchedStop(code) && !sim_->watched_stops[code].desc) {
+    sim_->watched_stops[code].desc = msg;
+  }
+  PrintF("Simulator hit %s\n", msg);
+  sim_->set_pc(sim_->get_pc() + 2 * Instr::kInstrSize);
   Debug();
 }
 #endif
@@ -359,6 +380,7 @@
         // use a reasonably large buffer
         v8::internal::EmbeddedVector<char, 256> buffer;
 
+        byte* prev = NULL;
         byte* cur = NULL;
         byte* end = NULL;
 
@@ -368,9 +390,9 @@
         } else if (argc == 2) {
           int32_t value;
           if (GetValue(arg1, &value)) {
-            cur = reinterpret_cast<byte*>(value);
-            // no length parameter passed, assume 10 instructions
-            end = cur + (10 * Instr::kInstrSize);
+            cur = reinterpret_cast<byte*>(sim_->get_pc());
+            // Disassemble <arg1> instructions.
+            end = cur + (value * Instr::kInstrSize);
           }
         } else {
           int32_t value1;
@@ -382,10 +404,10 @@
         }
 
         while (cur < end) {
-          dasm.InstructionDecode(buffer, cur);
+          prev = cur;
+          cur += dasm.InstructionDecode(buffer, cur);
           PrintF("  0x%08x  %s\n",
-                 reinterpret_cast<intptr_t>(cur), buffer.start());
-          cur += Instr::kInstrSize;
+                 reinterpret_cast<intptr_t>(prev), buffer.start());
         }
       } else if (strcmp(cmd, "gdb") == 0) {
         PrintF("relinquishing control to gdb\n");
@@ -418,13 +440,58 @@
         PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_);
         PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_);
         PrintF("INEXACT flag: %d; ", sim_->inexact_vfp_flag_);
-      } else if (strcmp(cmd, "unstop") == 0) {
-        intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
+      } else if (strcmp(cmd, "stop") == 0) {
+        int32_t value;
+        intptr_t stop_pc = sim_->get_pc() - 2 * Instr::kInstrSize;
         Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
-        if (stop_instr->ConditionField() == special_condition) {
-          stop_instr->SetInstructionBits(kNopInstr);
+        Instr* msg_address =
+          reinterpret_cast<Instr*>(stop_pc + Instr::kInstrSize);
+        if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
+          // Remove the current stop.
+          if (sim_->isStopInstruction(stop_instr)) {
+            stop_instr->SetInstructionBits(kNopInstr);
+            msg_address->SetInstructionBits(kNopInstr);
+          } else {
+            PrintF("Not at debugger stop.\n");
+          }
+        } else if (argc == 3) {
+          // Print information about all/the specified breakpoint(s).
+          if (strcmp(arg1, "info") == 0) {
+            if (strcmp(arg2, "all") == 0) {
+              PrintF("Stop information:\n");
+              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
+                sim_->PrintStopInfo(i);
+              }
+            } else if (GetValue(arg2, &value)) {
+              sim_->PrintStopInfo(value);
+            } else {
+              PrintF("Unrecognized argument.\n");
+            }
+          } else if (strcmp(arg1, "enable") == 0) {
+            // Enable all/the specified breakpoint(s).
+            if (strcmp(arg2, "all") == 0) {
+              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
+                sim_->EnableStop(i);
+              }
+            } else if (GetValue(arg2, &value)) {
+              sim_->EnableStop(value);
+            } else {
+              PrintF("Unrecognized argument.\n");
+            }
+          } else if (strcmp(arg1, "disable") == 0) {
+            // Disable all/the specified breakpoint(s).
+            if (strcmp(arg2, "all") == 0) {
+              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
+                sim_->DisableStop(i);
+              }
+            } else if (GetValue(arg2, &value)) {
+              sim_->DisableStop(value);
+            } else {
+              PrintF("Unrecognized argument.\n");
+            }
+          }
         } else {
-          PrintF("Not at debugger stop.");
+          PrintF("Wrong usage. Use help command for more information.\n");
         }
       } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
         ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
@@ -455,11 +522,29 @@
         PrintF("  set a break point on the address\n");
         PrintF("del\n");
         PrintF("  delete the breakpoint\n");
-        PrintF("unstop\n");
-        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\n");
+        PrintF("stop feature:\n");
+        PrintF("  Description:\n");
+        PrintF("    Stops are debug instructions inserted by\n");
+        PrintF("    the Assembler::stop() function.\n");
+        PrintF("    When hitting a stop, the Simulator will\n");
+        PrintF("    stop and and give control to the Debugger.\n");
+        PrintF("    The first %d stop codes are watched:\n",
+               Simulator::kNumOfWatchedStops);
+        PrintF("    - They can be enabled / disabled: the Simulator\n");
+        PrintF("       will / won't stop when hitting them.\n");
+        PrintF("    - The Simulator keeps track of how many times they \n");
+        PrintF("      are met. (See the info command.) Going over a\n");
+        PrintF("      disabled stop still increases its counter. \n");
+        PrintF("  Commands:\n");
+        PrintF("    stop info all/<code> : print infos about number <code>\n");
+        PrintF("      or all stop(s).\n");
+        PrintF("    stop enable/disable all/<code> : enables / disables\n");
+        PrintF("      all or number <code> stop(s)\n");
+        PrintF("    stop unstop\n");
+        PrintF("      ignore the stop instruction at the current location\n");
+        PrintF("      from now on\n");
       } else {
         PrintF("Unknown command: %s\n", cmd);
       }
@@ -643,9 +728,9 @@
 // the simulator.  The external reference will be a function compiled for the
 // host architecture.  We need to call that function instead of trying to
 // execute it with the simulator.  We do that by redirecting the external
-// reference to a swi (software-interrupt) instruction that is handled by
+// reference to a svc (Supervisor Call) instruction that is handled by
 // the simulator.  We write the original destination of the jump just at a known
-// offset from the swi instruction so the simulator knows what to call.
+// offset from the svc instruction so the simulator knows what to call.
 class Redirection {
  public:
   Redirection(void* external_function, bool fp_return)
@@ -1434,8 +1519,8 @@
 // Software interrupt instructions are used by the simulator to call into the
 // C-based V8 runtime.
 void Simulator::SoftwareInterrupt(Instr* instr) {
-  int swi = instr->SwiField();
-  switch (swi) {
+  int svc = instr->SvcField();
+  switch (svc) {
     case call_rt_redirected: {
       // Check if stack is aligned. Error if not aligned is reported below to
       // include information on the function called.
@@ -1505,9 +1590,98 @@
       dbg.Debug();
       break;
     }
+    // stop uses all codes greater than 1 << 23.
     default: {
-      UNREACHABLE();
-      break;
+      if (svc >= (1 << 23)) {
+        uint32_t code = svc & kStopCodeMask;
+        if (isWatchedStop(code)) {
+          IncreaseStopCounter(code);
+        }
+        // Stop if it is enabled, otherwise go on jumping over the stop
+        // and the message address.
+        if (isEnabledStop(code)) {
+          Debugger dbg(this);
+          dbg.Stop(instr);
+        } else {
+          set_pc(get_pc() + 2 * Instr::kInstrSize);
+        }
+      } else {
+        // This is not a valid svc code.
+        UNREACHABLE();
+        break;
+      }
+    }
+  }
+}
+
+
+// Stop helper functions.
+bool Simulator::isStopInstruction(Instr* instr) {
+  return (instr->Bits(27, 24) == 0xF) && (instr->SvcField() >= stop);
+}
+
+
+bool Simulator::isWatchedStop(uint32_t code) {
+  ASSERT(code <= kMaxStopCode);
+  return code < kNumOfWatchedStops;
+}
+
+
+bool Simulator::isEnabledStop(uint32_t code) {
+  ASSERT(code <= kMaxStopCode);
+  // Unwatched stops are always enabled.
+  return !isWatchedStop(code) ||
+    !(watched_stops[code].count & kStopDisabledBit);
+}
+
+
+void Simulator::EnableStop(uint32_t code) {
+  ASSERT(isWatchedStop(code));
+  if (!isEnabledStop(code)) {
+    watched_stops[code].count &= ~kStopDisabledBit;
+  }
+}
+
+
+void Simulator::DisableStop(uint32_t code) {
+  ASSERT(isWatchedStop(code));
+  if (isEnabledStop(code)) {
+    watched_stops[code].count |= kStopDisabledBit;
+  }
+}
+
+
+void Simulator::IncreaseStopCounter(uint32_t code) {
+  ASSERT(code <= kMaxStopCode);
+  ASSERT(isWatchedStop(code));
+  if ((watched_stops[code].count & ~(1 << 31)) == 0x7fffffff) {
+    PrintF("Stop counter for code %i has overflowed.\n"
+           "Enabling this code and reseting the counter to 0.\n", code);
+    watched_stops[code].count = 0;
+    EnableStop(code);
+  } else {
+    watched_stops[code].count++;
+  }
+}
+
+
+// Print a stop status.
+void Simulator::PrintStopInfo(uint32_t code) {
+  ASSERT(code <= kMaxStopCode);
+  if (!isWatchedStop(code)) {
+    PrintF("Stop not watched.");
+  } else {
+    const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
+    int32_t count = watched_stops[code].count & ~kStopDisabledBit;
+    // Don't print the state of unused breakpoints.
+    if (count != 0) {
+      if (watched_stops[code].desc) {
+        PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n",
+               code, code, state, count, watched_stops[code].desc);
+      } else {
+        PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n",
+               code, code, state, count);
+      }
     }
   }
 }
@@ -2216,73 +2390,6 @@
 }
 
 
-void Simulator::DecodeUnconditional(Instr* instr) {
-  if (instr->Bits(7, 4) == 0x0B && instr->Bits(27, 25) == 0 && instr->HasL()) {
-    // Load halfword instruction, either register or immediate offset.
-    int rd = instr->RdField();
-    int rn = instr->RnField();
-    int32_t rn_val = get_register(rn);
-    int32_t addr = 0;
-    int32_t offset;
-    if (instr->Bit(22) == 0) {
-      // Register offset.
-      int rm = instr->RmField();
-      offset = get_register(rm);
-    } else {
-      // Immediate offset
-      offset = instr->Bits(3, 0) + (instr->Bits(11, 8) << 4);
-    }
-    switch (instr->PUField()) {
-      case 0: {
-        // Post index, negative.
-        ASSERT(!instr->HasW());
-        addr = rn_val;
-        rn_val -= offset;
-        set_register(rn, rn_val);
-        break;
-      }
-      case 1: {
-        // Post index, positive.
-        ASSERT(!instr->HasW());
-        addr = rn_val;
-        rn_val += offset;
-        set_register(rn, rn_val);
-        break;
-      }
-      case 2: {
-        // Pre index or offset, negative.
-        rn_val -= offset;
-        addr = rn_val;
-        if (instr->HasW()) {
-          set_register(rn, rn_val);
-        }
-        break;
-      }
-      case 3: {
-        // Pre index or offset, positive.
-        rn_val += offset;
-        addr = rn_val;
-        if (instr->HasW()) {
-          set_register(rn, rn_val);
-        }
-        break;
-      }
-      default: {
-        // The PU field is a 2-bit field.
-        UNREACHABLE();
-        break;
-      }
-    }
-    // Not sign extending, so load as unsigned.
-    uint16_t halfword = ReadH(addr, instr);
-    set_register(rd, halfword);
-  } else {
-    Debugger dbg(this);
-    dbg.Stop(instr);
-  }
-}
-
-
 // void Simulator::DecodeTypeVFP(Instr* instr)
 // The Following ARMv7 VFPv instructions are currently supported.
 // vmov :Sn = Rt
@@ -2655,7 +2762,7 @@
     PrintF("  0x%08x  %s\n", reinterpret_cast<intptr_t>(instr), buffer.start());
   }
   if (instr->ConditionField() == special_condition) {
-    DecodeUnconditional(instr);
+    UNIMPLEMENTED();
   } else if (ConditionallyExecute(instr)) {
     switch (instr->TypeField()) {
       case 0:
diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h
index e0658fc..3e02348 100644
--- a/src/arm/simulator-arm.h
+++ b/src/arm/simulator-arm.h
@@ -226,6 +226,15 @@
   void HandleRList(Instr* instr, bool load);
   void SoftwareInterrupt(Instr* instr);
 
+  // Stop helper functions.
+  inline bool isStopInstruction(Instr* instr);
+  inline bool isWatchedStop(uint32_t bkpt_code);
+  inline bool isEnabledStop(uint32_t bkpt_code);
+  inline void EnableStop(uint32_t bkpt_code);
+  inline void DisableStop(uint32_t bkpt_code);
+  inline void IncreaseStopCounter(uint32_t bkpt_code);
+  void PrintStopInfo(uint32_t code);
+
   // Read and write memory.
   inline uint8_t ReadBU(int32_t addr);
   inline int8_t ReadB(int32_t addr);
@@ -252,7 +261,6 @@
   void DecodeType5(Instr* instr);
   void DecodeType6(Instr* instr);
   void DecodeType7(Instr* instr);
-  void DecodeUnconditional(Instr* instr);
 
   // Support for VFP.
   void DecodeTypeVFP(Instr* instr);
@@ -317,6 +325,23 @@
   // Registered breakpoints.
   Instr* break_pc_;
   instr_t break_instr_;
+
+  // A stop is watched if its code is less than kNumOfWatchedStops.
+  // Only watched stops support enabling/disabling and the counter feature.
+  static const uint32_t kNumOfWatchedStops = 256;
+
+  // Breakpoint is disabled if bit 31 is set.
+  static const uint32_t kStopDisabledBit = 1 << 31;
+
+  // A stop is enabled, meaning the simulator will stop when meeting the
+  // instruction, if bit 31 of watched_stops[code].count is unset.
+  // The value watched_stops[code].count & ~(1 << 31) indicates how many times
+  // the breakpoint was hit or gone through.
+  struct StopCoundAndDesc {
+    uint32_t count;
+    char* desc;
+  };
+  StopCoundAndDesc watched_stops[kNumOfWatchedStops];
 };
 
 } }  // namespace assembler::arm
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index fbad669..5e29c2e 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -43,43 +43,49 @@
                        Code::Flags flags,
                        StubCache::Table table,
                        Register name,
-                       Register offset) {
+                       Register offset,
+                       Register scratch,
+                       Register scratch2) {
   ExternalReference key_offset(SCTableReference::keyReference(table));
   ExternalReference value_offset(SCTableReference::valueReference(table));
 
-  Label miss;
+  uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address());
+  uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address());
 
-  // Save the offset on the stack.
-  __ push(offset);
+  // Check the relative positions of the address fields.
+  ASSERT(value_off_addr > key_off_addr);
+  ASSERT((value_off_addr - key_off_addr) % 4 == 0);
+  ASSERT((value_off_addr - key_off_addr) < (256 * 4));
+
+  Label miss;
+  Register offsets_base_addr = scratch;
 
   // Check that the key in the entry matches the name.
-  __ mov(ip, Operand(key_offset));
-  __ ldr(ip, MemOperand(ip, offset, LSL, 1));
+  __ mov(offsets_base_addr, Operand(key_offset));
+  __ ldr(ip, MemOperand(offsets_base_addr, offset, LSL, 1));
   __ cmp(name, ip);
   __ b(ne, &miss);
 
   // Get the code entry from the cache.
-  __ mov(ip, Operand(value_offset));
-  __ ldr(offset, MemOperand(ip, offset, LSL, 1));
+  __ add(offsets_base_addr, offsets_base_addr,
+         Operand(value_off_addr - key_off_addr));
+  __ ldr(scratch2, MemOperand(offsets_base_addr, offset, LSL, 1));
 
   // Check that the flags match what we're looking for.
-  __ ldr(offset, FieldMemOperand(offset, Code::kFlagsOffset));
-  __ and_(offset, offset, Operand(~Code::kFlagsNotUsedInLookup));
-  __ cmp(offset, Operand(flags));
+  __ ldr(scratch2, FieldMemOperand(scratch2, Code::kFlagsOffset));
+  __ bic(scratch2, scratch2, Operand(Code::kFlagsNotUsedInLookup));
+  __ cmp(scratch2, Operand(flags));
   __ b(ne, &miss);
 
-  // Restore offset and re-load code entry from cache.
-  __ pop(offset);
-  __ mov(ip, Operand(value_offset));
-  __ ldr(offset, MemOperand(ip, offset, LSL, 1));
+  // Re-load code entry from cache.
+  __ ldr(offset, MemOperand(offsets_base_addr, offset, LSL, 1));
 
   // Jump to the first instruction in the code stub.
   __ add(offset, offset, Operand(Code::kHeaderSize - kHeapObjectTag));
   __ Jump(offset);
 
-  // Miss: Restore offset and fall through.
+  // Miss: fall through.
   __ bind(&miss);
-  __ pop(offset);
 }
 
 
@@ -201,7 +207,8 @@
                               Register receiver,
                               Register name,
                               Register scratch,
-                              Register extra) {
+                              Register extra,
+                              Register extra2) {
   Label miss;
 
   // Make sure that code is valid. The shifting code relies on the
@@ -214,6 +221,18 @@
   // Make sure that there are no register conflicts.
   ASSERT(!scratch.is(receiver));
   ASSERT(!scratch.is(name));
+  ASSERT(!extra.is(receiver));
+  ASSERT(!extra.is(name));
+  ASSERT(!extra.is(scratch));
+  ASSERT(!extra2.is(receiver));
+  ASSERT(!extra2.is(name));
+  ASSERT(!extra2.is(scratch));
+  ASSERT(!extra2.is(extra));
+
+  // Check scratch, extra and extra2 registers are valid.
+  ASSERT(!scratch.is(no_reg));
+  ASSERT(!extra.is(no_reg));
+  ASSERT(!extra2.is(no_reg));
 
   // Check that the receiver isn't a smi.
   __ tst(receiver, Operand(kSmiTagMask));
@@ -229,7 +248,7 @@
           Operand((kPrimaryTableSize - 1) << kHeapObjectTagSize));
 
   // Probe the primary table.
-  ProbeTable(masm, flags, kPrimary, name, scratch);
+  ProbeTable(masm, flags, kPrimary, name, scratch, extra, extra2);
 
   // Primary miss: Compute hash for secondary probe.
   __ sub(scratch, scratch, Operand(name));
@@ -239,7 +258,7 @@
           Operand((kSecondaryTableSize - 1) << kHeapObjectTagSize));
 
   // Probe the secondary table.
-  ProbeTable(masm, flags, kSecondary, name, scratch);
+  ProbeTable(masm, flags, kSecondary, name, scratch, extra, extra2);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/assembler.cc b/src/assembler.cc
index ce90dce..7493673 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -804,4 +804,53 @@
 }
 #endif
 
+
+void PositionsRecorder::RecordPosition(int pos,
+                                       PositionRecordingType recording_type) {
+  ASSERT(pos != RelocInfo::kNoPosition);
+  ASSERT(pos >= 0);
+  current_position_ = pos;
+  current_position_recording_type_ = recording_type;
+}
+
+
+void PositionsRecorder::RecordStatementPosition(int pos) {
+  ASSERT(pos != RelocInfo::kNoPosition);
+  ASSERT(pos >= 0);
+  current_statement_position_ = pos;
+}
+
+
+bool PositionsRecorder::WriteRecordedPositions() {
+  bool written = false;
+
+  // Write the statement position if it is different from what was written last
+  // time.
+  if (current_statement_position_ != written_statement_position_) {
+    EnsureSpace ensure_space(assembler_);
+    assembler_->RecordRelocInfo(RelocInfo::STATEMENT_POSITION,
+                                current_statement_position_);
+    written_statement_position_ = current_statement_position_;
+    written = true;
+  }
+
+  // Write the position if it is different from what was written last time and
+  // also different from the written statement position or was forced.
+  if (current_position_ != written_position_ &&
+      (current_position_ != current_statement_position_ || !written) &&
+      (current_position_ != written_statement_position_
+       || current_position_recording_type_ == FORCED_POSITION)) {
+    EnsureSpace ensure_space(assembler_);
+    assembler_->RecordRelocInfo(RelocInfo::POSITION, current_position_);
+    written_position_ = current_position_;
+    written = true;
+  }
+
+  current_position_recording_type_ = NORMAL_POSITION;
+
+  // Return whether something was written.
+  return written;
+}
+
+
 } }  // namespace v8::internal
diff --git a/src/assembler.h b/src/assembler.h
index 6681177..09159fe 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -585,6 +585,67 @@
 
 
 // -----------------------------------------------------------------------------
+// Position recording support
+
+enum PositionRecordingType { FORCED_POSITION, NORMAL_POSITION };
+
+class PositionsRecorder BASE_EMBEDDED {
+ public:
+  explicit PositionsRecorder(Assembler* assembler)
+      : assembler_(assembler),
+        current_position_(RelocInfo::kNoPosition),
+        current_position_recording_type_(NORMAL_POSITION),
+        written_position_(RelocInfo::kNoPosition),
+        current_statement_position_(RelocInfo::kNoPosition),
+        written_statement_position_(RelocInfo::kNoPosition) { }
+
+  // Set current position to pos. If recording_type is FORCED_POSITION then
+  // WriteRecordedPositions will write this position even if it is equal to
+  // statement position previously written for another pc.
+  void RecordPosition(int pos,
+                      PositionRecordingType recording_type = NORMAL_POSITION);
+
+  // Set current statement position to pos.
+  void RecordStatementPosition(int pos);
+
+  // Write recorded positions to relocation information.
+  bool WriteRecordedPositions();
+
+  int current_position() const { return current_position_; }
+
+  int current_statement_position() const { return current_statement_position_; }
+
+ private:
+  Assembler* assembler_;
+
+  int current_position_;
+  PositionRecordingType current_position_recording_type_;
+  int written_position_;
+
+  int current_statement_position_;
+  int written_statement_position_;
+};
+
+
+class PreserveStatementPositionScope BASE_EMBEDDED {
+ public:
+  explicit PreserveStatementPositionScope(PositionsRecorder* positions_recorder)
+      : positions_recorder_(positions_recorder),
+        statement_position_(positions_recorder->current_statement_position()) {}
+
+  ~PreserveStatementPositionScope() {
+    if (statement_position_ != RelocInfo::kNoPosition) {
+      positions_recorder_->RecordStatementPosition(statement_position_);
+    }
+  }
+
+ private:
+  PositionsRecorder* positions_recorder_;
+  int statement_position_;
+};
+
+
+// -----------------------------------------------------------------------------
 // Utility functions
 
 static inline bool is_intn(int x, int n)  {
diff --git a/src/ast.cc b/src/ast.cc
index 92f1496..bb445c4 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -140,6 +140,7 @@
 
 
 ObjectLiteral::Property::Property(Literal* key, Expression* value) {
+  emit_store_ = true;
   key_ = key;
   value_ = value;
   Object* k = *key->handle();
@@ -156,6 +157,7 @@
 
 
 ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) {
+  emit_store_ = true;
   key_ = new Literal(value->name());
   value_ = value;
   kind_ = is_getter ? GETTER : SETTER;
@@ -169,6 +171,78 @@
 }
 
 
+void ObjectLiteral::Property::set_emit_store(bool emit_store) {
+  emit_store_ = emit_store;
+}
+
+
+bool ObjectLiteral::Property::emit_store() {
+  return emit_store_;
+}
+
+
+bool IsEqualString(void* first, void* second) {
+  Handle<String> h1(reinterpret_cast<String**>(first));
+  Handle<String> h2(reinterpret_cast<String**>(second));
+  return (*h1)->Equals(*h2);
+}
+
+bool IsEqualSmi(void* first, void* second) {
+  Handle<Smi> h1(reinterpret_cast<Smi**>(first));
+  Handle<Smi> h2(reinterpret_cast<Smi**>(second));
+  return (*h1)->value() == (*h2)->value();
+}
+
+void ObjectLiteral::CalculateEmitStore() {
+  HashMap properties(&IsEqualString);
+  HashMap elements(&IsEqualSmi);
+  for (int i = this->properties()->length() - 1; i >= 0; i--) {
+    ObjectLiteral::Property* property = this->properties()->at(i);
+    Literal* literal = property->key();
+    Handle<Object> handle = literal->handle();
+
+    if (handle->IsNull()) {
+      continue;
+    }
+
+    uint32_t hash;
+    HashMap* table;
+    void* key;
+    uint32_t index;
+    if (handle->IsSymbol()) {
+      Handle<String> name(String::cast(*handle));
+      ASSERT(!name->AsArrayIndex(&index));
+      key = name.location();
+      hash = name->Hash();
+      table = &properties;
+    } else if (handle->ToArrayIndex(&index)) {
+      key = handle.location();
+      hash = index;
+      table = &elements;
+    } else {
+      ASSERT(handle->IsNumber());
+      double num = handle->Number();
+      char arr[100];
+      Vector<char> buffer(arr, ARRAY_SIZE(arr));
+      const char* str = DoubleToCString(num, buffer);
+      Handle<String> name = Factory::NewStringFromAscii(CStrVector(str));
+      key = name.location();
+      hash = name->Hash();
+      table = &properties;
+    }
+    // If the key of a computed property is in the table, do not emit
+    // a store for the property later.
+    if (property->kind() == ObjectLiteral::Property::COMPUTED) {
+      if (table->Lookup(literal, hash, false) != NULL) {
+        property->set_emit_store(false);
+      }
+    }
+    // Add key to the table.
+    table->Lookup(literal, hash, true);
+  }
+}
+
+
 void TargetCollector::AddTarget(BreakTarget* target) {
   // Add the label to the collector, but discard duplicates.
   int length = targets_->length();
diff --git a/src/ast.h b/src/ast.h
index a01e48d..04c2977 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -832,10 +832,14 @@
 
     bool IsCompileTimeValue();
 
+    void set_emit_store(bool emit_store);
+    bool emit_store();
+
    private:
     Literal* key_;
     Expression* value_;
     Kind kind_;
+    bool emit_store_;
   };
 
   ObjectLiteral(Handle<FixedArray> constant_properties,
@@ -858,6 +862,12 @@
 
   bool fast_elements() const { return fast_elements_; }
 
+
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  void CalculateEmitStore();
+
  private:
   Handle<FixedArray> constant_properties_;
   ZoneList<Property*>* properties_;
diff --git a/src/builtins.cc b/src/builtins.cc
index 52d5530..aede302 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1014,20 +1014,18 @@
     Object* data_obj = call_data->data();
     Object* result;
 
-    Handle<Object> data_handle(data_obj);
-    v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
-    ASSERT(raw_holder->IsJSObject());
-    v8::Local<v8::Function> callee = v8::Utils::ToLocal(function);
-    Handle<JSObject> holder_handle(JSObject::cast(raw_holder));
-    v8::Local<v8::Object> holder = v8::Utils::ToLocal(holder_handle);
     LOG(ApiObjectAccess("call", JSObject::cast(*args.receiver())));
+    ASSERT(raw_holder->IsJSObject());
+
+    CustomArguments custom;
+    v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
+        data_obj, *function, raw_holder);
+
     v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
-        data,
-        holder,
-        callee,
-        is_construct,
-        reinterpret_cast<void**>(&args[0] - 1),
-        args.length() - 1);
+        custom.end(),
+        &args[0] - 1,
+        args.length() - 1,
+        is_construct);
 
     v8::Handle<v8::Value> value;
     {
@@ -1089,26 +1087,22 @@
 
   Handle<JSFunction> function = args.at<JSFunction>(args_length);
   Object* callback_obj = args[args_length + 1];
-  Handle<Object> data_handle = args.at<Object>(args_length + 2);
+  Handle<Object> data = args.at<Object>(args_length + 2);
   Handle<JSObject> checked_holder = args.at<JSObject>(args_length + 3);
 
 #ifdef DEBUG
   VerifyTypeCheck(checked_holder, function);
 #endif
 
-  v8::Local<v8::Object> holder = v8::Utils::ToLocal(checked_holder);
-  v8::Local<v8::Function> callee = v8::Utils::ToLocal(function);
-  v8::InvocationCallback callback =
-      v8::ToCData<v8::InvocationCallback>(callback_obj);
-  v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
+  CustomArguments custom;
+  v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
+      *data, *function, *checked_holder);
 
   v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
-      data,
-      holder,
-      callee,
-      is_construct,
-      reinterpret_cast<void**>(&args[0] - 1),
-      args_length - 1);
+      custom.end(),
+      &args[0] - 1,
+      args_length - 1,
+      is_construct);
 
   HandleScope scope;
   Object* result;
@@ -1119,6 +1113,9 @@
 #ifdef ENABLE_LOGGING_AND_PROFILING
     state.set_external_callback(v8::ToCData<Address>(callback_obj));
 #endif
+    v8::InvocationCallback callback =
+        v8::ToCData<v8::InvocationCallback>(callback_obj);
+
     value = callback(new_args);
   }
   if (value.IsEmpty()) {
@@ -1161,23 +1158,20 @@
       v8::ToCData<v8::InvocationCallback>(callback_obj);
 
   // Get the data for the call and perform the callback.
-  Object* data_obj = call_data->data();
   Object* result;
-  { HandleScope scope;
-    v8::Local<v8::Object> self =
-        v8::Utils::ToLocal(Handle<JSObject>::cast(args.receiver()));
-    Handle<Object> data_handle(data_obj);
-    v8::Local<v8::Value> data = v8::Utils::ToLocal(data_handle);
-    Handle<JSFunction> callee_handle(constructor);
-    v8::Local<v8::Function> callee = v8::Utils::ToLocal(callee_handle);
-    LOG(ApiObjectAccess("call non-function", JSObject::cast(*args.receiver())));
+  {
+    HandleScope scope;
+
+    LOG(ApiObjectAccess("call non-function", obj));
+
+    CustomArguments custom;
+    v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
+        call_data->data(), constructor, obj);
     v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
-        data,
-        self,
-        callee,
-        is_construct_call,
-        reinterpret_cast<void**>(&args[0] - 1),
-        args.length() - 1);
+        custom.end(),
+        &args[0] - 1,
+        args.length() - 1,
+        is_construct_call);
     v8::Handle<v8::Value> value;
     {
       // Leaving JavaScript.
diff --git a/src/checks.cc b/src/checks.cc
index b5df316..1ab8802 100644
--- a/src/checks.cc
+++ b/src/checks.cc
@@ -98,3 +98,12 @@
   i::OS::PrintError("\n#\n\n");
   i::OS::Abort();
 }
+
+
+namespace v8 { namespace internal {
+
+  bool EnableSlowAsserts() { return FLAG_enable_slow_asserts; }
+
+  intptr_t HeapObjectTagMask() { return kHeapObjectTagMask; }
+
+} }  // namespace v8::internal
diff --git a/src/checks.h b/src/checks.h
index 5ea5992..e070477 100644
--- a/src/checks.h
+++ b/src/checks.h
@@ -30,7 +30,7 @@
 
 #include <string.h>
 
-#include "flags.h"
+#include "../include/v8stdint.h"
 
 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
 void API_Fatal(const char* location, const char* format, ...);
@@ -279,6 +279,12 @@
     SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__)
 
 
+namespace v8 { namespace internal {
+
+bool EnableSlowAsserts();
+
+} }  // namespace v8::internal
+
 // The ASSERT macro is equivalent to CHECK except that it only
 // generates code in debug builds.
 #ifdef DEBUG
@@ -287,7 +293,7 @@
 #define ASSERT_EQ(v1, v2)    CHECK_EQ(v1, v2)
 #define ASSERT_NE(v1, v2)    CHECK_NE(v1, v2)
 #define ASSERT_GE(v1, v2)    CHECK_GE(v1, v2)
-#define SLOW_ASSERT(condition) if (FLAG_enable_slow_asserts) CHECK(condition)
+#define SLOW_ASSERT(condition) if (EnableSlowAsserts()) CHECK(condition)
 #else
 #define ASSERT_RESULT(expr)     (expr)
 #define ASSERT(condition)      ((void) 0)
@@ -303,11 +309,16 @@
 // and release compilation modes behaviour.
 #define STATIC_ASSERT(test)  STATIC_CHECK(test)
 
+namespace v8 { namespace internal {
+
+intptr_t HeapObjectTagMask();
+
+} }  // namespace v8::internal
 
 #define ASSERT_TAG_ALIGNED(address) \
-  ASSERT((reinterpret_cast<intptr_t>(address) & kHeapObjectTagMask) == 0)
+  ASSERT((reinterpret_cast<intptr_t>(address) & HeapObjectTagMask()) == 0)
 
-#define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & kHeapObjectTagMask) == 0)
+#define ASSERT_SIZE_TAG_ALIGNED(size) ASSERT((size & HeapObjectTagMask()) == 0)
 
 #define ASSERT_NOT_NULL(p)  ASSERT_NE(NULL, p)
 
diff --git a/src/codegen.cc b/src/codegen.cc
index bda697a..2e32418 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -70,9 +70,10 @@
     DeferredCode* code = deferred_.RemoveLast();
     ASSERT(masm_ == code->masm());
     // Record position of deferred code stub.
-    masm_->RecordStatementPosition(code->statement_position());
+    masm_->positions_recorder()->RecordStatementPosition(
+        code->statement_position());
     if (code->position() != RelocInfo::kNoPosition) {
-      masm_->RecordPosition(code->position());
+      masm_->positions_recorder()->RecordPosition(code->position());
     }
     // Generate the code.
     Comment cmnt(masm_, code->comment());
@@ -402,10 +403,10 @@
                                     int pos,
                                     bool right_here) {
   if (pos != RelocInfo::kNoPosition) {
-    masm->RecordStatementPosition(pos);
-    masm->RecordPosition(pos);
+    masm->positions_recorder()->RecordStatementPosition(pos);
+    masm->positions_recorder()->RecordPosition(pos);
     if (right_here) {
-      return masm->WriteRecordedPositions();
+      return masm->positions_recorder()->WriteRecordedPositions();
     }
   }
   return false;
@@ -435,7 +436,7 @@
 
 void CodeGenerator::CodeForSourcePosition(int pos) {
   if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
-    masm()->RecordPosition(pos);
+    masm()->positions_recorder()->RecordPosition(pos);
   }
 }
 
diff --git a/src/compiler.cc b/src/compiler.cc
index 6cc0971..29bbbc7 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -152,10 +152,8 @@
   script->set_context_data((*i::Top::global_context())->data());
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  if (info->is_eval() || info->is_json()) {
-    Script::CompilationType compilation_type = info->is_json()
-        ? Script::COMPILATION_TYPE_JSON
-        : Script::COMPILATION_TYPE_EVAL;
+  if (info->is_eval()) {
+    Script::CompilationType compilation_type = Script::COMPILATION_TYPE_EVAL;
     script->set_compilation_type(Smi::FromInt(compilation_type));
     // For eval scripts add information on the function from which eval was
     // called.
@@ -178,7 +176,7 @@
   // Only allow non-global compiles for eval.
   ASSERT(info->is_eval() || info->is_global());
 
-  if (!Parser::Parse(info)) return Handle<SharedFunctionInfo>::null();
+  if (!ParserApi::Parse(info)) return Handle<SharedFunctionInfo>::null();
 
   // Measure how long it takes to do the compilation; only take the
   // rest of the function into account to avoid overlap with the
@@ -281,9 +279,8 @@
     // in that case too.
     ScriptDataImpl* pre_data = input_pre_data;
     if (pre_data == NULL
-        && FLAG_lazy
         && source_length >= FLAG_min_preparse_length) {
-      pre_data = Parser::PartialPreParse(source, NULL, extension);
+      pre_data = ParserApi::PartialPreParse(source, NULL, extension);
     }
 
     // Create a script object describing the script to be compiled.
@@ -323,13 +320,7 @@
 
 Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
                                                  Handle<Context> context,
-                                                 bool is_global,
-                                                 ValidationState validate) {
-  // Note that if validation is required then no path through this function
-  // is allowed to return a value without validating that the input is legal
-  // json.
-  bool is_json = (validate == VALIDATE_JSON);
-
+                                                 bool is_global) {
   int source_length = source->length();
   Counters::total_eval_size.Increment(source_length);
   Counters::total_compile_size.Increment(source_length);
@@ -338,13 +329,9 @@
   VMState state(COMPILER);
 
   // Do a lookup in the compilation cache; if the entry is not there, invoke
-  // the compiler and add the result to the cache.  If we're evaluating json
-  // we bypass the cache since we can't be sure a potential value in the
-  // cache has been validated.
+  // the compiler and add the result to the cache.
   Handle<SharedFunctionInfo> result;
-  if (!is_json) {
-    result = CompilationCache::LookupEval(source, context, is_global);
-  }
+  result = CompilationCache::LookupEval(source, context, is_global);
 
   if (result.is_null()) {
     // Create a script object describing the script to be compiled.
@@ -352,12 +339,9 @@
     CompilationInfo info(script);
     info.MarkAsEval();
     if (is_global) info.MarkAsGlobal();
-    if (is_json) info.MarkAsJson();
     info.SetCallingContext(context);
     result = MakeFunctionInfo(&info);
-    if (!result.is_null() && !is_json) {
-      // For json it's unlikely that we'll ever see exactly the same string
-      // again so we don't use the compilation cache.
+    if (!result.is_null()) {
       CompilationCache::PutEval(source, context, is_global, result);
     }
   }
@@ -379,7 +363,7 @@
   Counters::total_compile_size.Increment(compiled_size);
 
   // Generate the AST for the lazily compiled function.
-  if (Parser::Parse(info)) {
+  if (ParserApi::Parse(info)) {
     // Measure how long it takes to do the lazy compilation; only take the
     // rest of the function into account to avoid overlap with the lazy
     // parsing statistics.
diff --git a/src/compiler.h b/src/compiler.h
index d6f4e69..20868e5 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -49,7 +49,6 @@
   bool is_lazy() const { return (flags_ & IsLazy::mask()) != 0; }
   bool is_eval() const { return (flags_ & IsEval::mask()) != 0; }
   bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; }
-  bool is_json() const { return (flags_ & IsJson::mask()) != 0; }
   bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; }
   FunctionLiteral* function() const { return function_; }
   Scope* scope() const { return scope_; }
@@ -69,10 +68,6 @@
     ASSERT(!is_lazy());
     flags_ |= IsGlobal::encode(true);
   }
-  void MarkAsJson() {
-    ASSERT(!is_lazy());
-    flags_ |= IsJson::encode(true);
-  }
   void MarkAsInLoop() {
     ASSERT(is_lazy());
     flags_ |= IsInLoop::encode(true);
@@ -108,16 +103,15 @@
   // Flags that can be set for eager compilation.
   class IsEval:   public BitField<bool, 1, 1> {};
   class IsGlobal: public BitField<bool, 2, 1> {};
-  class IsJson:   public BitField<bool, 3, 1> {};
   // Flags that can be set for lazy compilation.
-  class IsInLoop: public BitField<bool, 4, 1> {};
+  class IsInLoop: public BitField<bool, 3, 1> {};
 
   unsigned flags_;
 
   // Fields filled in by the compilation pipeline.
   // AST filled in by the parser.
   FunctionLiteral* function_;
-  // The scope of the function literal as a convenience.  Set to indidicate
+  // The scope of the function literal as a convenience.  Set to indicate
   // that scopes have been analyzed.
   Scope* scope_;
   // The compiled code.
@@ -153,8 +147,6 @@
 
 class Compiler : public AllStatic {
  public:
-  enum ValidationState { DONT_VALIDATE_JSON, VALIDATE_JSON };
-
   // All routines return a JSFunction.
   // If an error occurs an exception is raised and
   // the return handle contains NULL.
@@ -172,8 +164,7 @@
   // Compile a String source within a context for Eval.
   static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
                                                 Handle<Context> context,
-                                                bool is_global,
-                                                ValidationState validation);
+                                                bool is_global);
 
   // Compile from function info (used for lazy compilation). Returns true on
   // success and false if the compilation resulted in a stack overflow.
diff --git a/src/conversions.cc b/src/conversions.cc
index 790e807..4cc6744 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -816,7 +816,7 @@
 
 
 char* DoubleToFixedCString(double value, int f) {
-  const int kMaxDigitsBeforePoint = 20;
+  const int kMaxDigitsBeforePoint = 21;
   const double kFirstNonFixed = 1e21;
   const int kMaxDigitsAfterPoint = 20;
   ASSERT(f >= 0);
@@ -840,9 +840,9 @@
   // Find a sufficiently precise decimal representation of n.
   int decimal_point;
   int sign;
-  // Add space for the '.' and the '\0' byte.
+  // Add space for the '\0' byte.
   const int kDecimalRepCapacity =
-      kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 2;
+      kMaxDigitsBeforePoint + kMaxDigitsAfterPoint + 1;
   char decimal_rep[kDecimalRepCapacity];
   int decimal_rep_length;
   bool status = DoubleToAscii(value, DTOA_FIXED, f,
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index a0c6808..d091991 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -897,10 +897,6 @@
   return new FrameMirror(this.break_id, opt_index);
 };
 
-ExecutionState.prototype.cframesValue = function(opt_from_index, opt_to_index) {
-  return %GetCFrames(this.break_id);
-};
-
 ExecutionState.prototype.setSelectedFrame = function(index) {
   var i = %ToNumber(index);
   if (i < 0 || i >= this.frameCount()) throw new Error('Illegal frame index.');
@@ -1301,7 +1297,7 @@
   try {
     try {
       // Convert the JSON string to an object.
-      request = %CompileString('(' + json_request + ')', false)();
+      request = %CompileString('(' + json_request + ')')();
 
       // Create an initial response.
       response = this.createResponse(request);
@@ -1751,11 +1747,6 @@
 };
 
 
-DebugCommandProcessor.prototype.backtracec = function(cmd, args) {
-  return this.exec_state_.cframesValue();
-};
-
-
 DebugCommandProcessor.prototype.frameRequest_ = function(request, response) {
   // No frames no source.
   if (this.exec_state_.frameCount() == 0) {
@@ -2205,29 +2196,6 @@
   return r;
 };
 
-DebugCommandProcessor.prototype.formatCFrames = function(cframes_value) {
-  var result = "";
-  if (cframes_value == null || cframes_value.length == 0) {
-    result += "(stack empty)";
-  } else {
-    for (var i = 0; i < cframes_value.length; ++i) {
-      if (i != 0) result += "\n";
-      result += this.formatCFrame(cframes_value[i]);
-    }
-  }
-  return result;
-};
-
-
-DebugCommandProcessor.prototype.formatCFrame = function(cframe_value) {
-  var result = "";
-  result += "0x" + NumberToHex8Str(cframe_value.address);
-  if (!IS_UNDEFINED(cframe_value.text)) {
-    result += " " + cframe_value.text;
-  }
-  return result;
-}
-
 
 /**
  * Convert an Object to its debugger protocol representation. The representation
diff --git a/src/debug.cc b/src/debug.cc
index 5c6ddbe..f3bf954 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1464,8 +1464,7 @@
 // location.
 bool Debug::IsBreakStub(Code* code) {
   CodeStub::Major major_key = CodeStub::GetMajorKey(code);
-  return major_key == CodeStub::CallFunction ||
-         major_key == CodeStub::StackCheck;
+  return major_key == CodeStub::CallFunction;
 }
 
 
@@ -1503,8 +1502,7 @@
     return result;
   }
   if (code->kind() == Code::STUB) {
-    ASSERT(code->major_key() == CodeStub::CallFunction ||
-           code->major_key() == CodeStub::StackCheck);
+    ASSERT(code->major_key() == CodeStub::CallFunction);
     Handle<Code> result =
         Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak));
     return result;
@@ -1841,6 +1839,7 @@
 
 
 void Debug::ClearMirrorCache() {
+  PostponeInterruptsScope postpone;
   HandleScope scope;
   ASSERT(Top::context() == *Debug::debug_context());
 
diff --git a/src/execution.cc b/src/execution.cc
index 3bbac0f..885bf63 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -797,6 +797,7 @@
     if (result && !string->IsSymbol()) {
       i::ExternalStringTable::AddString(*string);
     }
+    if (!result) delete resource;
   } else {
     uc16* data = new uc16[string->length()];
     String::WriteToFlat(*string, data, 0, string->length());
@@ -806,6 +807,7 @@
     if (result && !string->IsSymbol()) {
       i::ExternalStringTable::AddString(*string);
     }
+    if (!result) delete resource;
   }
   if (!result) {
     return v8::ThrowException(v8::String::New("externalizeString() failed."));
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 2474c62..54501ec 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -140,6 +140,9 @@
 // codegen-ia32.cc / codegen-arm.cc
 DEFINE_bool(trace, false, "trace function calls")
 DEFINE_bool(defer_negation, true, "defer negation operation")
+DEFINE_bool(mask_constants_with_cookie,
+            true,
+            "use random jit cookie to mask large constants")
 
 // codegen.cc
 DEFINE_bool(lazy, true, "use lazy compilation")
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 97987c2..c770e18 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -563,9 +563,10 @@
 }
 
 
-void FullCodeGenerator::SetSourcePosition(int pos) {
+void FullCodeGenerator::SetSourcePosition(
+    int pos, PositionRecordingType recording_type) {
   if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
-    masm_->RecordPosition(pos);
+    masm_->positions_recorder()->RecordPosition(pos, recording_type);
   }
 }
 
@@ -1225,13 +1226,6 @@
 }
 
 
-void FullCodeGenerator::EmitRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT(args->length() == 1);
-  VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kRegExpCloneResult, 1);
-  context()->Plug(result_register());
-}
-
 #undef __
 
 
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 201507b..a3270aa 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -423,7 +423,9 @@
   void SetStatementPosition(Statement* stmt);
   void SetExpressionPosition(Expression* expr, int pos);
   void SetStatementPosition(int pos);
-  void SetSourcePosition(int pos);
+  void SetSourcePosition(
+      int pos,
+      PositionRecordingType recording_type = NORMAL_POSITION);
 
   // Non-local control flow support.
   void EnterFinallyBlock();
diff --git a/src/global-handles.cc b/src/global-handles.cc
index 9ede908..5339840 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -372,13 +372,14 @@
 
 int post_gc_processing_count = 0;
 
-void GlobalHandles::PostGarbageCollectionProcessing() {
+bool GlobalHandles::PostGarbageCollectionProcessing() {
   // Process weak global handle callbacks. This must be done after the
   // GC is completely done, because the callbacks may invoke arbitrary
   // API functions.
   // At the same time deallocate all DESTROYED nodes.
   ASSERT(Heap::gc_state() == Heap::NOT_IN_GC);
   const int initial_post_gc_processing_count = ++post_gc_processing_count;
+  bool next_gc_likely_to_collect_more = false;
   Node** p = &head_;
   while (*p != NULL) {
     if ((*p)->PostGarbageCollectionProcessing()) {
@@ -399,6 +400,7 @@
       }
       node->set_next_free(first_deallocated());
       set_first_deallocated(node);
+      next_gc_likely_to_collect_more = true;
     } else {
       p = (*p)->next_addr();
     }
@@ -407,6 +409,8 @@
   if (first_deallocated()) {
     first_deallocated()->set_next(head());
   }
+
+  return next_gc_likely_to_collect_more;
 }
 
 
diff --git a/src/global-handles.h b/src/global-handles.h
index 659f86e..37b2b44 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -96,7 +96,8 @@
   static bool IsWeak(Object** location);
 
   // Process pending weak handles.
-  static void PostGarbageCollectionProcessing();
+  // Returns true if next major GC is likely to collect more garbage.
+  static bool PostGarbageCollectionProcessing();
 
   // Iterates over all strong handles.
   static void IterateStrongRoots(ObjectVisitor* v);
diff --git a/src/globals.h b/src/globals.h
index c218f80..a74b6c7 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -193,10 +193,9 @@
 
 const int kCharSize     = sizeof(char);      // NOLINT
 const int kShortSize    = sizeof(short);     // NOLINT
-const int kIntSize      = sizeof(int);       // NOLINT
 const int kDoubleSize   = sizeof(double);    // NOLINT
-const int kPointerSize  = sizeof(void*);     // NOLINT
 const int kIntptrSize   = sizeof(intptr_t);  // NOLINT
+// kIntSize and kPointerSize are defined in include/v8.h.
 
 #if V8_HOST_ARCH_64_BIT
 const int kPointerSizeLog2 = 3;
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 15feb9d..ba50c0f 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -330,6 +330,11 @@
 }
 
 
+bool Heap::CollectGarbage(AllocationSpace space) {
+  return CollectGarbage(space, SelectGarbageCollector(space));
+}
+
+
 MaybeObject* Heap::PrepareForCompare(String* str) {
   // Always flatten small strings and force flattening of long strings
   // after we have accumulated a certain amount we failed to flatten.
@@ -413,7 +418,7 @@
     }                                                                     \
     if (!__maybe_object__->IsRetryAfterGC()) RETURN_EMPTY;                \
     Counters::gc_last_resort_from_handles.Increment();                    \
-    Heap::CollectAllGarbage(false);                                       \
+    Heap::CollectAllAvailableGarbage();                                   \
     {                                                                     \
       AlwaysAllocateScope __scope__;                                      \
       __maybe_object__ = FUNCTION_CALL;                                   \
diff --git a/src/heap.cc b/src/heap.cc
index fc90866..226a202 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -429,7 +429,31 @@
 }
 
 
-void Heap::CollectGarbage(AllocationSpace space) {
+void Heap::CollectAllAvailableGarbage() {
+  // Since we are ignoring the return value, the exact choice of space does
+  // not matter, so long as we do not specify NEW_SPACE, which would not
+  // cause a full GC.
+  MarkCompactCollector::SetForceCompaction(true);
+
+  // Major GC would invoke weak handle callbacks on weakly reachable
+  // handles, but won't collect weakly reachable objects until next
+  // major GC.  Therefore if we collect aggressively and weak handle callback
+  // has been invoked, we rerun major GC to release objects which become
+  // garbage.
+  // Note: as weak callbacks can execute arbitrary code, we cannot
+  // hope that eventually there will be no weak callbacks invocations.
+  // Therefore stop recollecting after several attempts.
+  const int kMaxNumberOfAttempts = 7;
+  for (int attempt = 0; attempt < kMaxNumberOfAttempts; attempt++) {
+    if (!CollectGarbage(OLD_POINTER_SPACE, MARK_COMPACTOR)) {
+      break;
+    }
+  }
+  MarkCompactCollector::SetForceCompaction(false);
+}
+
+
+bool Heap::CollectGarbage(AllocationSpace space, GarbageCollector collector) {
   // The VM is in the GC state until exiting this function.
   VMState state(GC);
 
@@ -442,13 +466,14 @@
   allocation_timeout_ = Max(6, FLAG_gc_interval);
 #endif
 
+  bool next_gc_likely_to_collect_more = false;
+
   { GCTracer tracer;
     GarbageCollectionPrologue();
     // The GC count was incremented in the prologue.  Tell the tracer about
     // it.
     tracer.set_gc_count(gc_count_);
 
-    GarbageCollector collector = SelectGarbageCollector(space);
     // Tell the tracer which collector we've selected.
     tracer.set_collector(collector);
 
@@ -456,7 +481,8 @@
         ? &Counters::gc_scavenger
         : &Counters::gc_compactor;
     rate->Start();
-    PerformGarbageCollection(collector, &tracer);
+    next_gc_likely_to_collect_more =
+        PerformGarbageCollection(collector, &tracer);
     rate->Stop();
 
     GarbageCollectionEpilogue();
@@ -467,6 +493,8 @@
   if (FLAG_log_gc) HeapProfiler::WriteSample();
   if (CpuProfiler::is_profiling()) CpuProfiler::ProcessMovedFunctions();
 #endif
+
+  return next_gc_likely_to_collect_more;
 }
 
 
@@ -581,25 +609,22 @@
 }
 
 
-class ClearThreadJSFunctionResultCachesVisitor: public ThreadVisitor  {
-  virtual void VisitThread(ThreadLocalTop* top) {
-    Context* context = top->context_;
-    if (context == NULL) return;
+void Heap::ClearJSFunctionResultCaches() {
+  if (Bootstrapper::IsActive()) return;
 
+  Object* context = global_contexts_list_;
+  while (!context->IsUndefined()) {
+    // Get the caches for this context:
     FixedArray* caches =
-      context->global()->global_context()->jsfunction_result_caches();
+      Context::cast(context)->jsfunction_result_caches();
+    // Clear the caches:
     int length = caches->length();
     for (int i = 0; i < length; i++) {
       JSFunctionResultCache::cast(caches->get(i))->Clear();
     }
+    // Get the next context:
+    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
   }
-};
-
-
-void Heap::ClearJSFunctionResultCaches() {
-  if (Bootstrapper::IsActive()) return;
-  ClearThreadJSFunctionResultCachesVisitor visitor;
-  ThreadManager::IterateArchivedThreads(&visitor);
 }
 
 
@@ -656,8 +681,10 @@
   survival_rate_ = survival_rate;
 }
 
-void Heap::PerformGarbageCollection(GarbageCollector collector,
+bool Heap::PerformGarbageCollection(GarbageCollector collector,
                                     GCTracer* tracer) {
+  bool next_gc_likely_to_collect_more = false;
+
   if (collector != SCAVENGER) {
     PROFILE(CodeMovingGCEvent());
   }
@@ -723,7 +750,8 @@
   if (collector == MARK_COMPACTOR) {
     DisableAssertNoAllocation allow_allocation;
     GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
-    GlobalHandles::PostGarbageCollectionProcessing();
+    next_gc_likely_to_collect_more =
+        GlobalHandles::PostGarbageCollectionProcessing();
   }
 
   // Update relocatables.
@@ -750,6 +778,8 @@
     global_gc_epilogue_callback_();
   }
   VerifySymbolTable();
+
+  return next_gc_likely_to_collect_more;
 }
 
 
diff --git a/src/heap.h b/src/heap.h
index 8ff2f5f..714bf0d 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -705,13 +705,22 @@
   static void GarbageCollectionEpilogue();
 
   // Performs garbage collection operation.
-  // Returns whether required_space bytes are available after the collection.
-  static void CollectGarbage(AllocationSpace space);
+  // Returns whether there is a chance that another major GC could
+  // collect more garbage.
+  static bool CollectGarbage(AllocationSpace space, GarbageCollector collector);
+
+  // Performs garbage collection operation.
+  // Returns whether there is a chance that another major GC could
+  // collect more garbage.
+  inline static bool CollectGarbage(AllocationSpace space);
 
   // Performs a full garbage collection. Force compaction if the
   // parameter is true.
   static void CollectAllGarbage(bool force_compaction);
 
+  // Last hope GC, should try to squeeze as much as possible.
+  static void CollectAllAvailableGarbage();
+
   // Notify the heap that a context has been disposed.
   static int NotifyContextDisposed() { return ++contexts_disposed_; }
 
@@ -1246,7 +1255,9 @@
   static GarbageCollector SelectGarbageCollector(AllocationSpace space);
 
   // Performs garbage collection
-  static void PerformGarbageCollection(GarbageCollector collector,
+  // Returns whether there is a chance another major GC could
+  // collect more garbage.
+  static bool PerformGarbageCollection(GarbageCollector collector,
                                        GCTracer* tracer);
 
   // Allocate an uninitialized object in map space.  The behavior is identical
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index 019f478..125f503 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -298,7 +298,8 @@
 // Spare buffer.
 byte* Assembler::spare_buffer_ = NULL;
 
-Assembler::Assembler(void* buffer, int buffer_size) {
+Assembler::Assembler(void* buffer, int buffer_size)
+    : positions_recorder_(this) {
   if (buffer == NULL) {
     // Do our own buffer management.
     if (buffer_size <= kMinimalBufferSize) {
@@ -339,10 +340,6 @@
   reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
 
   last_pc_ = NULL;
-  current_statement_position_ = RelocInfo::kNoPosition;
-  current_position_ = RelocInfo::kNoPosition;
-  written_statement_position_ = current_statement_position_;
-  written_position_ = current_position_;
 #ifdef GENERATED_CODE_COVERAGE
   InitCoverageLog();
 #endif
@@ -1581,7 +1578,7 @@
 
 
 void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
   ASSERT(RelocInfo::IsCodeTarget(rmode));
@@ -2464,14 +2461,14 @@
 
 
 void Assembler::RecordJSReturn() {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
   RecordRelocInfo(RelocInfo::JS_RETURN);
 }
 
 
 void Assembler::RecordDebugBreakSlot() {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
   RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
 }
@@ -2485,47 +2482,6 @@
 }
 
 
-void Assembler::RecordPosition(int pos) {
-  ASSERT(pos != RelocInfo::kNoPosition);
-  ASSERT(pos >= 0);
-  current_position_ = pos;
-}
-
-
-void Assembler::RecordStatementPosition(int pos) {
-  ASSERT(pos != RelocInfo::kNoPosition);
-  ASSERT(pos >= 0);
-  current_statement_position_ = pos;
-}
-
-
-bool Assembler::WriteRecordedPositions() {
-  bool written = false;
-
-  // Write the statement position if it is different from what was written last
-  // time.
-  if (current_statement_position_ != written_statement_position_) {
-    EnsureSpace ensure_space(this);
-    RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
-    written_statement_position_ = current_statement_position_;
-    written = true;
-  }
-
-  // Write the position if it is different from what was written last time and
-  // also different from the written statement position.
-  if (current_position_ != written_position_ &&
-      current_position_ != written_statement_position_) {
-    EnsureSpace ensure_space(this);
-    RecordRelocInfo(RelocInfo::POSITION, current_position_);
-    written_position_ = current_position_;
-    written = true;
-  }
-
-  // Return whether something was written.
-  return written;
-}
-
-
 void Assembler::GrowBuffer() {
   ASSERT(overflow());
   if (!own_buffer_) FATAL("external code buffer is too small");
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 5286788..624be0c 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -847,17 +847,11 @@
   // Use --debug_code to enable.
   void RecordComment(const char* msg);
 
-  void RecordPosition(int pos);
-  void RecordStatementPosition(int pos);
-  bool WriteRecordedPositions();
-
   // Writes a single word of data in the code stream.
   // Used for inline tables, e.g., jump-tables.
   void dd(uint32_t data, RelocInfo::Mode reloc_info);
 
   int pc_offset() const { return pc_ - buffer_; }
-  int current_statement_position() const { return current_statement_position_; }
-  int current_position() const { return current_position_; }
 
   // Check if there is less than kGap bytes available in the buffer.
   // If this is the case, we need to grow the buffer before emitting
@@ -869,6 +863,8 @@
 
   static bool IsNop(Address addr) { return *addr == 0x90; }
 
+  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
+
   // Avoid overflows for displacements etc.
   static const int kMaximalBufferSize = 512*MB;
   static const int kMinimalBufferSize = 4*KB;
@@ -947,11 +943,9 @@
   // push-pop elimination
   byte* last_pc_;
 
-  // source position information
-  int current_statement_position_;
-  int current_position_;
-  int written_statement_position_;
-  int written_position_;
+  PositionsRecorder positions_recorder_;
+
+  friend class PositionsRecorder;
 };
 
 
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index f2ac7f7..7295340 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -153,7 +153,8 @@
       in_safe_int32_mode_(false),
       safe_int32_mode_enabled_(true),
       function_return_is_shadowed_(false),
-      in_spilled_code_(false) {
+      in_spilled_code_(false),
+      jit_cookie_((FLAG_mask_constants_with_cookie) ? V8::Random() : 0) {
 }
 
 
@@ -3733,7 +3734,7 @@
   CodeForStatementPosition(node);
   Load(node->expression());
   Result return_value = frame_->Pop();
-  masm()->WriteRecordedPositions();
+  masm()->positions_recorder()->WriteRecordedPositions();
   if (function_return_is_shadowed_) {
     function_return_.Jump(&return_value);
   } else {
@@ -5363,16 +5364,16 @@
 void CodeGenerator::PushUnsafeSmi(Handle<Object> value) {
   ASSERT(value->IsSmi());
   int bits = reinterpret_cast<int>(*value);
-  __ push(Immediate(bits & 0x0000FFFF));
-  __ or_(Operand(esp, 0), Immediate(bits & 0xFFFF0000));
+  __ push(Immediate(bits ^ jit_cookie_));
+  __ xor_(Operand(esp, 0), Immediate(jit_cookie_));
 }
 
 
 void CodeGenerator::StoreUnsafeSmiToLocal(int offset, Handle<Object> value) {
   ASSERT(value->IsSmi());
   int bits = reinterpret_cast<int>(*value);
-  __ mov(Operand(ebp, offset), Immediate(bits & 0x0000FFFF));
-  __ or_(Operand(ebp, offset), Immediate(bits & 0xFFFF0000));
+  __ mov(Operand(ebp, offset), Immediate(bits ^ jit_cookie_));
+  __ xor_(Operand(ebp, offset), Immediate(jit_cookie_));
 }
 
 
@@ -5380,8 +5381,8 @@
   ASSERT(target.is_valid());
   ASSERT(value->IsSmi());
   int bits = reinterpret_cast<int>(*value);
-  __ Set(target, Immediate(bits & 0x0000FFFF));
-  __ or_(target, bits & 0xFFFF0000);
+  __ Set(target, Immediate(bits ^ jit_cookie_));
+  __ xor_(target, jit_cookie_);
 }
 
 
@@ -5559,6 +5560,11 @@
   }
   frame_->Push(&clone);
 
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  node->CalculateEmitStore();
+
   for (int i = 0; i < node->properties()->length(); i++) {
     ObjectLiteral::Property* property = node->properties()->at(i);
     switch (property->kind()) {
@@ -5573,24 +5579,32 @@
           // Duplicate the object as the IC receiver.
           frame_->Dup();
           Load(property->value());
-          Result ignored =
-              frame_->CallStoreIC(Handle<String>::cast(key), false);
-          // A test eax instruction following the store IC call would
-          // indicate the presence of an inlined version of the
-          // store. Add a nop to indicate that there is no such
-          // inlined version.
-          __ nop();
+          if (property->emit_store()) {
+            Result ignored =
+                frame_->CallStoreIC(Handle<String>::cast(key), false);
+            // A test eax instruction following the store IC call would
+            // indicate the presence of an inlined version of the
+            // store. Add a nop to indicate that there is no such
+            // inlined version.
+            __ nop();
+          } else {
+            frame_->Drop(2);
+          }
           break;
         }
         // Fall through
       }
       case ObjectLiteral::Property::PROTOTYPE: {
-        // Duplicate the object as an argument to the runtime call.
-        frame_->Dup();
-        Load(property->key());
-        Load(property->value());
-        Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3);
-        // Ignore the result.
+          // Duplicate the object as an argument to the runtime call.
+          frame_->Dup();
+          Load(property->key());
+          Load(property->value());
+          if (property->emit_store()) {
+            // Ignore the result.
+            Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3);
+          } else {
+            frame_->Drop(3);
+          }
         break;
       }
       case ObjectLiteral::Property::SETTER: {
@@ -7278,88 +7292,6 @@
 }
 
 
-void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT_EQ(1, args->length());
-
-  Load(args->at(0));
-  Result object_result = frame_->Pop();
-  object_result.ToRegister(eax);
-  object_result.Unuse();
-  {
-    VirtualFrame::SpilledScope spilled_scope;
-
-    Label done;
-
-    __ test(eax, Immediate(kSmiTagMask));
-    __ j(zero, &done);
-
-    // Load JSRegExpResult map into edx.
-    // Arguments to this function should be results of calling RegExp exec,
-    // which is either an unmodified JSRegExpResult or null. Anything not having
-    // the unmodified JSRegExpResult map is returned unmodified.
-    // This also ensures that elements are fast.
-    __ mov(edx, ContextOperand(esi, Context::GLOBAL_INDEX));
-    __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalContextOffset));
-    __ mov(edx, ContextOperand(edx, Context::REGEXP_RESULT_MAP_INDEX));
-    __ cmp(edx, FieldOperand(eax, HeapObject::kMapOffset));
-    __ j(not_equal, &done);
-
-    if (FLAG_debug_code) {
-      // Check that object really has empty properties array, as the map
-      // should guarantee.
-      __ cmp(FieldOperand(eax, JSObject::kPropertiesOffset),
-             Immediate(Factory::empty_fixed_array()));
-      __ Check(equal, "JSRegExpResult: default map but non-empty properties.");
-    }
-
-    DeferredAllocateInNewSpace* allocate_fallback =
-        new DeferredAllocateInNewSpace(JSRegExpResult::kSize,
-                                       ebx,
-                                       edx.bit() | eax.bit());
-
-    // All set, copy the contents to a new object.
-    __ AllocateInNewSpace(JSRegExpResult::kSize,
-                          ebx,
-                          ecx,
-                          no_reg,
-                          allocate_fallback->entry_label(),
-                          TAG_OBJECT);
-    __ bind(allocate_fallback->exit_label());
-
-    // Copy all fields from eax to ebx.
-    STATIC_ASSERT(JSRegExpResult::kSize % (2 * kPointerSize) == 0);
-    // There is an even number of fields, so unroll the loop once
-    // for efficiency.
-    for (int i = 0; i < JSRegExpResult::kSize; i += 2 * kPointerSize) {
-      STATIC_ASSERT(JSObject::kMapOffset % (2 * kPointerSize) == 0);
-      if (i != JSObject::kMapOffset) {
-        // The map was already loaded into edx.
-        __ mov(edx, FieldOperand(eax, i));
-      }
-      __ mov(ecx, FieldOperand(eax, i + kPointerSize));
-
-      STATIC_ASSERT(JSObject::kElementsOffset % (2 * kPointerSize) == 0);
-      if (i == JSObject::kElementsOffset) {
-        // If the elements array isn't empty, make it copy-on-write
-        // before copying it.
-        Label empty;
-        __ cmp(Operand(edx), Immediate(Factory::empty_fixed_array()));
-        __ j(equal, &empty);
-        __ mov(FieldOperand(edx, HeapObject::kMapOffset),
-               Immediate(Factory::fixed_cow_array_map()));
-        __ bind(&empty);
-      }
-      __ mov(FieldOperand(ebx, i), edx);
-      __ mov(FieldOperand(ebx, i + kPointerSize), ecx);
-    }
-    __ mov(eax, ebx);
-
-    __ bind(&done);
-  }
-  frame_->Push(eax);
-}
-
-
 class DeferredSearchCache: public DeferredCode {
  public:
   DeferredSearchCache(Register dst, Register cache, Register key)
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index b072409..5a12e10 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -697,11 +697,6 @@
   // Construct a RegExp exec result with two in-object properties.
   void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
 
-  // Clone the result of a regexp function.
-  // Must be an object created by GenerateRegExpConstructResult with
-  // no extra properties.
-  void GenerateRegExpCloneResult(ZoneList<Expression*>* args);
-
   // Support for fast native caches.
   void GenerateGetFromCache(ZoneList<Expression*>* args);
 
@@ -785,6 +780,11 @@
   // in a spilled state.
   bool in_spilled_code_;
 
+  // A cookie that is used for JIT IMM32 Encoding.  Initialized to a
+  // random number when the command-line
+  // FLAG_mask_constants_with_cookie is true, zero otherwise.
+  int jit_cookie_;
+
   friend class VirtualFrame;
   friend class JumpTarget;
   friend class Reference;
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 150df99..1ea719d 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1202,6 +1202,11 @@
   // result_saved is false the result is in eax.
   bool result_saved = false;
 
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  expr->CalculateEmitStore();
+
   for (int i = 0; i < expr->properties()->length(); i++) {
     ObjectLiteral::Property* property = expr->properties()->at(i);
     if (property->IsCompileTimeValue()) continue;
@@ -1221,8 +1226,10 @@
           VisitForAccumulatorValue(value);
           __ mov(ecx, Immediate(key->handle()));
           __ mov(edx, Operand(esp, 0));
-          Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
-          EmitCallIC(ic,  RelocInfo::CODE_TARGET);
+          if (property->emit_store()) {
+            Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+            EmitCallIC(ic, RelocInfo::CODE_TARGET);
+          }
           break;
         }
         // Fall through.
@@ -1230,7 +1237,11 @@
         __ push(Operand(esp, 0));  // Duplicate receiver.
         VisitForStackValue(key);
         VisitForStackValue(value);
-        __ CallRuntime(Runtime::kSetProperty, 3);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kSetProperty, 3);
+        } else {
+          __ Drop(3);
+        }
         break;
       case ObjectLiteral::Property::SETTER:
       case ObjectLiteral::Property::GETTER:
@@ -1985,12 +1996,14 @@
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+    __ Set(ecx, Immediate(name));
   }
-  __ Set(ecx, Immediate(name));
   // Record source position of the IC call.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop);
   EmitCallIC(ic, mode);
@@ -2006,13 +2019,15 @@
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+    VisitForAccumulatorValue(key);
+    __ mov(ecx, eax);
   }
-  VisitForAccumulatorValue(key);
-  __ mov(ecx, eax);
   // Record source position of the IC call.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(
       arg_count, in_loop);
@@ -2027,11 +2042,13 @@
   // Code common for calls using the call stub.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
   }
   // Record source position for debugger.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
   __ CallStub(&stub);
@@ -2051,37 +2068,39 @@
     // resolve the function we need to call and the receiver of the
     // call.  Then we call the resolved function using the given
     // arguments.
-    VisitForStackValue(fun);
-    __ push(Immediate(Factory::undefined_value()));  // Reserved receiver slot.
-
-    // Push the arguments.
     ZoneList<Expression*>* args = expr->arguments();
     int arg_count = args->length();
-    for (int i = 0; i < arg_count; i++) {
-      VisitForStackValue(args->at(i));
-    }
-
-    // Push copy of the function - found below the arguments.
-    __ push(Operand(esp, (arg_count + 1) * kPointerSize));
-
-    // Push copy of the first argument or undefined if it doesn't exist.
-    if (arg_count > 0) {
-      __ push(Operand(esp, arg_count * kPointerSize));
-    } else {
+    { PreserveStatementPositionScope pos_scope(masm()->positions_recorder());
+      VisitForStackValue(fun);
+      // Reserved receiver slot.
       __ push(Immediate(Factory::undefined_value()));
+
+      // Push the arguments.
+      for (int i = 0; i < arg_count; i++) {
+        VisitForStackValue(args->at(i));
+      }
+
+      // Push copy of the function - found below the arguments.
+      __ push(Operand(esp, (arg_count + 1) * kPointerSize));
+
+      // Push copy of the first argument or undefined if it doesn't exist.
+      if (arg_count > 0) {
+        __ push(Operand(esp, arg_count * kPointerSize));
+      } else {
+        __ push(Immediate(Factory::undefined_value()));
+      }
+
+      // Push the receiver of the enclosing function and do runtime call.
+      __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
+      __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
+
+      // The runtime call returns a pair of values in eax (function) and
+      // edx (receiver). Touch up the stack with the right values.
+      __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
+      __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
     }
-
-    // Push the receiver of the enclosing function and do runtime call.
-    __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize));
-    __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
-
-    // The runtime call returns a pair of values in eax (function) and
-    // edx (receiver). Touch up the stack with the right values.
-    __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
-    __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
-
     // Record source position for debugger.
-    SetSourcePosition(expr->position());
+    SetSourcePosition(expr->position(), FORCED_POSITION);
     InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
     CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
     __ CallStub(&stub);
@@ -2097,12 +2116,14 @@
     // Call to a lookup slot (dynamically introduced variable).
     Label slow, done;
 
-    // Generate code for loading from variables potentially shadowed
-    // by eval-introduced variables.
-    EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
-                                    NOT_INSIDE_TYPEOF,
-                                    &slow,
-                                    &done);
+    { PreserveStatementPositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
+                                      NOT_INSIDE_TYPEOF,
+                                      &slow,
+                                      &done);
+    }
 
     __ bind(&slow);
     // Call the runtime to find the function to call (returned in eax)
@@ -2141,11 +2162,15 @@
       // Call to a keyed property.
       // For a synthetic property use keyed load IC followed by function call,
       // for a regular property use keyed EmitCallIC.
-      VisitForStackValue(prop->obj());
+      { PreserveStatementPositionScope scope(masm()->positions_recorder());
+        VisitForStackValue(prop->obj());
+      }
       if (prop->is_synthetic()) {
-        VisitForAccumulatorValue(prop->key());
+        { PreserveStatementPositionScope scope(masm()->positions_recorder());
+          VisitForAccumulatorValue(prop->key());
+        }
         // Record source code position for IC call.
-        SetSourcePosition(prop->position());
+        SetSourcePosition(prop->position(), FORCED_POSITION);
         __ pop(edx);  // We do not need to keep the receiver.
 
         Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
@@ -2170,7 +2195,9 @@
         loop_depth() == 0) {
       lit->set_try_full_codegen(true);
     }
-    VisitForStackValue(fun);
+    { PreserveStatementPositionScope scope(masm()->positions_recorder());
+      VisitForStackValue(fun);
+    }
     // Load global receiver object.
     __ mov(ebx, CodeGenerator::GlobalObject());
     __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index b5f4dee..a0bc086 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -33,7 +33,6 @@
 #include "ic-inl.h"
 #include "runtime.h"
 #include "stub-cache.h"
-#include "utils.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 90dabed..042335a 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -206,8 +206,10 @@
                               Register receiver,
                               Register name,
                               Register scratch,
-                              Register extra) {
+                              Register extra,
+                              Register extra2) {
   Label miss;
+  USE(extra2);  // The register extra2 is not used on the ia32 platform.
 
   // Make sure that code is valid. The shifting code relies on the
   // entry size being 8.
@@ -223,6 +225,10 @@
   ASSERT(!extra.is(name));
   ASSERT(!extra.is(scratch));
 
+  // Check scratch and extra registers are valid, and extra2 is unused.
+  ASSERT(!scratch.is(no_reg));
+  ASSERT(extra2.is(no_reg));
+
   // Check that the receiver isn't a smi.
   __ test(receiver, Immediate(kSmiTagMask));
   __ j(zero, &miss, not_taken);
@@ -899,7 +905,7 @@
         MaybeObject* maybe_lookup_result = Heap::LookupSymbol(name);
         Object* lookup_result = NULL;  // Initialization to please compiler.
         if (!maybe_lookup_result->ToObject(&lookup_result)) {
-          set_failure(Failure::cast(lookup_result));
+          set_failure(Failure::cast(maybe_lookup_result));
           return reg;
         }
         name = String::cast(lookup_result);
@@ -1071,7 +1077,7 @@
   Object* result = NULL;  // Initialization to please compiler.
   { MaybeObject* try_call_result = masm()->TryCallStub(&stub);
     if (!try_call_result->ToObject(&result)) {
-      *failure = Failure::cast(result);
+      *failure = Failure::cast(try_call_result);
       return false;
     }
   }
diff --git a/src/json.js b/src/json.js
index a39d7c4..5993100 100644
--- a/src/json.js
+++ b/src/json.js
@@ -29,8 +29,7 @@
 
 function ParseJSONUnfiltered(text) {
   var s = $String(text);
-  var f = %CompileString(s, true);
-  return f();
+  return %ParseJson(s);
 }
 
 function Revive(holder, name, reviver) {
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 3c5ddfb..8cd13bc 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -125,7 +125,8 @@
   PostponeInterruptsScope postpone;
   RegExpCompileData parse_result;
   FlatStringReader reader(pattern);
-  if (!Parser::ParseRegExp(&reader, flags.is_multiline(), &parse_result)) {
+  if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
+                                 &parse_result)) {
     // Throw an exception if we fail to parse the pattern.
     ThrowRegExpException(re,
                          pattern,
@@ -267,7 +268,8 @@
 
   RegExpCompileData compile_data;
   FlatStringReader reader(pattern);
-  if (!Parser::ParseRegExp(&reader, flags.is_multiline(), &compile_data)) {
+  if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
+                                 &compile_data)) {
     // Throw an exception if we fail to parse the pattern.
     // THIS SHOULD NOT HAPPEN. We already pre-parsed it successfully once.
     ThrowRegExpException(re,
diff --git a/src/jump-target-heavy.cc b/src/jump-target-heavy.cc
index e0585e7..c3c22f1 100644
--- a/src/jump-target-heavy.cc
+++ b/src/jump-target-heavy.cc
@@ -414,8 +414,9 @@
 
 DeferredCode::DeferredCode()
     : masm_(CodeGeneratorScope::Current()->masm()),
-      statement_position_(masm_->current_statement_position()),
-      position_(masm_->current_position()),
+      statement_position_(masm_->positions_recorder()->
+                          current_statement_position()),
+      position_(masm_->positions_recorder()->current_position()),
       frame_state_(CodeGeneratorScope::Current()->frame()) {
   ASSERT(statement_position_ != RelocInfo::kNoPosition);
   ASSERT(position_ != RelocInfo::kNoPosition);
diff --git a/src/jump-target-light.cc b/src/jump-target-light.cc
index 19f7bfe..36dc176 100644
--- a/src/jump-target-light.cc
+++ b/src/jump-target-light.cc
@@ -36,8 +36,9 @@
 
 DeferredCode::DeferredCode()
     : masm_(CodeGeneratorScope::Current()->masm()),
-      statement_position_(masm_->current_statement_position()),
-      position_(masm_->current_position()),
+      statement_position_(masm_->positions_recorder()->
+                          current_statement_position()),
+      position_(masm_->positions_recorder()->current_position()),
       frame_state_(*CodeGeneratorScope::Current()->frame()) {
   ASSERT(statement_position_ != RelocInfo::kNoPosition);
   ASSERT(position_ != RelocInfo::kNoPosition);
diff --git a/src/liveedit.cc b/src/liveedit.cc
index 49f221a..642b3e6 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -404,7 +404,7 @@
   // Build AST.
   CompilationInfo info(script);
   info.MarkAsGlobal();
-  if (Parser::Parse(&info)) {
+  if (ParserApi::Parse(&info)) {
     // Compile the code.
     LiveEditFunctionTracker tracker(info.function());
     if (Compiler::MakeCodeForLiveEdit(&info)) {
diff --git a/src/log.cc b/src/log.cc
index 2cc2b8f..d12aafb 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -164,7 +164,10 @@
 
   int i = 0;
   const Address callback = VMState::external_callback();
-  if (callback != NULL) {
+  // Surprisingly, PC can point _exactly_ to callback start, with good
+  // probability, and this will result in reporting fake nested
+  // callback call.
+  if (callback != NULL && callback != sample->pc) {
     sample->stack[i++] = callback;
   }
 
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index faaacbc..91dec17 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -44,7 +44,8 @@
                               Register receiver,
                               Register name,
                               Register scratch,
-                              Register extra) {
+                              Register extra,
+                              Register extra2) {
   UNIMPLEMENTED_MIPS();
 }
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 4d21017..399ef35 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1952,7 +1952,9 @@
 void JSFunctionResultCache::Clear() {
   int cache_size = Smi::cast(get(kCacheSizeIndex))->value();
   Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
-  MemsetPointer(entries_start, Heap::the_hole_value(), cache_size);
+  MemsetPointer(entries_start,
+                Heap::the_hole_value(),
+                cache_size - kEntriesIndex);
   MakeZeroSize();
 }
 
@@ -2669,6 +2671,7 @@
 #else
 
 #define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)             \
+  STATIC_ASSERT(holder::offset % kPointerSize == 0);              \
   int holder::name() {                                            \
     int value = READ_INT_FIELD(this, offset);                     \
     ASSERT(kHeapObjectTag == 1);                                  \
@@ -2684,30 +2687,36 @@
                     (value << 1) & ~kHeapObjectTag);              \
   }
 
-#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
+#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset)             \
+  STATIC_ASSERT(holder::offset % kPointerSize == kIntSize);       \
   INT_ACCESSORS(holder, name, offset)
 
 
-
 PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
-PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, formal_parameter_count,
-              kFormalParameterCountOffset)
+PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
+                        formal_parameter_count,
+                        kFormalParameterCountOffset)
 
-PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, expected_nof_properties,
-              kExpectedNofPropertiesOffset)
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
+                        expected_nof_properties,
+                        kExpectedNofPropertiesOffset)
 PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
 
-PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, start_position_and_type,
-              kStartPositionAndTypeOffset)
-PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, end_position, kEndPositionOffset)
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
+PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
+                        start_position_and_type,
+                        kStartPositionAndTypeOffset)
 
-PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, function_token_position,
-              kFunctionTokenPositionOffset)
-PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, compiler_hints,
-              kCompilerHintsOffset)
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
+                        function_token_position,
+                        kFunctionTokenPositionOffset)
+PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
+                        compiler_hints,
+                        kCompilerHintsOffset)
 
-PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, this_property_assignments_count,
-              kThisPropertyAssignmentsCountOffset)
+PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
+                        this_property_assignments_count,
+                        kThisPropertyAssignmentsCountOffset)
 #endif
 
 
diff --git a/src/objects.h b/src/objects.h
index 87234ea..6029ad5 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -3409,8 +3409,7 @@
   // Script compilation types.
   enum CompilationType {
     COMPILATION_TYPE_HOST = 0,
-    COMPILATION_TYPE_EVAL = 1,
-    COMPILATION_TYPE_JSON = 2
+    COMPILATION_TYPE_EVAL = 1
   };
 
   // [source]: the script source.
diff --git a/src/parser.cc b/src/parser.cc
index 180d0d2..a0f3b71 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -36,9 +36,9 @@
 #include "messages.h"
 #include "parser.h"
 #include "platform.h"
+#include "preparser.h"
 #include "runtime.h"
 #include "scopeinfo.h"
-#include "scopes.h"
 #include "string-stream.h"
 
 #include "ast-inl.h"
@@ -87,112 +87,6 @@
 };
 
 
-template <typename T, int initial_size>
-class BufferedZoneList {
- public:
-  BufferedZoneList() : list_(NULL), last_(NULL) {}
-
-  // Adds element at end of list. This element is buffered and can
-  // be read using last() or removed using RemoveLast until a new Add or until
-  // RemoveLast or GetList has been called.
-  void Add(T* value) {
-    if (last_ != NULL) {
-      if (list_ == NULL) {
-        list_ = new ZoneList<T*>(initial_size);
-      }
-      list_->Add(last_);
-    }
-    last_ = value;
-  }
-
-  T* last() {
-    ASSERT(last_ != NULL);
-    return last_;
-  }
-
-  T* RemoveLast() {
-    ASSERT(last_ != NULL);
-    T* result = last_;
-    if (list_ != NULL && list_->length() > 0)
-      last_ = list_->RemoveLast();
-    else
-      last_ = NULL;
-    return result;
-  }
-
-  T* Get(int i) {
-    ASSERT(0 <= i && i < length());
-    if (list_ == NULL) {
-      ASSERT_EQ(0, i);
-      return last_;
-    } else {
-      if (i == list_->length()) {
-        ASSERT(last_ != NULL);
-        return last_;
-      } else {
-        return list_->at(i);
-      }
-    }
-  }
-
-  void Clear() {
-    list_ = NULL;
-    last_ = NULL;
-  }
-
-  int length() {
-    int length = (list_ == NULL) ? 0 : list_->length();
-    return length + ((last_ == NULL) ? 0 : 1);
-  }
-
-  ZoneList<T*>* GetList() {
-    if (list_ == NULL) {
-      list_ = new ZoneList<T*>(initial_size);
-    }
-    if (last_ != NULL) {
-      list_->Add(last_);
-      last_ = NULL;
-    }
-    return list_;
-  }
-
- private:
-  ZoneList<T*>* list_;
-  T* last_;
-};
-
-
-// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
-class RegExpBuilder: public ZoneObject {
- public:
-  RegExpBuilder();
-  void AddCharacter(uc16 character);
-  // "Adds" an empty expression. Does nothing except consume a
-  // following quantifier
-  void AddEmpty();
-  void AddAtom(RegExpTree* tree);
-  void AddAssertion(RegExpTree* tree);
-  void NewAlternative();  // '|'
-  void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type);
-  RegExpTree* ToRegExp();
- private:
-  void FlushCharacters();
-  void FlushText();
-  void FlushTerms();
-  bool pending_empty_;
-  ZoneList<uc16>* characters_;
-  BufferedZoneList<RegExpTree, 2> terms_;
-  BufferedZoneList<RegExpTree, 2> text_;
-  BufferedZoneList<RegExpTree, 2> alternatives_;
-#ifdef DEBUG
-  enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
-#define LAST(x) last_added_ = x;
-#else
-#define LAST(x)
-#endif
-};
-
-
 RegExpBuilder::RegExpBuilder()
   : pending_empty_(false),
     characters_(NULL),
@@ -352,124 +246,13 @@
 }
 
 
-class RegExpParser {
- public:
-  RegExpParser(FlatStringReader* in,
-               Handle<String>* error,
-               bool multiline_mode);
-  RegExpTree* ParsePattern();
-  RegExpTree* ParseDisjunction();
-  RegExpTree* ParseGroup();
-  RegExpTree* ParseCharacterClass();
-
-  // Parses a {...,...} quantifier and stores the range in the given
-  // out parameters.
-  bool ParseIntervalQuantifier(int* min_out, int* max_out);
-
-  // Parses and returns a single escaped character.  The character
-  // must not be 'b' or 'B' since they are usually handle specially.
-  uc32 ParseClassCharacterEscape();
-
-  // Checks whether the following is a length-digit hexadecimal number,
-  // and sets the value if it is.
-  bool ParseHexEscape(int length, uc32* value);
-
-  uc32 ParseControlLetterEscape();
-  uc32 ParseOctalLiteral();
-
-  // Tries to parse the input as a back reference.  If successful it
-  // stores the result in the output parameter and returns true.  If
-  // it fails it will push back the characters read so the same characters
-  // can be reparsed.
-  bool ParseBackReferenceIndex(int* index_out);
-
-  CharacterRange ParseClassAtom(uc16* char_class);
-  RegExpTree* ReportError(Vector<const char> message);
-  void Advance();
-  void Advance(int dist);
-  void Reset(int pos);
-
-  // Reports whether the pattern might be used as a literal search string.
-  // Only use if the result of the parse is a single atom node.
-  bool simple();
-  bool contains_anchor() { return contains_anchor_; }
-  void set_contains_anchor() { contains_anchor_ = true; }
-  int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
-  int position() { return next_pos_ - 1; }
-  bool failed() { return failed_; }
-
-  static const int kMaxCaptures = 1 << 16;
-  static const uc32 kEndMarker = (1 << 21);
-
- private:
-  enum SubexpressionType {
-    INITIAL,
-    CAPTURE,  // All positive values represent captures.
-    POSITIVE_LOOKAHEAD,
-    NEGATIVE_LOOKAHEAD,
-    GROUPING
-  };
-
-  class RegExpParserState : public ZoneObject {
-   public:
-    RegExpParserState(RegExpParserState* previous_state,
-                      SubexpressionType group_type,
-                      int disjunction_capture_index)
-        : previous_state_(previous_state),
-          builder_(new RegExpBuilder()),
-          group_type_(group_type),
-          disjunction_capture_index_(disjunction_capture_index) {}
-    // Parser state of containing expression, if any.
-    RegExpParserState* previous_state() { return previous_state_; }
-    bool IsSubexpression() { return previous_state_ != NULL; }
-    // RegExpBuilder building this regexp's AST.
-    RegExpBuilder* builder() { return builder_; }
-    // Type of regexp being parsed (parenthesized group or entire regexp).
-    SubexpressionType group_type() { return group_type_; }
-    // Index in captures array of first capture in this sub-expression, if any.
-    // Also the capture index of this sub-expression itself, if group_type
-    // is CAPTURE.
-    int capture_index() { return disjunction_capture_index_; }
-   private:
-    // Linked list implementation of stack of states.
-    RegExpParserState* previous_state_;
-    // Builder for the stored disjunction.
-    RegExpBuilder* builder_;
-    // Stored disjunction type (capture, look-ahead or grouping), if any.
-    SubexpressionType group_type_;
-    // Stored disjunction's capture index (if any).
-    int disjunction_capture_index_;
-  };
-
-  uc32 current() { return current_; }
-  bool has_more() { return has_more_; }
-  bool has_next() { return next_pos_ < in()->length(); }
-  uc32 Next();
-  FlatStringReader* in() { return in_; }
-  void ScanForCaptures();
-  uc32 current_;
-  bool has_more_;
-  bool multiline_;
-  int next_pos_;
-  FlatStringReader* in_;
-  Handle<String>* error_;
-  bool simple_;
-  bool contains_anchor_;
-  ZoneList<RegExpCapture*>* captures_;
-  bool is_scanned_for_captures_;
-  // The capture count is only valid after we have scanned for captures.
-  int capture_count_;
-  bool failed_;
-};
-
-
 // A temporary scope stores information during parsing, just like
 // a plain scope.  However, temporary scopes are not kept around
 // after parsing or referenced by syntax trees so they can be stack-
 // allocated and hence used by the pre-parser.
 class TemporaryScope BASE_EMBEDDED {
  public:
-  explicit TemporaryScope(Parser* parser);
+  explicit TemporaryScope(TemporaryScope** variable);
   ~TemporaryScope();
 
   int NextMaterializedLiteralIndex() {
@@ -518,326 +301,118 @@
   int loop_count_;
 
   // Bookkeeping
-  Parser* parser_;
+  TemporaryScope** variable_;
   TemporaryScope* parent_;
-
-  friend class Parser;
 };
 
 
-TemporaryScope::TemporaryScope(Parser* parser)
+TemporaryScope::TemporaryScope(TemporaryScope** variable)
   : materialized_literal_count_(0),
     expected_property_count_(0),
     only_simple_this_property_assignments_(false),
     this_property_assignments_(Factory::empty_fixed_array()),
     loop_count_(0),
-    parser_(parser),
-    parent_(parser->temp_scope_) {
-  parser->temp_scope_ = this;
+    variable_(variable),
+    parent_(*variable) {
+  *variable = this;
 }
 
 
 TemporaryScope::~TemporaryScope() {
-  parser_->temp_scope_ = parent_;
+  *variable_ = parent_;
 }
 
 
-// A zone list wrapper lets code either access a access a zone list
-// or appear to do so while actually ignoring all operations.
-template <typename T>
-class ZoneListWrapper {
- public:
-  ZoneListWrapper() : list_(NULL) { }
-  explicit ZoneListWrapper(int size) : list_(new ZoneList<T*>(size)) { }
-  void Add(T* that) { if (list_) list_->Add(that); }
-  int length() { return list_->length(); }
-  ZoneList<T*>* elements() { return list_; }
-  T* at(int index) { return list_->at(index); }
- private:
-  ZoneList<T*>* list_;
-};
-
-
-// Allocation macro that should be used to allocate objects that must
-// only be allocated in real parsing mode.  Note that in preparse mode
-// not only is the syntax tree not created but the constructor
-// arguments are not evaluated.
-#define NEW(expr) (is_pre_parsing_ ? NULL : new expr)
-
-
-class ParserFactory BASE_EMBEDDED {
- public:
-  explicit ParserFactory(bool is_pre_parsing) :
-      is_pre_parsing_(is_pre_parsing) { }
-
-  virtual ~ParserFactory() { }
-
-  virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
-
-  virtual Handle<String> LookupSymbol(int index, Vector<const char> string) {
-    return Handle<String>();
-  }
-
-  virtual Handle<String> EmptySymbol() {
-    return Handle<String>();
-  }
-
-  virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) {
-    if (obj == VariableProxySentinel::this_proxy()) {
-      return Property::this_property();
-    } else {
-      return ValidLeftHandSideSentinel::instance();
-    }
-  }
-
-  virtual Expression* NewCall(Expression* expression,
-                              ZoneList<Expression*>* arguments,
-                              int pos) {
-    return Call::sentinel();
-  }
-
-  virtual Statement* EmptyStatement() {
-    return NULL;
-  }
-
-  template <typename T> ZoneListWrapper<T> NewList(int size) {
-    return is_pre_parsing_ ? ZoneListWrapper<T>() : ZoneListWrapper<T>(size);
-  }
-
- private:
-  bool is_pre_parsing_;
-};
-
-
-class ParserLog BASE_EMBEDDED {
- public:
-  virtual ~ParserLog() { }
-
-  // Records the occurrence of a function.
-  virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); }
-  virtual void LogSymbol(int start, Vector<const char> symbol) {}
-  virtual void LogError() { }
-  // Return the current position in the function entry log.
-  virtual int function_position() { return 0; }
-  virtual int symbol_position() { return 0; }
-  virtual int symbol_ids() { return 0; }
-  virtual void PauseRecording() {}
-  virtual void ResumeRecording() {}
-  virtual Vector<unsigned> ExtractData() {
-    return Vector<unsigned>();
-  };
-};
-
-
-
-class ConditionalLogPauseScope {
- public:
-  ConditionalLogPauseScope(bool pause, ParserLog* log)
-      : log_(log), pause_(pause) {
-    if (pause) log->PauseRecording();
-  }
-  ~ConditionalLogPauseScope() {
-    if (pause_) log_->ResumeRecording();
-  }
- private:
-  ParserLog* log_;
-  bool pause_;
-};
-
-
-class AstBuildingParserFactory : public ParserFactory {
- public:
-  explicit AstBuildingParserFactory(int expected_symbols)
-      : ParserFactory(false), symbol_cache_(expected_symbols) { }
-
-  virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
-
-  virtual Handle<String> LookupSymbol(int symbol_id,
-                                      Vector<const char> string) {
-    // Length of symbol cache is the number of identified symbols.
-    // If we are larger than that, or negative, it's not a cached symbol.
-    // This might also happen if there is no preparser symbol data, even
-    // if there is some preparser data.
-    if (static_cast<unsigned>(symbol_id)
-        >= static_cast<unsigned>(symbol_cache_.length())) {
-      return Factory::LookupSymbol(string);
-    }
-    return LookupCachedSymbol(symbol_id, string);
-  }
-
-  Handle<String> LookupCachedSymbol(int symbol_id,
+Handle<String> Parser::LookupSymbol(int symbol_id,
                                     Vector<const char> string) {
-    // Make sure the cache is large enough to hold the symbol identifier.
-    if (symbol_cache_.length() <= symbol_id) {
-      // Increase length to index + 1.
-      symbol_cache_.AddBlock(Handle<String>::null(),
-                             symbol_id + 1 - symbol_cache_.length());
-    }
-    Handle<String> result = symbol_cache_.at(symbol_id);
-    if (result.is_null()) {
-      result = Factory::LookupSymbol(string);
-      symbol_cache_.at(symbol_id) = result;
-      return result;
-    }
-    Counters::total_preparse_symbols_skipped.Increment();
+  // Length of symbol cache is the number of identified symbols.
+  // If we are larger than that, or negative, it's not a cached symbol.
+  // This might also happen if there is no preparser symbol data, even
+  // if there is some preparser data.
+  if (static_cast<unsigned>(symbol_id)
+      >= static_cast<unsigned>(symbol_cache_.length())) {
+    return Factory::LookupSymbol(string);
+  }
+  return LookupCachedSymbol(symbol_id, string);
+}
+
+
+Handle<String> Parser::LookupCachedSymbol(int symbol_id,
+                                          Vector<const char> string) {
+  // Make sure the cache is large enough to hold the symbol identifier.
+  if (symbol_cache_.length() <= symbol_id) {
+    // Increase length to index + 1.
+    symbol_cache_.AddBlock(Handle<String>::null(),
+                           symbol_id + 1 - symbol_cache_.length());
+  }
+  Handle<String> result = symbol_cache_.at(symbol_id);
+  if (result.is_null()) {
+    result = Factory::LookupSymbol(string);
+    symbol_cache_.at(symbol_id) = result;
     return result;
   }
+  Counters::total_preparse_symbols_skipped.Increment();
+  return result;
+}
 
-  virtual Handle<String> EmptySymbol() {
-    return Factory::empty_symbol();
+
+Vector<unsigned> PartialParserRecorder::ExtractData() {
+  int function_size = function_store_.size();
+  int total_size = ScriptDataImpl::kHeaderSize + function_size;
+  Vector<unsigned> data = Vector<unsigned>::New(total_size);
+  preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
+  preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
+  memcpy(data.start(), preamble_, sizeof(preamble_));
+  int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
+  if (function_size > 0) {
+    function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
+                                           symbol_start));
   }
+  return data;
+}
 
-  virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) {
-    return new Property(obj, key, pos);
+
+void CompleteParserRecorder::LogSymbol(int start, Vector<const char> literal) {
+  if (!is_recording_) return;
+
+  int hash = vector_hash(literal);
+  HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
+  int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
+  if (id == 0) {
+    // Put (symbol_id_ + 1) into entry and increment it.
+    id = ++symbol_id_;
+    entry->value = reinterpret_cast<void*>(id);
+    Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal);
+    entry->key = &symbol[0];
   }
+  WriteNumber(id - 1);
+}
 
-  virtual Expression* NewCall(Expression* expression,
-                              ZoneList<Expression*>* arguments,
-                              int pos) {
-    return new Call(expression, arguments, pos);
+
+Vector<unsigned> CompleteParserRecorder::ExtractData() {
+  int function_size = function_store_.size();
+  // Add terminator to symbols, then pad to unsigned size.
+  int symbol_size = symbol_store_.size();
+  int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned));
+  symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator);
+  symbol_size += padding;
+  int total_size = ScriptDataImpl::kHeaderSize + function_size
+      + (symbol_size / sizeof(unsigned));
+  Vector<unsigned> data = Vector<unsigned>::New(total_size);
+  preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
+  preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_;
+  memcpy(data.start(), preamble_, sizeof(preamble_));
+  int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
+  if (function_size > 0) {
+    function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
+                                           symbol_start));
   }
-
-  virtual Statement* EmptyStatement();
- private:
-  List<Handle<String> > symbol_cache_;
-};
-
-
-// Record only functions.
-class PartialParserRecorder: public ParserLog {
- public:
-  PartialParserRecorder();
-  virtual FunctionEntry LogFunction(int start);
-
-  virtual int function_position() { return function_store_.size(); }
-
-  virtual void LogError() { }
-
-  virtual void LogMessage(Scanner::Location loc,
-                          const char* message,
-                          Vector<const char*> args);
-
-  virtual Vector<unsigned> ExtractData() {
-    int function_size = function_store_.size();
-    int total_size = ScriptDataImpl::kHeaderSize + function_size;
-    Vector<unsigned> data = Vector<unsigned>::New(total_size);
-    preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
-    preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
-    memcpy(data.start(), preamble_, sizeof(preamble_));
-    int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
-    if (function_size > 0) {
-      function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
-                                             symbol_start));
-    }
-    return data;
+  if (!has_error()) {
+    symbol_store_.WriteTo(
+        Vector<byte>::cast(data.SubVector(symbol_start, total_size)));
   }
-
-  virtual void PauseRecording() {
-    pause_count_++;
-    is_recording_ = false;
-  }
-
-  virtual void ResumeRecording() {
-    ASSERT(pause_count_ > 0);
-    if (--pause_count_ == 0) is_recording_ = !has_error();
-  }
-
- protected:
-  bool has_error() {
-    return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
-  }
-  bool is_recording() {
-    return is_recording_;
-  }
-
-  void WriteString(Vector<const char> str);
-
-  Collector<unsigned> function_store_;
-  unsigned preamble_[ScriptDataImpl::kHeaderSize];
-  bool is_recording_;
-  int pause_count_;
-
-#ifdef DEBUG
-  int prev_start;
-#endif
-};
-
-
-// Record both functions and symbols.
-class CompleteParserRecorder: public PartialParserRecorder {
- public:
-  CompleteParserRecorder();
-
-  virtual void LogSymbol(int start, Vector<const char> literal) {
-    if (!is_recording_) return;
-    int hash = vector_hash(literal);
-    HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
-    int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
-    if (id == 0) {
-      // Put (symbol_id_ + 1) into entry and increment it.
-      id = ++symbol_id_;
-      entry->value = reinterpret_cast<void*>(id);
-      Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal);
-      entry->key = &symbol[0];
-    }
-    WriteNumber(id - 1);
-  }
-
-  virtual Vector<unsigned> ExtractData() {
-    int function_size = function_store_.size();
-    // Add terminator to symbols, then pad to unsigned size.
-    int symbol_size = symbol_store_.size();
-    int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned));
-    symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator);
-    symbol_size += padding;
-    int total_size = ScriptDataImpl::kHeaderSize + function_size
-        + (symbol_size / sizeof(unsigned));
-    Vector<unsigned> data = Vector<unsigned>::New(total_size);
-    preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
-    preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_;
-    memcpy(data.start(), preamble_, sizeof(preamble_));
-    int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
-    if (function_size > 0) {
-      function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
-                                             symbol_start));
-    }
-    if (!has_error()) {
-      symbol_store_.WriteTo(
-          Vector<byte>::cast(data.SubVector(symbol_start, total_size)));
-    }
-    return data;
-  }
-
-  virtual int symbol_position() { return symbol_store_.size(); }
-  virtual int symbol_ids() { return symbol_id_; }
- private:
-    static int vector_hash(Vector<const char> string) {
-    int hash = 0;
-    for (int i = 0; i < string.length(); i++) {
-      int c = string[i];
-      hash += c;
-      hash += (hash << 10);
-      hash ^= (hash >> 6);
-    }
-    return hash;
-  }
-
-  static bool vector_compare(void* a, void* b) {
-    Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a);
-    Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b);
-    int length = string1->length();
-    if (string2->length() != length) return false;
-    return memcmp(string1->start(), string2->start(), length) == 0;
-  }
-
-  // Write a non-negative number to the symbol store.
-  void WriteNumber(int number);
-
-  Collector<byte> symbol_store_;
-  Collector<Vector<const char> > symbol_entries_;
-  HashMap symbol_table_;
-  int symbol_id_;
-};
+  return data;
+}
 
 
 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
@@ -910,7 +485,7 @@
   preamble_[ScriptDataImpl::kSizeOffset] = 0;
   ASSERT_EQ(6, ScriptDataImpl::kHeaderSize);
 #ifdef DEBUG
-  prev_start = -1;
+  prev_start_ = -1;
 #endif
 }
 
@@ -961,8 +536,8 @@
 
 
 void PartialParserRecorder::LogMessage(Scanner::Location loc,
-                                      const char* message,
-                                      Vector<const char*> args) {
+                                       const char* message,
+                                       Vector<const char*> args) {
   if (has_error()) return;
   preamble_[ScriptDataImpl::kHasErrorOffset] = true;
   function_store_.Reset();
@@ -1019,120 +594,12 @@
 }
 
 
-FunctionEntry PartialParserRecorder::LogFunction(int start) {
-#ifdef DEBUG
-  ASSERT(start > prev_start);
-  prev_start = start;
-#endif
-  if (!is_recording_) return FunctionEntry();
-  FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0));
-  result.set_start_pos(start);
-  return result;
-}
-
-
-class AstBuildingParser : public Parser {
- public:
-  AstBuildingParser(Handle<Script> script, bool allow_natives_syntax,
-                    v8::Extension* extension, ScriptDataImpl* pre_data)
-      : Parser(script,
-               allow_natives_syntax,
-               extension,
-               PARSE,
-               factory(),
-               log(),
-               pre_data),
-        factory_(pre_data ? pre_data->symbol_count() : 0) { }
-  virtual void ReportMessageAt(Scanner::Location loc, const char* message,
-                               Vector<const char*> args);
-  virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
-                                 FunctionLiteral* fun, bool resolve, bool* ok);
-  AstBuildingParserFactory* factory() { return &factory_; }
-  ParserLog* log() { return &log_; }
-
- private:
-  ParserLog log_;
-  AstBuildingParserFactory factory_;
-};
-
-
-class PreParser : public Parser {
- public:
-  PreParser(Handle<Script> script, bool allow_natives_syntax,
-            v8::Extension* extension, ParserLog* recorder)
-      : Parser(script, allow_natives_syntax, extension, PREPARSE,
-               factory(), recorder, NULL),
-        factory_(true) { }
-  virtual void ReportMessageAt(Scanner::Location loc, const char* message,
-                               Vector<const char*> args);
-  virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
-                                 FunctionLiteral* fun, bool resolve, bool* ok);
-  ParserFactory* factory() { return &factory_; }
-  virtual PartialParserRecorder* recorder() = 0;
-
- private:
-  ParserFactory factory_;
-};
-
-
-class CompletePreParser : public PreParser {
- public:
-  CompletePreParser(Handle<Script> script, bool allow_natives_syntax,
-                    v8::Extension* extension)
-      : PreParser(script, allow_natives_syntax, extension, &recorder_),
-        recorder_()  { }
-  virtual PartialParserRecorder* recorder() { return &recorder_; }
- private:
-  CompleteParserRecorder recorder_;
-};
-
-
-class PartialPreParser : public PreParser {
- public:
-  PartialPreParser(Handle<Script> script, bool allow_natives_syntax,
-                   v8::Extension* extension)
-      : PreParser(script, allow_natives_syntax, extension, &recorder_),
-        recorder_() { }
-  virtual PartialParserRecorder* recorder() { return &recorder_; }
- private:
-  PartialParserRecorder recorder_;
-};
-
-
-Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type,
-                                          bool inside_with) {
+Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
   Scope* result = new Scope(parent, type);
   result->Initialize(inside_with);
   return result;
 }
 
-
-Statement* AstBuildingParserFactory::EmptyStatement() {
-  // Use a statically allocated empty statement singleton to avoid
-  // allocating lots and lots of empty statements.
-  static v8::internal::EmptyStatement empty;
-  return &empty;
-}
-
-
-Scope* ParserFactory::NewScope(Scope* parent, Scope::Type type,
-                               bool inside_with) {
-  ASSERT(parent != NULL);
-  parent->type_ = type;
-  // Initialize function is hijacked by DummyScope to increment scope depth.
-  parent->Initialize(inside_with);
-  return parent;
-}
-
-
-VariableProxy* PreParser::Declare(Handle<String> name, Variable::Mode mode,
-                                  FunctionLiteral* fun, bool resolve,
-                                  bool* ok) {
-  return NULL;
-}
-
-
-
 // ----------------------------------------------------------------------------
 // Target is a support class to facilitate manipulation of the
 // Parser's target_stack_ (the stack of potential 'break' and
@@ -1141,20 +608,20 @@
 
 class Target BASE_EMBEDDED {
  public:
-  Target(Parser* parser, AstNode* node)
-      : parser_(parser), node_(node), previous_(parser_->target_stack_) {
-    parser_->target_stack_ = this;
+  Target(Target** variable, AstNode* node)
+      : variable_(variable), node_(node), previous_(*variable) {
+    *variable = this;
   }
 
   ~Target() {
-    parser_->target_stack_ = previous_;
+    *variable_ = previous_;
   }
 
   Target* previous() { return previous_; }
   AstNode* node() { return node_; }
 
  private:
-  Parser* parser_;
+  Target** variable_;
   AstNode* node_;
   Target* previous_;
 };
@@ -1162,17 +629,17 @@
 
 class TargetScope BASE_EMBEDDED {
  public:
-  explicit TargetScope(Parser* parser)
-      : parser_(parser), previous_(parser->target_stack_) {
-    parser->target_stack_ = NULL;
+  explicit TargetScope(Target** variable)
+      : variable_(variable), previous_(*variable) {
+    *variable = NULL;
   }
 
   ~TargetScope() {
-    parser_->target_stack_ = previous_;
+    *variable_ = previous_;
   }
 
  private:
-  Parser* parser_;
+  Target** variable_;
   Target* previous_;
 };
 
@@ -1184,22 +651,26 @@
 
 class LexicalScope BASE_EMBEDDED {
  public:
-  LexicalScope(Parser* parser, Scope* scope)
-    : parser_(parser),
-      prev_scope_(parser->top_scope_),
-      prev_level_(parser->with_nesting_level_) {
-    parser_->top_scope_ = scope;
-    parser_->with_nesting_level_ = 0;
+  LexicalScope(Scope** scope_variable,
+               int* with_nesting_level_variable,
+               Scope* scope)
+    : scope_variable_(scope_variable),
+      with_nesting_level_variable_(with_nesting_level_variable),
+      prev_scope_(*scope_variable),
+      prev_level_(*with_nesting_level_variable) {
+    *scope_variable = scope;
+    *with_nesting_level_variable = 0;
   }
 
   ~LexicalScope() {
-    parser_->top_scope_->Leave();
-    parser_->top_scope_ = prev_scope_;
-    parser_->with_nesting_level_ = prev_level_;
+    (*scope_variable_)->Leave();
+    *scope_variable_ = prev_scope_;
+    *with_nesting_level_variable_ = prev_level_;
   }
 
  private:
-  Parser* parser_;
+  Scope** scope_variable_;
+  int* with_nesting_level_variable_;
   Scope* prev_scope_;
   int prev_level_;
 };
@@ -1231,11 +702,9 @@
 Parser::Parser(Handle<Script> script,
                bool allow_natives_syntax,
                v8::Extension* extension,
-               ParserMode is_pre_parsing,
-               ParserFactory* factory,
-               ParserLog* log,
                ScriptDataImpl* pre_data)
-    : script_(script),
+    : symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
+      script_(script),
       scanner_(),
       top_scope_(NULL),
       with_nesting_level_(0),
@@ -1243,34 +712,11 @@
       target_stack_(NULL),
       allow_natives_syntax_(allow_natives_syntax),
       extension_(extension),
-      factory_(factory),
-      log_(log),
-      is_pre_parsing_(is_pre_parsing == PREPARSE),
       pre_data_(pre_data),
       fni_(NULL) {
 }
 
 
-bool Parser::PreParseProgram(Handle<String> source,
-                             unibrow::CharacterStream* stream) {
-  HistogramTimerScope timer(&Counters::pre_parse);
-  AssertNoZoneAllocation assert_no_zone_allocation;
-  AssertNoAllocation assert_no_allocation;
-  NoHandleAllocation no_handle_allocation;
-  scanner_.Initialize(source, stream, JAVASCRIPT);
-  ASSERT(target_stack_ == NULL);
-  mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
-  if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
-  DummyScope top_scope;
-  LexicalScope scope(this, &top_scope);
-  TemporaryScope temp_scope(this);
-  ZoneListWrapper<Statement> processor;
-  bool ok = true;
-  ParseSourceElements(&processor, Token::EOS, &ok);
-  return !scanner().stack_overflow();
-}
-
-
 FunctionLiteral* Parser::ParseProgram(Handle<String> source,
                                       bool in_global_context) {
   CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
@@ -1293,20 +739,21 @@
     in_global_context
       ? Scope::GLOBAL_SCOPE
       : Scope::EVAL_SCOPE;
-  Handle<String> no_name = factory()->EmptySymbol();
+  Handle<String> no_name = Factory::empty_symbol();
 
   FunctionLiteral* result = NULL;
-  { Scope* scope = factory()->NewScope(top_scope_, type, inside_with());
-    LexicalScope lexical_scope(this, scope);
-    TemporaryScope temp_scope(this);
-    ZoneListWrapper<Statement> body(16);
+  { Scope* scope = NewScope(top_scope_, type, inside_with());
+    LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
+                               scope);
+    TemporaryScope temp_scope(&this->temp_scope_);
+    ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
     bool ok = true;
-    ParseSourceElements(&body, Token::EOS, &ok);
+    ParseSourceElements(body, Token::EOS, &ok);
     if (ok) {
-      result = NEW(FunctionLiteral(
+      result = new FunctionLiteral(
           no_name,
           top_scope_,
-          body.elements(),
+          body,
           temp_scope.materialized_literal_count(),
           temp_scope.expected_property_count(),
           temp_scope.only_simple_this_property_assignments(),
@@ -1315,7 +762,7 @@
           0,
           source->length(),
           false,
-          temp_scope.ContainsLoops()));
+          temp_scope.ContainsLoops());
     } else if (scanner().stack_overflow()) {
       Top::StackOverflow();
     }
@@ -1353,11 +800,12 @@
 
   {
     // Parse the function literal.
-    Handle<String> no_name = factory()->EmptySymbol();
+    Handle<String> no_name = Factory::empty_symbol();
     Scope* scope =
-        factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
-    LexicalScope lexical_scope(this, scope);
-    TemporaryScope temp_scope(this);
+        NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
+    LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
+                               scope);
+    TemporaryScope temp_scope(&this->temp_scope_);
 
     FunctionLiteralType type =
         info->is_expression() ? EXPRESSION : DECLARATION;
@@ -1382,78 +830,24 @@
 }
 
 
-FunctionLiteral* Parser::ParseJson(Handle<String> source) {
-  CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
-
-  HistogramTimerScope timer(&Counters::parse);
-  Counters::total_parse_size.Increment(source->length());
-
-  // Initialize parser state.
-  source->TryFlatten(TENURED);
-  scanner_.Initialize(source, JSON);
-  ASSERT(target_stack_ == NULL);
-
-  FunctionLiteral* result = NULL;
-  Handle<String> no_name = factory()->EmptySymbol();
-
-  {
-    Scope* scope = factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, false);
-    LexicalScope lexical_scope(this, scope);
-    TemporaryScope temp_scope(this);
-    bool ok = true;
-    Expression* expression = ParseJson(&ok);
-    if (ok) {
-      ZoneListWrapper<Statement> statement = factory()->NewList<Statement>(1);
-      statement.Add(new ExpressionStatement(expression));
-      result = NEW(FunctionLiteral(
-          no_name,
-          top_scope_,
-          statement.elements(),
-          temp_scope.materialized_literal_count(),
-          temp_scope.expected_property_count(),
-          temp_scope.only_simple_this_property_assignments(),
-          temp_scope.this_property_assignments(),
-          0,
-          0,
-          source->length(),
-          false,
-          temp_scope.ContainsLoops()));
-    } else if (scanner().stack_overflow()) {
-      Top::StackOverflow();
-    }
+Handle<String> Parser::GetSymbol(bool* ok) {
+  int symbol_id = -1;
+  if (pre_data() != NULL) {
+    symbol_id = pre_data()->GetSymbolIdentifier();
   }
-
-  // Make sure the target stack is empty.
-  ASSERT(target_stack_ == NULL);
-
-  // If there was a syntax error we have to get rid of the AST
-  // and it is not safe to do so before the scope has been deleted.
-  if (result == NULL) zone_scope.DeleteOnExit();
-  return result;
+  return LookupSymbol(symbol_id, scanner_.literal());
 }
 
+
 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
   Scanner::Location source_location = scanner_.location();
   ReportMessageAt(source_location, type, args);
 }
 
 
-Handle<String> Parser::GetSymbol(bool* ok) {
-  if (is_pre_parsing_) {
-    log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
-    return Handle<String>::null();
-  }
-  int symbol_id = -1;
-  if (pre_data() != NULL) {
-    symbol_id = pre_data()->GetSymbolIdentifier();
-  }
-  return factory()->LookupSymbol(symbol_id, scanner_.literal());
-}
-
-
-void AstBuildingParser::ReportMessageAt(Scanner::Location source_location,
-                                        const char* type,
-                                        Vector<const char*> args) {
+void Parser::ReportMessageAt(Scanner::Location source_location,
+                             const char* type,
+                             Vector<const char*> args) {
   MessageLocation location(script_,
                            source_location.beg_pos, source_location.end_pos);
   Handle<JSArray> array = Factory::NewJSArray(args.length());
@@ -1465,13 +859,6 @@
 }
 
 
-void PreParser::ReportMessageAt(Scanner::Location source_location,
-                                const char* type,
-                                Vector<const char*> args) {
-  recorder()->LogMessage(source_location, type, args);
-}
-
-
 // Base class containing common code for the different finder classes used by
 // the parser.
 class ParserFinder {
@@ -1513,6 +900,11 @@
   }
 
  private:
+  // The minimum number of contiguous assignment that will
+  // be treated as an initialization block. Benchmarks show that
+  // the overhead exceeds the savings below this limit.
+  static const int kMinInitializationBlock = 3;
+
   // Returns true if the expressions appear to denote the same object.
   // In the context of initialization blocks, we only consider expressions
   // of the form 'expr.x' or expr["x"].
@@ -1565,7 +957,7 @@
   }
 
   void EndBlock() {
-    if (block_size_ >= Parser::kMinInitializationBlock) {
+    if (block_size_ >= kMinInitializationBlock) {
       first_in_block_->mark_block_start();
       last_in_block_->mark_block_end();
     }
@@ -1723,7 +1115,7 @@
 };
 
 
-void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
+void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
                                   int end_token,
                                   bool* ok) {
   // SourceElements ::
@@ -1733,7 +1125,7 @@
   // elements. This way, all scripts and functions get their own
   // target stack thus avoiding illegal breaks and continues across
   // functions.
-  TargetScope scope(this);
+  TargetScope scope(&this->target_stack_);
 
   ASSERT(processor != NULL);
   InitializationBlockFinder block_finder;
@@ -1755,7 +1147,7 @@
   }
 
   // Propagate the collected information on this property assignments.
-  if (!is_pre_parsing_ && top_scope_->is_function_scope()) {
+  if (top_scope_->is_function_scope()) {
     bool only_simple_this_property_assignments =
         this_property_assignment_finder.only_simple_this_property_assignments()
         && top_scope_->declarations()->length() == 0;
@@ -1808,7 +1200,7 @@
 
     case Token::SEMICOLON:
       Next();
-      return factory()->EmptyStatement();
+      return EmptyStatement();
 
     case Token::IF:
       stmt = ParseIfStatement(labels, ok);
@@ -1856,8 +1248,8 @@
       // one must take great care not to treat it as a
       // fall-through. It is much easier just to wrap the entire
       // try-statement in a statement block and put the labels there
-      Block* result = NEW(Block(labels, 1, false));
-      Target target(this, result);
+      Block* result = new Block(labels, 1, false);
+      Target target(&this->target_stack_, result);
       TryStatement* statement = ParseTryStatement(CHECK_OK);
       if (statement) {
         statement->set_statement_pos(statement_pos);
@@ -1886,11 +1278,11 @@
 }
 
 
-VariableProxy* AstBuildingParser::Declare(Handle<String> name,
-                                          Variable::Mode mode,
-                                          FunctionLiteral* fun,
-                                          bool resolve,
-                                          bool* ok) {
+VariableProxy* Parser::Declare(Handle<String> name,
+                               Variable::Mode mode,
+                               FunctionLiteral* fun,
+                               bool resolve,
+                               bool* ok) {
   Variable* var = NULL;
   // If we are inside a function, a declaration of a variable
   // is a truly local variable, and the scope of the variable
@@ -1945,13 +1337,13 @@
   // a performance issue since it may lead to repeated
   // Runtime::DeclareContextSlot() calls.
   VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with());
-  top_scope_->AddDeclaration(NEW(Declaration(proxy, mode, fun)));
+  top_scope_->AddDeclaration(new Declaration(proxy, mode, fun));
 
   // For global const variables we bind the proxy to a variable.
   if (mode == Variable::CONST && top_scope_->is_global_scope()) {
     ASSERT(resolve);  // should be set by all callers
     Variable::Kind kind = Variable::NORMAL;
-    var = NEW(Variable(top_scope_, name, Variable::CONST, true, kind));
+    var = new Variable(top_scope_, name, Variable::CONST, true, kind);
   }
 
   // If requested and we have a local variable, bind the proxy to the variable
@@ -2003,13 +1395,13 @@
   while (!done) {
     ParseIdentifier(CHECK_OK);
     done = (peek() == Token::RPAREN);
-    if (!done) Expect(Token::COMMA, CHECK_OK);
+    if (!done) {
+      Expect(Token::COMMA, CHECK_OK);
+    }
   }
   Expect(Token::RPAREN, CHECK_OK);
   Expect(Token::SEMICOLON, CHECK_OK);
 
-  if (is_pre_parsing_) return NULL;
-
   // Make sure that the function containing the native declaration
   // isn't lazily compiled. The extension structures are only
   // accessible while parsing the first time not when reparsing
@@ -2039,10 +1431,10 @@
   // TODO(1240846): It's weird that native function declarations are
   // introduced dynamically when we meet their declarations, whereas
   // other functions are setup when entering the surrounding scope.
-  SharedFunctionInfoLiteral* lit = NEW(SharedFunctionInfoLiteral(shared));
+  SharedFunctionInfoLiteral* lit = new SharedFunctionInfoLiteral(shared);
   VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
-  return NEW(ExpressionStatement(
-      new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)));
+  return new ExpressionStatement(
+      new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
 }
 
 
@@ -2060,7 +1452,7 @@
   // scope, we treat is as such and introduce the function with it's
   // initial value upon entering the corresponding scope.
   Declare(name, Variable::VAR, fun, true, CHECK_OK);
-  return factory()->EmptyStatement();
+  return EmptyStatement();
 }
 
 
@@ -2072,8 +1464,8 @@
   // (ECMA-262, 3rd, 12.2)
   //
   // Construct block expecting 16 statements.
-  Block* result = NEW(Block(labels, 16, false));
-  Target target(this, result);
+  Block* result = new Block(labels, 16, false);
+  Target target(&this->target_stack_, result);
   Expect(Token::LBRACE, CHECK_OK);
   while (peek() != Token::RBRACE) {
     Statement* stat = ParseStatement(NULL, CHECK_OK);
@@ -2131,7 +1523,7 @@
   // is inside an initializer block, it is ignored.
   //
   // Create new block with one expected declaration.
-  Block* block = NEW(Block(NULL, 1, true));
+  Block* block = new Block(NULL, 1, true);
   VariableProxy* last_var = NULL;  // the last variable declared
   int nvars = 0;  // the number of variables declared
   do {
@@ -2222,14 +1614,14 @@
     // browsers where the global object (window) has lots of
     // properties defined in prototype objects.
 
-    if (!is_pre_parsing_ && top_scope_->is_global_scope()) {
+    if (top_scope_->is_global_scope()) {
       // Compute the arguments for the runtime call.
       ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2);
       // Be careful not to assign a value to the global variable if
       // we're in a with. The initialization value should not
       // necessarily be stored in the global object in that case,
       // which is why we need to generate a separate assignment node.
-      arguments->Add(NEW(Literal(name)));  // we have at least 1 parameter
+      arguments->Add(new Literal(name));  // we have at least 1 parameter
       if (is_const || (value != NULL && !inside_with())) {
         arguments->Add(value);
         value = NULL;  // zap the value to avoid the unnecessary assignment
@@ -2241,18 +1633,18 @@
       CallRuntime* initialize;
       if (is_const) {
         initialize =
-          NEW(CallRuntime(
+          new CallRuntime(
             Factory::InitializeConstGlobal_symbol(),
             Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
-            arguments));
+            arguments);
       } else {
         initialize =
-          NEW(CallRuntime(
+          new CallRuntime(
             Factory::InitializeVarGlobal_symbol(),
             Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
-            arguments));
+            arguments);
       }
-      block->AddStatement(NEW(ExpressionStatement(initialize)));
+      block->AddStatement(new ExpressionStatement(initialize));
     }
 
     // Add an assignment node to the initialization statement block if
@@ -2267,8 +1659,8 @@
     // the top context for variables). Sigh...
     if (value != NULL) {
       Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
-      Assignment* assignment = NEW(Assignment(op, last_var, value, position));
-      if (block) block->AddStatement(NEW(ExpressionStatement(assignment)));
+      Assignment* assignment = new Assignment(op, last_var, value, position);
+      if (block) block->AddStatement(new ExpressionStatement(assignment));
     }
 
     if (fni_ != NULL) fni_->Leave();
@@ -2276,14 +1668,8 @@
 
   if (!is_const && nvars == 1) {
     // We have a single, non-const variable.
-    if (is_pre_parsing_) {
-      // If we're preparsing then we need to set the var to something
-      // in order for for-in loops to parse correctly.
-      *var = ValidLeftHandSideSentinel::instance();
-    } else {
-      ASSERT(last_var != NULL);
-      *var = last_var;
-    }
+    ASSERT(last_var != NULL);
+    *var = last_var;
   }
 
   return block;
@@ -2318,29 +1704,27 @@
     // labels requires nontrivial changes to the way scopes are
     // structured.  However, these are probably changes we want to
     // make later anyway so we should go back and fix this then.
-    if (!is_pre_parsing_) {
-      if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
-        SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
-        const char* elms[2] = { "Label", *c_string };
-        Vector<const char*> args(elms, 2);
-        ReportMessage("redeclaration", args);
-        *ok = false;
-        return NULL;
-      }
-      if (labels == NULL) labels = new ZoneStringList(4);
-      labels->Add(label);
-      // Remove the "ghost" variable that turned out to be a label
-      // from the top scope. This way, we don't try to resolve it
-      // during the scope processing.
-      top_scope_->RemoveUnresolved(var);
+    if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
+      SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
+      const char* elms[2] = { "Label", *c_string };
+      Vector<const char*> args(elms, 2);
+      ReportMessage("redeclaration", args);
+      *ok = false;
+      return NULL;
     }
+    if (labels == NULL) labels = new ZoneStringList(4);
+    labels->Add(label);
+    // Remove the "ghost" variable that turned out to be a label
+    // from the top scope. This way, we don't try to resolve it
+    // during the scope processing.
+    top_scope_->RemoveUnresolved(var);
     Expect(Token::COLON, CHECK_OK);
     return ParseStatement(labels, ok);
   }
 
   // Parsed expression statement.
   ExpectSemicolon(CHECK_OK);
-  return NEW(ExpressionStatement(expr));
+  return new ExpressionStatement(expr);
 }
 
 
@@ -2357,10 +1741,10 @@
   if (peek() == Token::ELSE) {
     Next();
     else_statement = ParseStatement(labels, CHECK_OK);
-  } else if (!is_pre_parsing_) {
-    else_statement = factory()->EmptyStatement();
+  } else {
+    else_statement = EmptyStatement();
   }
-  return NEW(IfStatement(condition, then_statement, else_statement));
+  return new IfStatement(condition, then_statement, else_statement);
 }
 
 
@@ -2376,19 +1760,17 @@
     label = ParseIdentifier(CHECK_OK);
   }
   IterationStatement* target = NULL;
-  if (!is_pre_parsing_) {
-    target = LookupContinueTarget(label, CHECK_OK);
-    if (target == NULL) {
-      // Illegal continue statement.  To be consistent with KJS we delay
-      // reporting of the syntax error until runtime.
-      Handle<String> error_type = Factory::illegal_continue_symbol();
-      if (!label.is_null()) error_type = Factory::unknown_label_symbol();
-      Expression* throw_error = NewThrowSyntaxError(error_type, label);
-      return NEW(ExpressionStatement(throw_error));
-    }
+  target = LookupContinueTarget(label, CHECK_OK);
+  if (target == NULL) {
+    // Illegal continue statement.  To be consistent with KJS we delay
+    // reporting of the syntax error until runtime.
+    Handle<String> error_type = Factory::illegal_continue_symbol();
+    if (!label.is_null()) error_type = Factory::unknown_label_symbol();
+    Expression* throw_error = NewThrowSyntaxError(error_type, label);
+    return new ExpressionStatement(throw_error);
   }
   ExpectSemicolon(CHECK_OK);
-  return NEW(ContinueStatement(target));
+  return new ContinueStatement(target);
 }
 
 
@@ -2406,22 +1788,20 @@
   // Parse labeled break statements that target themselves into
   // empty statements, e.g. 'l1: l2: l3: break l2;'
   if (!label.is_null() && ContainsLabel(labels, label)) {
-    return factory()->EmptyStatement();
+    return EmptyStatement();
   }
   BreakableStatement* target = NULL;
-  if (!is_pre_parsing_) {
-    target = LookupBreakTarget(label, CHECK_OK);
-    if (target == NULL) {
-      // Illegal break statement.  To be consistent with KJS we delay
-      // reporting of the syntax error until runtime.
-      Handle<String> error_type = Factory::illegal_break_symbol();
-      if (!label.is_null()) error_type = Factory::unknown_label_symbol();
-      Expression* throw_error = NewThrowSyntaxError(error_type, label);
-      return NEW(ExpressionStatement(throw_error));
-    }
+  target = LookupBreakTarget(label, CHECK_OK);
+  if (target == NULL) {
+    // Illegal break statement.  To be consistent with KJS we delay
+    // reporting of the syntax error until runtime.
+    Handle<String> error_type = Factory::illegal_break_symbol();
+    if (!label.is_null()) error_type = Factory::unknown_label_symbol();
+    Expression* throw_error = NewThrowSyntaxError(error_type, label);
+    return new ExpressionStatement(throw_error);
   }
   ExpectSemicolon(CHECK_OK);
-  return NEW(BreakStatement(target));
+  return new BreakStatement(target);
 }
 
 
@@ -2439,10 +1819,10 @@
   // function. See ECMA-262, section 12.9, page 67.
   //
   // To be consistent with KJS we report the syntax error at runtime.
-  if (!is_pre_parsing_ && !top_scope_->is_function_scope()) {
+  if (!top_scope_->is_function_scope()) {
     Handle<String> type = Factory::illegal_return_symbol();
     Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
-    return NEW(ExpressionStatement(throw_error));
+    return new ExpressionStatement(throw_error);
   }
 
   Token::Value tok = peek();
@@ -2451,12 +1831,12 @@
       tok == Token::RBRACE ||
       tok == Token::EOS) {
     ExpectSemicolon(CHECK_OK);
-    return NEW(ReturnStatement(GetLiteralUndefined()));
+    return new ReturnStatement(GetLiteralUndefined());
   }
 
   Expression* expr = ParseExpression(true, CHECK_OK);
   ExpectSemicolon(CHECK_OK);
-  return NEW(ReturnStatement(expr));
+  return new ReturnStatement(expr);
 }
 
 
@@ -2465,10 +1845,10 @@
                           bool is_catch_block,
                           bool* ok) {
   // Parse the statement and collect escaping labels.
-  ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0));
+  ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0);
   TargetCollector collector(target_list);
   Statement* stat;
-  { Target target(this, &collector);
+  { Target target(&this->target_stack_, &collector);
     with_nesting_level_++;
     top_scope_->RecordWithStatement();
     stat = ParseStatement(labels, CHECK_OK);
@@ -2477,21 +1857,21 @@
   // Create resulting block with two statements.
   // 1: Evaluate the with expression.
   // 2: The try-finally block evaluating the body.
-  Block* result = NEW(Block(NULL, 2, false));
+  Block* result = new Block(NULL, 2, false);
 
   if (result != NULL) {
-    result->AddStatement(NEW(WithEnterStatement(obj, is_catch_block)));
+    result->AddStatement(new WithEnterStatement(obj, is_catch_block));
 
     // Create body block.
-    Block* body = NEW(Block(NULL, 1, false));
+    Block* body = new Block(NULL, 1, false);
     body->AddStatement(stat);
 
     // Create exit block.
-    Block* exit = NEW(Block(NULL, 1, false));
-    exit->AddStatement(NEW(WithExitStatement()));
+    Block* exit = new Block(NULL, 1, false);
+    exit->AddStatement(new WithExitStatement());
 
     // Return a try-finally statement.
-    TryFinallyStatement* wrapper = NEW(TryFinallyStatement(body, exit));
+    TryFinallyStatement* wrapper = new TryFinallyStatement(body, exit);
     wrapper->set_escaping_targets(collector.targets());
     result->AddStatement(wrapper);
   }
@@ -2533,15 +1913,15 @@
   }
   Expect(Token::COLON, CHECK_OK);
 
-  ZoneListWrapper<Statement> statements = factory()->NewList<Statement>(5);
+  ZoneList<Statement*>* statements = new ZoneList<Statement*>(5);
   while (peek() != Token::CASE &&
          peek() != Token::DEFAULT &&
          peek() != Token::RBRACE) {
     Statement* stat = ParseStatement(NULL, CHECK_OK);
-    statements.Add(stat);
+    statements->Add(stat);
   }
 
-  return NEW(CaseClause(label, statements.elements()));
+  return new CaseClause(label, statements);
 }
 
 
@@ -2550,8 +1930,8 @@
   // SwitchStatement ::
   //   'switch' '(' Expression ')' '{' CaseClause* '}'
 
-  SwitchStatement* statement = NEW(SwitchStatement(labels));
-  Target target(this, statement);
+  SwitchStatement* statement = new SwitchStatement(labels);
+  Target target(&this->target_stack_, statement);
 
   Expect(Token::SWITCH, CHECK_OK);
   Expect(Token::LPAREN, CHECK_OK);
@@ -2559,15 +1939,15 @@
   Expect(Token::RPAREN, CHECK_OK);
 
   bool default_seen = false;
-  ZoneListWrapper<CaseClause> cases = factory()->NewList<CaseClause>(4);
+  ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4);
   Expect(Token::LBRACE, CHECK_OK);
   while (peek() != Token::RBRACE) {
     CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
-    cases.Add(clause);
+    cases->Add(clause);
   }
   Expect(Token::RBRACE, CHECK_OK);
 
-  if (statement) statement->Initialize(tag, cases.elements());
+  if (statement) statement->Initialize(tag, cases);
   return statement;
 }
 
@@ -2586,7 +1966,7 @@
   Expression* exception = ParseExpression(true, CHECK_OK);
   ExpectSemicolon(CHECK_OK);
 
-  return NEW(ExpressionStatement(new Throw(exception, pos)));
+  return new ExpressionStatement(new Throw(exception, pos));
 }
 
 
@@ -2604,11 +1984,11 @@
 
   Expect(Token::TRY, CHECK_OK);
 
-  ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0));
+  ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0);
   TargetCollector collector(target_list);
   Block* try_block;
 
-  { Target target(this, &collector);
+  { Target target(&this->target_stack_, &collector);
     try_block = ParseBlock(NULL, CHECK_OK);
   }
 
@@ -2627,7 +2007,7 @@
   // then we will need to collect jump targets from the catch block. Since
   // we don't know yet if there will be a finally block, we always collect
   // the jump targets.
-  ZoneList<BreakTarget*>* catch_target_list = NEW(ZoneList<BreakTarget*>(0));
+  ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0);
   TargetCollector catch_collector(catch_target_list);
   bool has_catch = false;
   if (tok == Token::CATCH) {
@@ -2642,9 +2022,9 @@
       // Allocate a temporary for holding the finally state while
       // executing the finally block.
       catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol());
-      Literal* name_literal = NEW(Literal(name));
-      Expression* obj = NEW(CatchExtensionObject(name_literal, catch_var));
-      { Target target(this, &catch_collector);
+      Literal* name_literal = new Literal(name);
+      Expression* obj = new CatchExtensionObject(name_literal, catch_var);
+      { Target target(&this->target_stack_, &catch_collector);
         catch_block = WithHelper(obj, NULL, true, CHECK_OK);
       }
     } else {
@@ -2666,30 +2046,28 @@
   // to:
   //   'try { try { } catch { } } finally { }'
 
-  if (!is_pre_parsing_ && catch_block != NULL && finally_block != NULL) {
+  if (catch_block != NULL && finally_block != NULL) {
     TryCatchStatement* statement =
-        NEW(TryCatchStatement(try_block, catch_var, catch_block));
+        new TryCatchStatement(try_block, catch_var, catch_block);
     statement->set_escaping_targets(collector.targets());
-    try_block = NEW(Block(NULL, 1, false));
+    try_block = new Block(NULL, 1, false);
     try_block->AddStatement(statement);
     catch_block = NULL;
   }
 
   TryStatement* result = NULL;
-  if (!is_pre_parsing_) {
-    if (catch_block != NULL) {
-      ASSERT(finally_block == NULL);
-      result = NEW(TryCatchStatement(try_block, catch_var, catch_block));
-      result->set_escaping_targets(collector.targets());
-    } else {
-      ASSERT(finally_block != NULL);
-      result = NEW(TryFinallyStatement(try_block, finally_block));
-      // Add the jump targets of the try block and the catch block.
-      for (int i = 0; i < collector.targets()->length(); i++) {
-        catch_collector.AddTarget(collector.targets()->at(i));
-      }
-      result->set_escaping_targets(catch_collector.targets());
+  if (catch_block != NULL) {
+    ASSERT(finally_block == NULL);
+    result = new TryCatchStatement(try_block, catch_var, catch_block);
+    result->set_escaping_targets(collector.targets());
+  } else {
+    ASSERT(finally_block != NULL);
+    result = new TryFinallyStatement(try_block, finally_block);
+    // Add the jump targets of the try block and the catch block.
+    for (int i = 0; i < collector.targets()->length(); i++) {
+      catch_collector.AddTarget(collector.targets()->at(i));
     }
+    result->set_escaping_targets(catch_collector.targets());
   }
 
   return result;
@@ -2702,8 +2080,8 @@
   //   'do' Statement 'while' '(' Expression ')' ';'
 
   temp_scope_->AddLoop();
-  DoWhileStatement* loop = NEW(DoWhileStatement(labels));
-  Target target(this, loop);
+  DoWhileStatement* loop = new DoWhileStatement(labels);
+  Target target(&this->target_stack_, loop);
 
   Expect(Token::DO, CHECK_OK);
   Statement* body = ParseStatement(NULL, CHECK_OK);
@@ -2735,8 +2113,8 @@
   //   'while' '(' Expression ')' Statement
 
   temp_scope_->AddLoop();
-  WhileStatement* loop = NEW(WhileStatement(labels));
-  Target target(this, loop);
+  WhileStatement* loop = new WhileStatement(labels);
+  Target target(&this->target_stack_, loop);
 
   Expect(Token::WHILE, CHECK_OK);
   Expect(Token::LPAREN, CHECK_OK);
@@ -2765,25 +2143,20 @@
       Block* variable_statement =
           ParseVariableDeclarations(false, &each, CHECK_OK);
       if (peek() == Token::IN && each != NULL) {
-        ForInStatement* loop = NEW(ForInStatement(labels));
-        Target target(this, loop);
+        ForInStatement* loop = new ForInStatement(labels);
+        Target target(&this->target_stack_, loop);
 
         Expect(Token::IN, CHECK_OK);
         Expression* enumerable = ParseExpression(true, CHECK_OK);
         Expect(Token::RPAREN, CHECK_OK);
 
         Statement* body = ParseStatement(NULL, CHECK_OK);
-        if (is_pre_parsing_) {
-          return NULL;
-        } else {
-          loop->Initialize(each, enumerable, body);
-          Block* result = NEW(Block(NULL, 2, false));
-          result->AddStatement(variable_statement);
-          result->AddStatement(loop);
-          // Parsed for-in loop w/ variable/const declaration.
-          return result;
-        }
-
+        loop->Initialize(each, enumerable, body);
+        Block* result = new Block(NULL, 2, false);
+        result->AddStatement(variable_statement);
+        result->AddStatement(loop);
+        // Parsed for-in loop w/ variable/const declaration.
+        return result;
       } else {
         init = variable_statement;
       }
@@ -2799,8 +2172,8 @@
           Handle<String> type = Factory::invalid_lhs_in_for_in_symbol();
           expression = NewThrowReferenceError(type);
         }
-        ForInStatement* loop = NEW(ForInStatement(labels));
-        Target target(this, loop);
+        ForInStatement* loop = new ForInStatement(labels);
+        Target target(&this->target_stack_, loop);
 
         Expect(Token::IN, CHECK_OK);
         Expression* enumerable = ParseExpression(true, CHECK_OK);
@@ -2812,14 +2185,14 @@
         return loop;
 
       } else {
-        init = NEW(ExpressionStatement(expression));
+        init = new ExpressionStatement(expression);
       }
     }
   }
 
   // Standard 'for' loop
-  ForStatement* loop = NEW(ForStatement(labels));
-  Target target(this, loop);
+  ForStatement* loop = new ForStatement(labels);
+  Target target(&this->target_stack_, loop);
 
   // Parsed initializer at this point.
   Expect(Token::SEMICOLON, CHECK_OK);
@@ -2834,7 +2207,7 @@
   Statement* next = NULL;
   if (peek() != Token::RPAREN) {
     Expression* exp = ParseExpression(true, CHECK_OK);
-    next = NEW(ExpressionStatement(exp));
+    next = new ExpressionStatement(exp);
   }
   Expect(Token::RPAREN, CHECK_OK);
 
@@ -2855,7 +2228,7 @@
     Expect(Token::COMMA, CHECK_OK);
     int position = scanner().location().beg_pos;
     Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
-    result = NEW(BinaryOperation(Token::COMMA, result, right, position));
+    result = new BinaryOperation(Token::COMMA, result, right, position);
   }
   return result;
 }
@@ -2915,7 +2288,7 @@
     fni_->Leave();
   }
 
-  return NEW(Assignment(op, expression, right, pos));
+  return new Assignment(op, expression, right, pos);
 }
 
 
@@ -2937,8 +2310,8 @@
   Expect(Token::COLON, CHECK_OK);
   int right_position = scanner().peek_location().beg_pos;
   Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
-  return NEW(Conditional(expression, left, right,
-                         left_position, right_position));
+  return new Conditional(expression, left, right,
+                         left_position, right_position);
 }
 
 
@@ -3045,12 +2418,12 @@
         x = NewCompareNode(cmp, x, y, position);
         if (cmp != op) {
           // The comparison was negated - add a NOT.
-          x = NEW(UnaryOperation(Token::NOT, x));
+          x = new UnaryOperation(Token::NOT, x);
         }
 
       } else {
         // We have a "normal" binary operation.
-        x = NEW(BinaryOperation(op, x, y, position));
+        x = new BinaryOperation(op, x, y, position);
       }
     }
   }
@@ -3063,19 +2436,19 @@
                                    Expression* y,
                                    int position) {
   ASSERT(op != Token::NE && op != Token::NE_STRICT);
-  if (!is_pre_parsing_ && (op == Token::EQ || op == Token::EQ_STRICT)) {
+  if (op == Token::EQ || op == Token::EQ_STRICT) {
     bool is_strict = (op == Token::EQ_STRICT);
     Literal* x_literal = x->AsLiteral();
     if (x_literal != NULL && x_literal->IsNull()) {
-      return NEW(CompareToNull(is_strict, y));
+      return new CompareToNull(is_strict, y);
     }
 
     Literal* y_literal = y->AsLiteral();
     if (y_literal != NULL && y_literal->IsNull()) {
-      return NEW(CompareToNull(is_strict, x));
+      return new CompareToNull(is_strict, x);
     }
   }
-  return NEW(CompareOperation(op, x, y, position));
+  return new CompareOperation(op, x, y, position);
 }
 
 
@@ -3112,7 +2485,7 @@
       }
     }
 
-    return NEW(UnaryOperation(op, expression));
+    return new UnaryOperation(op, expression);
 
   } else if (Token::IsCountOp(op)) {
     op = Next();
@@ -3126,8 +2499,8 @@
       expression = NewThrowReferenceError(type);
     }
     int position = scanner().location().beg_pos;
-    IncrementOperation* increment = NEW(IncrementOperation(op, expression));
-    return NEW(CountOperation(true /* prefix */, increment, position));
+    IncrementOperation* increment = new IncrementOperation(op, expression);
+    return new CountOperation(true /* prefix */, increment, position);
 
   } else {
     return ParsePostfixExpression(ok);
@@ -3151,8 +2524,8 @@
     }
     Token::Value next = Next();
     int position = scanner().location().beg_pos;
-    IncrementOperation* increment = NEW(IncrementOperation(next, expression));
-    expression = NEW(CountOperation(false /* postfix */, increment, position));
+    IncrementOperation* increment = new IncrementOperation(next, expression);
+    expression = new CountOperation(false /* postfix */, increment, position);
   }
   return expression;
 }
@@ -3175,7 +2548,7 @@
         Consume(Token::LBRACK);
         int pos = scanner().location().beg_pos;
         Expression* index = ParseExpression(true, CHECK_OK);
-        result = factory()->NewProperty(result, index, pos);
+        result = new Property(result, index, pos);
         Expect(Token::RBRACK, CHECK_OK);
         break;
       }
@@ -3192,17 +2565,15 @@
         // declared in the current scope chain. These calls are marked as
         // potentially direct eval calls. Whether they are actually direct calls
         // to eval is determined at run time.
-        if (!is_pre_parsing_) {
-          VariableProxy* callee = result->AsVariableProxy();
-          if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) {
-            Handle<String> name = callee->name();
-            Variable* var = top_scope_->Lookup(name);
-            if (var == NULL) {
-              top_scope_->RecordEvalCall();
-            }
+        VariableProxy* callee = result->AsVariableProxy();
+        if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) {
+          Handle<String> name = callee->name();
+          Variable* var = top_scope_->Lookup(name);
+          if (var == NULL) {
+            top_scope_->RecordEvalCall();
           }
         }
-        result = factory()->NewCall(result, args, pos);
+        result = NewCall(result, args, pos);
         break;
       }
 
@@ -3210,7 +2581,7 @@
         Consume(Token::PERIOD);
         int pos = scanner().location().beg_pos;
         Handle<String> name = ParseIdentifierName(CHECK_OK);
-        result = factory()->NewProperty(result, NEW(Literal(name)), pos);
+        result = new Property(result, new Literal(name), pos);
         if (fni_ != NULL) fni_->PushLiteralName(name);
         break;
       }
@@ -3222,7 +2593,6 @@
 }
 
 
-
 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
   // NewExpression ::
   //   ('new')+ MemberExpression
@@ -3247,7 +2617,7 @@
 
   if (!stack->is_empty()) {
     int last = stack->pop();
-    result = NEW(CallNew(result, new ZoneList<Expression*>(0), last));
+    result = new CallNew(result, new ZoneList<Expression*>(0), last);
   }
   return result;
 }
@@ -3289,7 +2659,7 @@
         Consume(Token::LBRACK);
         int pos = scanner().location().beg_pos;
         Expression* index = ParseExpression(true, CHECK_OK);
-        result = factory()->NewProperty(result, index, pos);
+        result = new Property(result, index, pos);
         Expect(Token::RBRACK, CHECK_OK);
         break;
       }
@@ -3297,7 +2667,7 @@
         Consume(Token::PERIOD);
         int pos = scanner().location().beg_pos;
         Handle<String> name = ParseIdentifierName(CHECK_OK);
-        result = factory()->NewProperty(result, NEW(Literal(name)), pos);
+        result = new Property(result, new Literal(name), pos);
         if (fni_ != NULL) fni_->PushLiteralName(name);
         break;
       }
@@ -3306,7 +2676,7 @@
         // Consume one of the new prefixes (already parsed).
         ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
         int last = stack->pop();
-        result = NEW(CallNew(result, args, last));
+        result = new CallNew(result, args, last);
         break;
       }
       default:
@@ -3325,7 +2695,7 @@
 
   Expect(Token::DEBUGGER, CHECK_OK);
   ExpectSemicolon(CHECK_OK);
-  return NEW(DebuggerStatement());
+  return new DebuggerStatement();
 }
 
 
@@ -3383,38 +2753,30 @@
   switch (peek()) {
     case Token::THIS: {
       Consume(Token::THIS);
-      if (is_pre_parsing_) {
-        result = VariableProxySentinel::this_proxy();
-      } else {
-        VariableProxy* recv = top_scope_->receiver();
-        result = recv;
-      }
+      VariableProxy* recv = top_scope_->receiver();
+      result = recv;
       break;
     }
 
     case Token::NULL_LITERAL:
       Consume(Token::NULL_LITERAL);
-      result = NEW(Literal(Factory::null_value()));
+      result = new Literal(Factory::null_value());
       break;
 
     case Token::TRUE_LITERAL:
       Consume(Token::TRUE_LITERAL);
-      result = NEW(Literal(Factory::true_value()));
+      result = new Literal(Factory::true_value());
       break;
 
     case Token::FALSE_LITERAL:
       Consume(Token::FALSE_LITERAL);
-      result = NEW(Literal(Factory::false_value()));
+      result = new Literal(Factory::false_value());
       break;
 
     case Token::IDENTIFIER: {
       Handle<String> name = ParseIdentifier(CHECK_OK);
       if (fni_ != NULL) fni_->PushVariableName(name);
-      if (is_pre_parsing_) {
-        result = VariableProxySentinel::identifier_proxy();
-      } else {
-        result = top_scope_->NewUnresolved(name, inside_with());
-      }
+      result = top_scope_->NewUnresolved(name, inside_with());
       break;
     }
 
@@ -3429,7 +2791,7 @@
     case Token::STRING: {
       Consume(Token::STRING);
       Handle<String> symbol = GetSymbol(CHECK_OK);
-      result = NEW(Literal(symbol));
+      result = new Literal(symbol);
       if (fni_ != NULL) fni_->PushLiteralName(symbol);
       break;
     }
@@ -3507,7 +2869,7 @@
   // ArrayLiteral ::
   //   '[' Expression? (',' Expression?)* ']'
 
-  ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4);
+  ZoneList<Expression*>* values = new ZoneList<Expression*>(4);
   Expect(Token::LBRACK, CHECK_OK);
   while (peek() != Token::RBRACK) {
     Expression* elem;
@@ -3516,7 +2878,7 @@
     } else {
       elem = ParseAssignmentExpression(true, CHECK_OK);
     }
-    values.Add(elem);
+    values->Add(elem);
     if (peek() != Token::RBRACK) {
       Expect(Token::COMMA, CHECK_OK);
     }
@@ -3526,21 +2888,19 @@
   // Update the scope information before the pre-parsing bailout.
   int literal_index = temp_scope_->NextMaterializedLiteralIndex();
 
-  if (is_pre_parsing_) return NULL;
-
   // Allocate a fixed array with all the literals.
   Handle<FixedArray> literals =
-      Factory::NewFixedArray(values.length(), TENURED);
+      Factory::NewFixedArray(values->length(), TENURED);
 
   // Fill in the literals.
   bool is_simple = true;
   int depth = 1;
-  for (int i = 0; i < values.length(); i++) {
-    MaterializedLiteral* m_literal = values.at(i)->AsMaterializedLiteral();
+  for (int i = 0, n = values->length(); i < n; i++) {
+    MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
     if (m_literal != NULL && m_literal->depth() + 1 > depth) {
       depth = m_literal->depth() + 1;
     }
-    Handle<Object> boilerplate_value = GetBoilerplateValue(values.at(i));
+    Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
     if (boilerplate_value->IsUndefined()) {
       literals->set_the_hole(i);
       is_simple = false;
@@ -3551,12 +2911,12 @@
 
   // Simple and shallow arrays can be lazily copied, we transform the
   // elements array to a copy-on-write array.
-  if (is_simple && depth == 1 && values.length() > 0) {
+  if (is_simple && depth == 1 && values->length() > 0) {
     literals->set_map(Heap::fixed_cow_array_map());
   }
 
-  return NEW(ArrayLiteral(literals, values.elements(),
-                          literal_index, is_simple, depth));
+  return new ArrayLiteral(literals, values,
+                          literal_index, is_simple, depth);
 }
 
 
@@ -3703,7 +3063,7 @@
                              DECLARATION,
                              CHECK_OK);
     ObjectLiteral::Property* property =
-        NEW(ObjectLiteral::Property(is_getter, value));
+        new ObjectLiteral::Property(is_getter, value);
     return property;
   } else {
     ReportUnexpectedToken(next);
@@ -3720,8 +3080,8 @@
   //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
   //    )*[','] '}'
 
-  ZoneListWrapper<ObjectLiteral::Property> properties =
-      factory()->NewList<ObjectLiteral::Property>(4);
+  ZoneList<ObjectLiteral::Property*>* properties =
+      new ZoneList<ObjectLiteral::Property*>(4);
   int number_of_boilerplate_properties = 0;
 
   Expect(Token::LBRACE, CHECK_OK);
@@ -3744,7 +3104,7 @@
             if (IsBoilerplateProperty(property)) {
               number_of_boilerplate_properties++;
             }
-            properties.Add(property);
+            properties->Add(property);
             if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
 
             if (fni_ != NULL) {
@@ -3755,7 +3115,7 @@
         }
         // Failed to parse as get/set property, so it's just a property
         // called "get" or "set".
-        key = NEW(Literal(id));
+        key = new Literal(id);
         break;
       }
       case Token::STRING: {
@@ -3767,7 +3127,7 @@
           key = NewNumberLiteral(index);
           break;
         }
-        key = NEW(Literal(string));
+        key = new Literal(string);
         break;
       }
       case Token::NUMBER: {
@@ -3781,7 +3141,7 @@
         if (Token::IsKeyword(next)) {
           Consume(next);
           Handle<String> string = GetSymbol(CHECK_OK);
-          key = NEW(Literal(string));
+          key = new Literal(string);
         } else {
           // Unexpected token.
           Token::Value next = Next();
@@ -3795,11 +3155,11 @@
     Expression* value = ParseAssignmentExpression(true, CHECK_OK);
 
     ObjectLiteral::Property* property =
-        NEW(ObjectLiteral::Property(key, value));
+        new ObjectLiteral::Property(key, value);
 
     // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
     if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
-    properties.Add(property);
+    properties->Add(property);
 
     // TODO(1240767): Consider allowing trailing comma.
     if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
@@ -3812,7 +3172,6 @@
   Expect(Token::RBRACE, CHECK_OK);
   // Computation of literal_index must happen before pre parse bailout.
   int literal_index = temp_scope_->NextMaterializedLiteralIndex();
-  if (is_pre_parsing_) return NULL;
 
   Handle<FixedArray> constant_properties =
       Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
@@ -3820,13 +3179,13 @@
   bool is_simple = true;
   bool fast_elements = true;
   int depth = 1;
-  BuildObjectLiteralConstantProperties(properties.elements(),
+  BuildObjectLiteralConstantProperties(properties,
                                        constant_properties,
                                        &is_simple,
                                        &fast_elements,
                                        &depth);
   return new ObjectLiteral(constant_properties,
-                           properties.elements(),
+                           properties,
                            literal_index,
                            is_simple,
                            fast_elements,
@@ -3844,19 +3203,6 @@
 
   int literal_index = temp_scope_->NextMaterializedLiteralIndex();
 
-  if (is_pre_parsing_) {
-    // If we're preparsing we just do all the parsing stuff without
-    // building anything.
-    if (!scanner_.ScanRegExpFlags()) {
-      Next();
-      ReportMessage("invalid_regexp_flags", Vector<const char*>::empty());
-      *ok = false;
-      return NULL;
-    }
-    Next();
-    return NULL;
-  }
-
   Handle<String> js_pattern =
       Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED);
   scanner_.ScanRegExpFlags();
@@ -3872,17 +3218,17 @@
   // Arguments ::
   //   '(' (AssignmentExpression)*[','] ')'
 
-  ZoneListWrapper<Expression> result = factory()->NewList<Expression>(4);
+  ZoneList<Expression*>* result = new ZoneList<Expression*>(4);
   Expect(Token::LPAREN, CHECK_OK);
   bool done = (peek() == Token::RPAREN);
   while (!done) {
     Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
-    result.Add(argument);
+    result->Add(argument);
     done = (peek() == Token::RPAREN);
     if (!done) Expect(Token::COMMA, CHECK_OK);
   }
   Expect(Token::RPAREN, CHECK_OK);
-  return result.elements();
+  return result;
 }
 
 
@@ -3898,9 +3244,9 @@
   // this is the actual function name, otherwise this is the name of the
   // variable declared and initialized with the function (expression). In
   // that case, we don't have a function name (it's empty).
-  Handle<String> name = is_named ? var_name : factory()->EmptySymbol();
+  Handle<String> name = is_named ? var_name : Factory::empty_symbol();
   // The function name, if any.
-  Handle<String> function_name = factory()->EmptySymbol();
+  Handle<String> function_name = Factory::empty_symbol();
   if (is_named && (type == EXPRESSION || type == NESTED)) {
     function_name = name;
   }
@@ -3908,9 +3254,10 @@
   int num_parameters = 0;
   // Parse function body.
   { Scope* scope =
-        factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
-    LexicalScope lexical_scope(this, scope);
-    TemporaryScope temp_scope(this);
+        NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
+    LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
+                               scope);
+    TemporaryScope temp_scope(&this->temp_scope_);
     top_scope_->SetScopeName(name);
 
     //  FormalParameterList ::
@@ -3920,18 +3267,16 @@
     bool done = (peek() == Token::RPAREN);
     while (!done) {
       Handle<String> param_name = ParseIdentifier(CHECK_OK);
-      if (!is_pre_parsing_) {
-        top_scope_->AddParameter(top_scope_->DeclareLocal(param_name,
-                                                          Variable::VAR));
-        num_parameters++;
-      }
+      top_scope_->AddParameter(top_scope_->DeclareLocal(param_name,
+                                                        Variable::VAR));
+      num_parameters++;
       done = (peek() == Token::RPAREN);
       if (!done) Expect(Token::COMMA, CHECK_OK);
     }
     Expect(Token::RPAREN, CHECK_OK);
 
     Expect(Token::LBRACE, CHECK_OK);
-    ZoneListWrapper<Statement> body = factory()->NewList<Statement>(8);
+    ZoneList<Statement*>* body = new ZoneList<Statement*>(8);
 
     // If we have a named function expression, we add a local variable
     // declaration to the body of the function with the name of the
@@ -3939,17 +3284,15 @@
     // NOTE: We create a proxy and resolve it here so that in the
     // future we can change the AST to only refer to VariableProxies
     // instead of Variables and Proxis as is the case now.
-    if (!is_pre_parsing_
-        && !function_name.is_null()
-        && function_name->length() > 0) {
+    if (!function_name.is_null() && function_name->length() > 0) {
       Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
       VariableProxy* fproxy =
           top_scope_->NewUnresolved(function_name, inside_with());
       fproxy->BindTo(fvar);
-      body.Add(new ExpressionStatement(
-                   new Assignment(Token::INIT_CONST, fproxy,
-                                  NEW(ThisFunction()),
-                                  RelocInfo::kNoPosition)));
+      body->Add(new ExpressionStatement(
+                    new Assignment(Token::INIT_CONST, fproxy,
+                                   new ThisFunction(),
+                                   RelocInfo::kNoPosition)));
     }
 
     // Determine if the function will be lazily compiled. The mode can
@@ -3981,12 +3324,8 @@
       this_property_assignments = Factory::empty_fixed_array();
       Expect(Token::RBRACE, CHECK_OK);
     } else {
-      FunctionEntry entry;
-      if (is_lazily_compiled) entry = log()->LogFunction(function_block_pos);
-      {
-        ConditionalLogPauseScope pause_if(is_lazily_compiled, log());
-        ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
-      }
+      ParseSourceElements(body, Token::RBRACE, CHECK_OK);
+
       materialized_literal_count = temp_scope.materialized_literal_count();
       expected_property_count = temp_scope.expected_property_count();
       only_simple_this_property_assignments =
@@ -3995,19 +3334,12 @@
 
       Expect(Token::RBRACE, CHECK_OK);
       end_pos = scanner_.location().end_pos;
-      if (entry.is_valid()) {
-        ASSERT(is_lazily_compiled);
-        ASSERT(is_pre_parsing_);
-        entry.set_end_pos(end_pos);
-        entry.set_literal_count(materialized_literal_count);
-        entry.set_property_count(expected_property_count);
-      }
     }
 
     FunctionLiteral* function_literal =
-        NEW(FunctionLiteral(name,
+        new FunctionLiteral(name,
                             top_scope_,
-                            body.elements(),
+                            body,
                             materialized_literal_count,
                             expected_property_count,
                             only_simple_this_property_assignments,
@@ -4016,10 +3348,8 @@
                             start_pos,
                             end_pos,
                             function_name->length() > 0,
-                            temp_scope.ContainsLoops()));
-    if (!is_pre_parsing_) {
-      function_literal->set_function_token_position(function_token_position);
-    }
+                            temp_scope.ContainsLoops());
+    function_literal->set_function_token_position(function_token_position);
 
     if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
     return function_literal;
@@ -4034,7 +3364,6 @@
   Expect(Token::MOD, CHECK_OK);
   Handle<String> name = ParseIdentifier(CHECK_OK);
   ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
-  if (is_pre_parsing_) return NULL;
 
   if (extension_ != NULL) {
     // The extension structures are only accessible while parsing the
@@ -4070,7 +3399,7 @@
   }
 
   // We have a valid intrinsics call or a call to a builtin.
-  return NEW(CallRuntime(name, function, args));
+  return new CallRuntime(name, function, args);
 }
 
 
@@ -4118,12 +3447,12 @@
 
 
 Literal* Parser::GetLiteralUndefined() {
-  return NEW(Literal(Factory::undefined_value()));
+  return new Literal(Factory::undefined_value());
 }
 
 
 Literal* Parser::GetLiteralTheHole() {
-  return NEW(Literal(Factory::the_hole_value()));
+  return new Literal(Factory::the_hole_value());
 }
 
 
@@ -4226,7 +3555,7 @@
 
 
 Literal* Parser::NewNumberLiteral(double number) {
-  return NEW(Literal(Factory::NewNumber(number, TENURED)));
+  return new Literal(Factory::NewNumber(number, TENURED));
 }
 
 
@@ -4258,8 +3587,6 @@
 Expression* Parser::NewThrowError(Handle<String> constructor,
                                   Handle<String> type,
                                   Vector< Handle<Object> > arguments) {
-  if (is_pre_parsing_) return NULL;
-
   int argc = arguments.length();
   Handle<JSArray> array = Factory::NewJSArray(argc, TENURED);
   ASSERT(array->IsJSArray() && array->HasFastElements());
@@ -4281,145 +3608,165 @@
 // ----------------------------------------------------------------------------
 // JSON
 
-Expression* Parser::ParseJson(bool* ok) {
-  Expression* result = ParseJsonValue(CHECK_OK);
-  Expect(Token::EOS, CHECK_OK);
+Handle<Object> JsonParser::ParseJson(Handle<String> source) {
+  source->TryFlatten();
+  scanner_.Initialize(source, JSON);
+  Handle<Object> result = ParseJsonValue();
+  if (result.is_null() || scanner_.Next() != Token::EOS) {
+    if (scanner_.stack_overflow()) {
+      // Scanner failed.
+      Top::StackOverflow();
+    } else {
+      // Parse failed. Scanner's current token is the unexpected token.
+      Token::Value token = scanner_.current_token();
+
+      const char* message;
+      const char* name_opt = NULL;
+
+      switch (token) {
+        case Token::EOS:
+          message = "unexpected_eos";
+          break;
+        case Token::NUMBER:
+          message = "unexpected_token_number";
+          break;
+        case Token::STRING:
+          message = "unexpected_token_string";
+          break;
+        case Token::IDENTIFIER:
+          message = "unexpected_token_identifier";
+          break;
+        default:
+          message = "unexpected_token";
+          name_opt = Token::String(token);
+          ASSERT(name_opt != NULL);
+          break;
+      }
+
+      Scanner::Location source_location = scanner_.location();
+      MessageLocation location(Factory::NewScript(source),
+                               source_location.beg_pos,
+                               source_location.end_pos);
+      int argc = (name_opt == NULL) ? 0 : 1;
+      Handle<JSArray> array = Factory::NewJSArray(argc);
+      if (name_opt != NULL) {
+        SetElement(array,
+                   0,
+                   Factory::NewStringFromUtf8(CStrVector(name_opt)));
+      }
+      Handle<Object> result = Factory::NewSyntaxError(message, array);
+      Top::Throw(*result, &location);
+      return Handle<Object>::null();
+    }
+  }
   return result;
 }
 
 
+Handle<String> JsonParser::GetString() {
+  int literal_length = scanner_.literal_length();
+  if (literal_length == 0) {
+    return Factory::empty_string();
+  }
+  const char* literal_string = scanner_.literal_string();
+  Vector<const char> literal(literal_string, literal_length);
+  return Factory::NewStringFromUtf8(literal);
+}
+
+
 // Parse any JSON value.
-Expression* Parser::ParseJsonValue(bool* ok) {
-  Token::Value token = peek();
+Handle<Object> JsonParser::ParseJsonValue() {
+  Token::Value token = scanner_.Next();
   switch (token) {
     case Token::STRING: {
-      Consume(Token::STRING);
-      int literal_length = scanner_.literal_length();
-      const char* literal_string = scanner_.literal_string();
-      if (literal_length == 0) {
-        return NEW(Literal(Factory::empty_string()));
-      }
-      Vector<const char> literal(literal_string, literal_length);
-      return NEW(Literal(Factory::NewStringFromUtf8(literal, TENURED)));
+      return GetString();
     }
     case Token::NUMBER: {
-      Consume(Token::NUMBER);
-      ASSERT(scanner_.literal_length() > 0);
       double value = StringToDouble(scanner_.literal(),
                                     NO_FLAGS,  // Hex, octal or trailing junk.
                                     OS::nan_value());
-      return NewNumberLiteral(value);
+      return Factory::NewNumber(value);
     }
     case Token::FALSE_LITERAL:
-      Consume(Token::FALSE_LITERAL);
-      return NEW(Literal(Factory::false_value()));
+      return Factory::false_value();
     case Token::TRUE_LITERAL:
-      Consume(Token::TRUE_LITERAL);
-      return NEW(Literal(Factory::true_value()));
+      return Factory::true_value();
     case Token::NULL_LITERAL:
-      Consume(Token::NULL_LITERAL);
-      return NEW(Literal(Factory::null_value()));
-    case Token::LBRACE: {
-      Expression* result = ParseJsonObject(CHECK_OK);
-      return result;
-    }
-    case Token::LBRACK: {
-      Expression* result = ParseJsonArray(CHECK_OK);
-      return result;
-    }
+      return Factory::null_value();
+    case Token::LBRACE:
+      return ParseJsonObject();
+    case Token::LBRACK:
+      return ParseJsonArray();
     default:
-      *ok = false;
-      ReportUnexpectedToken(token);
-      return NULL;
+      return ReportUnexpectedToken();
   }
 }
 
 
 // Parse a JSON object. Scanner must be right after '{' token.
-Expression* Parser::ParseJsonObject(bool* ok) {
-  Consume(Token::LBRACE);
-  ZoneListWrapper<ObjectLiteral::Property> properties =
-      factory()->NewList<ObjectLiteral::Property>(4);
-  int boilerplate_properties = 0;
-  if (peek() != Token::RBRACE) {
+Handle<Object> JsonParser::ParseJsonObject() {
+  Handle<JSFunction> object_constructor(
+      Top::global_context()->object_function());
+  Handle<JSObject> json_object = Factory::NewJSObject(object_constructor);
+  if (scanner_.peek() == Token::RBRACE) {
+    scanner_.Next();
+  } else {
     do {
-      Expect(Token::STRING, CHECK_OK);
-      Handle<String> key = GetSymbol(CHECK_OK);
-      Expect(Token::COLON, CHECK_OK);
-      Expression* value = ParseJsonValue(CHECK_OK);
-      Literal* key_literal;
+      if (scanner_.Next() != Token::STRING) {
+        return ReportUnexpectedToken();
+      }
+      Handle<String> key = GetString();
+      if (scanner_.Next() != Token::COLON) {
+        return ReportUnexpectedToken();
+      }
+      Handle<Object> value = ParseJsonValue();
+      if (value.is_null()) return Handle<Object>::null();
       uint32_t index;
       if (key->AsArrayIndex(&index)) {
-        key_literal = NewNumberLiteral(index);
+        SetElement(json_object, index, value);
       } else {
-        key_literal = NEW(Literal(key));
+        SetProperty(json_object, key, value, NONE);
       }
-      ObjectLiteral::Property* property =
-          NEW(ObjectLiteral::Property(key_literal, value));
-      properties.Add(property);
-
-      if (IsBoilerplateProperty(property)) {
-        boilerplate_properties++;
-      }
-    } while (Check(Token::COMMA));
+    } while (scanner_.Next() == Token::COMMA);
+    if (scanner_.current_token() != Token::RBRACE) {
+      return ReportUnexpectedToken();
+    }
   }
-  Expect(Token::RBRACE, CHECK_OK);
-
-  int literal_index = temp_scope_->NextMaterializedLiteralIndex();
-  if (is_pre_parsing_) return NULL;
-
-  Handle<FixedArray> constant_properties =
-        Factory::NewFixedArray(boilerplate_properties * 2, TENURED);
-  bool is_simple = true;
-  bool fast_elements = true;
-  int depth = 1;
-  BuildObjectLiteralConstantProperties(properties.elements(),
-                                       constant_properties,
-                                       &is_simple,
-                                       &fast_elements,
-                                       &depth);
-  return new ObjectLiteral(constant_properties,
-                           properties.elements(),
-                           literal_index,
-                           is_simple,
-                           fast_elements,
-                           depth);
+  return json_object;
 }
 
 
 // Parse a JSON array. Scanner must be right after '[' token.
-Expression* Parser::ParseJsonArray(bool* ok) {
-  Consume(Token::LBRACK);
+Handle<Object> JsonParser::ParseJsonArray() {
+  ZoneScope zone_scope(DELETE_ON_EXIT);
+  ZoneList<Handle<Object> > elements(4);
 
-  ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4);
-  if (peek() != Token::RBRACK) {
+  Token::Value token = scanner_.peek();
+  if (token == Token::RBRACK) {
+    scanner_.Next();
+  } else {
     do {
-      Expression* exp = ParseJsonValue(CHECK_OK);
-      values.Add(exp);
-    } while (Check(Token::COMMA));
+      Handle<Object> element = ParseJsonValue();
+      if (element.is_null()) return Handle<Object>::null();
+      elements.Add(element);
+      token = scanner_.Next();
+    } while (token == Token::COMMA);
+    if (token != Token::RBRACK) {
+      return ReportUnexpectedToken();
+    }
   }
-  Expect(Token::RBRACK, CHECK_OK);
 
-  // Update the scope information before the pre-parsing bailout.
-  int literal_index = temp_scope_->NextMaterializedLiteralIndex();
+  // Allocate a fixed array with all the elements.
+  Handle<FixedArray> fast_elements =
+      Factory::NewFixedArray(elements.length());
 
-  if (is_pre_parsing_) return NULL;
+  for (int i = 0, n = elements.length(); i < n; i++) {
+    fast_elements->set(i, *elements[i]);
+  }
 
-  // Allocate a fixed array with all the literals.
-  Handle<FixedArray> literals =
-      Factory::NewFixedArray(values.length(), TENURED);
-
-  bool is_simple;
-  int depth;
-  BuildArrayLiteralBoilerplateLiterals(values.elements(),
-                                       literals,
-                                       &is_simple,
-                                       &depth);
-  return NEW(ArrayLiteral(literals, values.elements(),
-                          literal_index, is_simple, depth));
+  return Factory::NewJSArrayWithElements(fast_elements);
 }
 
-
 // ----------------------------------------------------------------------------
 // Regular expressions
 
@@ -4427,17 +3774,17 @@
 RegExpParser::RegExpParser(FlatStringReader* in,
                            Handle<String>* error,
                            bool multiline)
-  : current_(kEndMarker),
+  : error_(error),
+    captures_(NULL),
+    in_(in),
+    current_(kEndMarker),
+    next_pos_(0),
+    capture_count_(0),
     has_more_(true),
     multiline_(multiline),
-    next_pos_(0),
-    in_(in),
-    error_(error),
     simple_(false),
     contains_anchor_(false),
-    captures_(NULL),
     is_scanned_for_captures_(false),
-    capture_count_(0),
     failed_(false) {
   Advance(1);
 }
@@ -5245,23 +4592,6 @@
 }
 
 
-// Preparse, but only collect data that is immediately useful,
-// even if the preparser data is only used once.
-ScriptDataImpl* Parser::PartialPreParse(Handle<String> source,
-                                        unibrow::CharacterStream* stream,
-                                        v8::Extension* extension) {
-  Handle<Script> no_script;
-  bool allow_natives_syntax =
-      FLAG_allow_natives_syntax || Bootstrapper::IsActive();
-  PartialPreParser parser(no_script, allow_natives_syntax, extension);
-  if (!parser.PreParseProgram(source, stream)) return NULL;
-  // Extract the accumulated data from the recorder as a single
-  // contiguous vector that we are responsible for disposing.
-  Vector<unsigned> store = parser.recorder()->ExtractData();
-  return new ScriptDataImpl(store);
-}
-
-
 void ScriptDataImpl::Initialize() {
   // Prepares state for use.
   if (store_.length() >= kHeaderSize) {
@@ -5305,24 +4635,57 @@
 }
 
 
-ScriptDataImpl* Parser::PreParse(Handle<String> source,
-                                 unibrow::CharacterStream* stream,
-                                 v8::Extension* extension) {
+// Preparse, but only collect data that is immediately useful,
+// even if the preparser data is only used once.
+ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source,
+                                           unibrow::CharacterStream* stream,
+                                           v8::Extension* extension) {
   Handle<Script> no_script;
-  bool allow_natives_syntax =
-      FLAG_allow_natives_syntax || Bootstrapper::IsActive();
-  CompletePreParser parser(no_script, allow_natives_syntax, extension);
-  if (!parser.PreParseProgram(source, stream)) return NULL;
+  bool allow_lazy = FLAG_lazy && (extension == NULL);
+  if (!allow_lazy) {
+    // Partial preparsing is only about lazily compiled functions.
+    // If we don't allow lazy compilation, the log data will be empty.
+    return NULL;
+  }
+  preparser::PreParser<Scanner, PartialParserRecorder> parser;
+  Scanner scanner;
+  scanner.Initialize(source, stream, JAVASCRIPT);
+  PartialParserRecorder recorder;
+  if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) {
+    Top::StackOverflow();
+    return NULL;
+  }
+
   // Extract the accumulated data from the recorder as a single
   // contiguous vector that we are responsible for disposing.
-  Vector<unsigned> store = parser.recorder()->ExtractData();
+  Vector<unsigned> store = recorder.ExtractData();
   return new ScriptDataImpl(store);
 }
 
 
-bool Parser::ParseRegExp(FlatStringReader* input,
-                         bool multiline,
-                         RegExpCompileData* result) {
+ScriptDataImpl* ParserApi::PreParse(Handle<String> source,
+                                    unibrow::CharacterStream* stream,
+                                    v8::Extension* extension) {
+  Handle<Script> no_script;
+  preparser::PreParser<Scanner, CompleteParserRecorder> parser;
+  Scanner scanner;
+  scanner.Initialize(source, stream, JAVASCRIPT);
+  bool allow_lazy = FLAG_lazy && (extension == NULL);
+  CompleteParserRecorder recorder;
+  if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) {
+    Top::StackOverflow();
+    return NULL;
+  }
+  // Extract the accumulated data from the recorder as a single
+  // contiguous vector that we are responsible for disposing.
+  Vector<unsigned> store = recorder.ExtractData();
+  return new ScriptDataImpl(store);
+}
+
+
+bool RegExpParser::ParseRegExp(FlatStringReader* input,
+                               bool multiline,
+                               RegExpCompileData* result) {
   ASSERT(result != NULL);
   RegExpParser parser(input, &result->error, multiline);
   RegExpTree* tree = parser.ParsePattern();
@@ -5342,19 +4705,18 @@
 }
 
 
-bool Parser::Parse(CompilationInfo* info) {
+bool ParserApi::Parse(CompilationInfo* info) {
   ASSERT(info->function() == NULL);
   FunctionLiteral* result = NULL;
   Handle<Script> script = info->script();
   if (info->is_lazy()) {
-    AstBuildingParser parser(script, true, NULL, NULL);
+    Parser parser(script, true, NULL, NULL);
     result = parser.ParseLazy(info->shared_info());
   } else {
     bool allow_natives_syntax =
         FLAG_allow_natives_syntax || Bootstrapper::IsActive();
     ScriptDataImpl* pre_data = info->pre_parse_data();
-    AstBuildingParser parser(script, allow_natives_syntax, info->extension(),
-                             pre_data);
+    Parser parser(script, allow_natives_syntax, info->extension(), pre_data);
     if (pre_data != NULL && pre_data->has_error()) {
       Scanner::Location loc = pre_data->MessageLocation();
       const char* message = pre_data->BuildMessage();
@@ -5368,11 +4730,7 @@
       ASSERT(Top::has_pending_exception());
     } else {
       Handle<String> source = Handle<String>(String::cast(script->source()));
-      // JSON is always global.
-      ASSERT(!info->is_json() || info->is_global());
-      result = info->is_json()
-          ? parser.ParseJson(source)
-          : parser.ParseProgram(source, info->is_global());
+      result = parser.ParseProgram(source, info->is_global());
     }
   }
 
@@ -5380,6 +4738,4 @@
   return (result != NULL);
 }
 
-#undef NEW
-
 } }  // namespace v8::internal
diff --git a/src/parser.h b/src/parser.h
index 7142551..667410b 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -31,13 +31,13 @@
 #include "allocation.h"
 #include "ast.h"
 #include "scanner.h"
+#include "scopes.h"
 
 namespace v8 {
 namespace internal {
 
 class CompilationInfo;
 class FuncNameInferrer;
-class ParserFactory;
 class ParserLog;
 class PositionStack;
 class Target;
@@ -177,13 +177,127 @@
 };
 
 
-class Parser {
+// Record only functions.
+class PartialParserRecorder {
  public:
-  Parser(Handle<Script> script, bool allow_natives_syntax,
-         v8::Extension* extension, ParserMode is_pre_parsing,
-         ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data);
-  virtual ~Parser() { }
+  PartialParserRecorder();
 
+  void LogFunction(int start, int end, int literals, int properties) {
+    function_store_.Add(start);
+    function_store_.Add(end);
+    function_store_.Add(literals);
+    function_store_.Add(properties);
+  }
+
+  void LogSymbol(int start, const char* symbol, int length) { }
+
+  // Logs an error message and marks the log as containing an error.
+  // Further logging will be ignored, and ExtractData will return a vector
+  // representing the error only.
+  void LogMessage(int start,
+                  int end,
+                  const char* message,
+                  const char* argument_opt) {
+    Scanner::Location location(start, end);
+    Vector<const char*> arguments;
+    if (argument_opt != NULL) {
+      arguments = Vector<const char*>(&argument_opt, 1);
+    }
+    this->LogMessage(location, message, arguments);
+  }
+
+  int function_position() { return function_store_.size(); }
+
+  void LogMessage(Scanner::Location loc,
+                  const char* message,
+                  Vector<const char*> args);
+
+  Vector<unsigned> ExtractData();
+
+  void PauseRecording() {
+    pause_count_++;
+    is_recording_ = false;
+  }
+
+  void ResumeRecording() {
+    ASSERT(pause_count_ > 0);
+    if (--pause_count_ == 0) is_recording_ = !has_error();
+  }
+
+  int symbol_position() { return 0; }
+  int symbol_ids() { return 0; }
+
+ protected:
+  bool has_error() {
+    return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
+  }
+
+  bool is_recording() {
+    return is_recording_;
+  }
+
+  void WriteString(Vector<const char> str);
+
+  Collector<unsigned> function_store_;
+  unsigned preamble_[ScriptDataImpl::kHeaderSize];
+  bool is_recording_;
+  int pause_count_;
+
+#ifdef DEBUG
+  int prev_start_;
+#endif
+};
+
+
+// Record both functions and symbols.
+class CompleteParserRecorder: public PartialParserRecorder {
+ public:
+  CompleteParserRecorder();
+
+  void LogSymbol(int start, Vector<const char> literal);
+
+  void LogSymbol(int start, const char* symbol, int length) {
+    LogSymbol(start, Vector<const char>(symbol, length));
+  }
+
+  Vector<unsigned> ExtractData();
+
+  int symbol_position() { return symbol_store_.size(); }
+  int symbol_ids() { return symbol_id_; }
+
+ private:
+  static int vector_hash(Vector<const char> string) {
+    int hash = 0;
+    for (int i = 0; i < string.length(); i++) {
+      int c = string[i];
+      hash += c;
+      hash += (hash << 10);
+      hash ^= (hash >> 6);
+    }
+    return hash;
+  }
+
+  static bool vector_compare(void* a, void* b) {
+    Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a);
+    Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b);
+    int length = string1->length();
+    if (string2->length() != length) return false;
+    return memcmp(string1->start(), string2->start(), length) == 0;
+  }
+
+  // Write a non-negative number to the symbol store.
+  void WriteNumber(int number);
+
+  Collector<byte> symbol_store_;
+  Collector<Vector<const char> > symbol_entries_;
+  HashMap symbol_table_;
+  int symbol_id_;
+};
+
+
+
+class ParserApi {
+ public:
   // Parses the source code represented by the compilation info and sets its
   // function literal.  Returns false (and deallocates any allocated AST
   // nodes) if parsing failed.
@@ -199,34 +313,263 @@
   static ScriptDataImpl* PartialPreParse(Handle<String> source,
                                          unibrow::CharacterStream* stream,
                                          v8::Extension* extension);
+};
+
+// ----------------------------------------------------------------------------
+// REGEXP PARSING
+
+// A BuffferedZoneList is an automatically growing list, just like (and backed
+// by) a ZoneList, that is optimized for the case of adding and removing
+// a single element. The last element added is stored outside the backing list,
+// and if no more than one element is ever added, the ZoneList isn't even
+// allocated.
+// Elements must not be NULL pointers.
+template <typename T, int initial_size>
+class BufferedZoneList {
+ public:
+  BufferedZoneList() : list_(NULL), last_(NULL) {}
+
+  // Adds element at end of list. This element is buffered and can
+  // be read using last() or removed using RemoveLast until a new Add or until
+  // RemoveLast or GetList has been called.
+  void Add(T* value) {
+    if (last_ != NULL) {
+      if (list_ == NULL) {
+        list_ = new ZoneList<T*>(initial_size);
+      }
+      list_->Add(last_);
+    }
+    last_ = value;
+  }
+
+  T* last() {
+    ASSERT(last_ != NULL);
+    return last_;
+  }
+
+  T* RemoveLast() {
+    ASSERT(last_ != NULL);
+    T* result = last_;
+    if ((list_ != NULL) && (list_->length() > 0))
+      last_ = list_->RemoveLast();
+    else
+      last_ = NULL;
+    return result;
+  }
+
+  T* Get(int i) {
+    ASSERT((0 <= i) && (i < length()));
+    if (list_ == NULL) {
+      ASSERT_EQ(0, i);
+      return last_;
+    } else {
+      if (i == list_->length()) {
+        ASSERT(last_ != NULL);
+        return last_;
+      } else {
+        return list_->at(i);
+      }
+    }
+  }
+
+  void Clear() {
+    list_ = NULL;
+    last_ = NULL;
+  }
+
+  int length() {
+    int length = (list_ == NULL) ? 0 : list_->length();
+    return length + ((last_ == NULL) ? 0 : 1);
+  }
+
+  ZoneList<T*>* GetList() {
+    if (list_ == NULL) {
+      list_ = new ZoneList<T*>(initial_size);
+    }
+    if (last_ != NULL) {
+      list_->Add(last_);
+      last_ = NULL;
+    }
+    return list_;
+  }
+
+ private:
+  ZoneList<T*>* list_;
+  T* last_;
+};
+
+
+// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
+class RegExpBuilder: public ZoneObject {
+ public:
+  RegExpBuilder();
+  void AddCharacter(uc16 character);
+  // "Adds" an empty expression. Does nothing except consume a
+  // following quantifier
+  void AddEmpty();
+  void AddAtom(RegExpTree* tree);
+  void AddAssertion(RegExpTree* tree);
+  void NewAlternative();  // '|'
+  void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type);
+  RegExpTree* ToRegExp();
+
+ private:
+  void FlushCharacters();
+  void FlushText();
+  void FlushTerms();
+  bool pending_empty_;
+  ZoneList<uc16>* characters_;
+  BufferedZoneList<RegExpTree, 2> terms_;
+  BufferedZoneList<RegExpTree, 2> text_;
+  BufferedZoneList<RegExpTree, 2> alternatives_;
+#ifdef DEBUG
+  enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
+#define LAST(x) last_added_ = x;
+#else
+#define LAST(x)
+#endif
+};
+
+
+class RegExpParser {
+ public:
+  RegExpParser(FlatStringReader* in,
+               Handle<String>* error,
+               bool multiline_mode);
 
   static bool ParseRegExp(FlatStringReader* input,
                           bool multiline,
                           RegExpCompileData* result);
 
-  // Pre-parse the program from the character stream; returns true on
-  // success, false if a stack-overflow happened during parsing.
-  bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream);
+  RegExpTree* ParsePattern();
+  RegExpTree* ParseDisjunction();
+  RegExpTree* ParseGroup();
+  RegExpTree* ParseCharacterClass();
 
-  void ReportMessage(const char* message, Vector<const char*> args);
-  virtual void ReportMessageAt(Scanner::Location loc,
-                               const char* message,
-                               Vector<const char*> args) = 0;
+  // Parses a {...,...} quantifier and stores the range in the given
+  // out parameters.
+  bool ParseIntervalQuantifier(int* min_out, int* max_out);
 
+  // Parses and returns a single escaped character.  The character
+  // must not be 'b' or 'B' since they are usually handle specially.
+  uc32 ParseClassCharacterEscape();
+
+  // Checks whether the following is a length-digit hexadecimal number,
+  // and sets the value if it is.
+  bool ParseHexEscape(int length, uc32* value);
+
+  uc32 ParseControlLetterEscape();
+  uc32 ParseOctalLiteral();
+
+  // Tries to parse the input as a back reference.  If successful it
+  // stores the result in the output parameter and returns true.  If
+  // it fails it will push back the characters read so the same characters
+  // can be reparsed.
+  bool ParseBackReferenceIndex(int* index_out);
+
+  CharacterRange ParseClassAtom(uc16* char_class);
+  RegExpTree* ReportError(Vector<const char> message);
+  void Advance();
+  void Advance(int dist);
+  void Reset(int pos);
+
+  // Reports whether the pattern might be used as a literal search string.
+  // Only use if the result of the parse is a single atom node.
+  bool simple();
+  bool contains_anchor() { return contains_anchor_; }
+  void set_contains_anchor() { contains_anchor_ = true; }
+  int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
+  int position() { return next_pos_ - 1; }
+  bool failed() { return failed_; }
+
+  static const int kMaxCaptures = 1 << 16;
+  static const uc32 kEndMarker = (1 << 21);
+
+ private:
+  enum SubexpressionType {
+    INITIAL,
+    CAPTURE,  // All positive values represent captures.
+    POSITIVE_LOOKAHEAD,
+    NEGATIVE_LOOKAHEAD,
+    GROUPING
+  };
+
+  class RegExpParserState : public ZoneObject {
+   public:
+    RegExpParserState(RegExpParserState* previous_state,
+                      SubexpressionType group_type,
+                      int disjunction_capture_index)
+        : previous_state_(previous_state),
+          builder_(new RegExpBuilder()),
+          group_type_(group_type),
+          disjunction_capture_index_(disjunction_capture_index) {}
+    // Parser state of containing expression, if any.
+    RegExpParserState* previous_state() { return previous_state_; }
+    bool IsSubexpression() { return previous_state_ != NULL; }
+    // RegExpBuilder building this regexp's AST.
+    RegExpBuilder* builder() { return builder_; }
+    // Type of regexp being parsed (parenthesized group or entire regexp).
+    SubexpressionType group_type() { return group_type_; }
+    // Index in captures array of first capture in this sub-expression, if any.
+    // Also the capture index of this sub-expression itself, if group_type
+    // is CAPTURE.
+    int capture_index() { return disjunction_capture_index_; }
+
+   private:
+    // Linked list implementation of stack of states.
+    RegExpParserState* previous_state_;
+    // Builder for the stored disjunction.
+    RegExpBuilder* builder_;
+    // Stored disjunction type (capture, look-ahead or grouping), if any.
+    SubexpressionType group_type_;
+    // Stored disjunction's capture index (if any).
+    int disjunction_capture_index_;
+  };
+
+  uc32 current() { return current_; }
+  bool has_more() { return has_more_; }
+  bool has_next() { return next_pos_ < in()->length(); }
+  uc32 Next();
+  FlatStringReader* in() { return in_; }
+  void ScanForCaptures();
+
+  Handle<String>* error_;
+  ZoneList<RegExpCapture*>* captures_;
+  FlatStringReader* in_;
+  uc32 current_;
+  int next_pos_;
+  // The capture count is only valid after we have scanned for captures.
+  int capture_count_;
+  bool has_more_;
+  bool multiline_;
+  bool simple_;
+  bool contains_anchor_;
+  bool is_scanned_for_captures_;
+  bool failed_;
+};
+
+// ----------------------------------------------------------------------------
+// JAVASCRIPT PARSING
+
+class Parser {
+ public:
+  Parser(Handle<Script> script,
+         bool allow_natives_syntax,
+         v8::Extension* extension,
+         ScriptDataImpl* pre_data);
+  virtual ~Parser() { }
 
   // Returns NULL if parsing failed.
   FunctionLiteral* ParseProgram(Handle<String> source,
                                 bool in_global_context);
-  FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info);
-  FunctionLiteral* ParseJson(Handle<String> source);
 
-  // The minimum number of contiguous assignment that will
-  // be treated as an initialization block. Benchmarks show that
-  // the overhead exceeds the savings below this limit.
-  static const int kMinInitializationBlock = 3;
+  FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info);
+
+  void ReportMessageAt(Scanner::Location loc,
+                       const char* message,
+                       Vector<const char*> args);
 
  protected:
-
   enum Mode {
     PARSE_LAZILY,
     PARSE_EAGERLY
@@ -235,28 +578,9 @@
   // Report syntax error
   void ReportUnexpectedToken(Token::Value token);
   void ReportInvalidPreparseData(Handle<String> name, bool* ok);
-
-  Handle<Script> script_;
-  Scanner scanner_;
-
-  Scope* top_scope_;
-  int with_nesting_level_;
-
-  TemporaryScope* temp_scope_;
-  Mode mode_;
-
-  Target* target_stack_;  // for break, continue statements
-  bool allow_natives_syntax_;
-  v8::Extension* extension_;
-  ParserFactory* factory_;
-  ParserLog* log_;
-  bool is_pre_parsing_;
-  ScriptDataImpl* pre_data_;
-  FuncNameInferrer* fni_;
+  void ReportMessage(const char* message, Vector<const char*> args);
 
   bool inside_with() const { return with_nesting_level_ > 0; }
-  ParserFactory* factory() const { return factory_; }
-  ParserLog* log() const { return log_; }
   Scanner& scanner()  { return scanner_; }
   Mode mode() const { return mode_; }
   ScriptDataImpl* pre_data() const { return pre_data_; }
@@ -265,7 +589,7 @@
   // which is set to false if parsing failed; it is unchanged otherwise.
   // By making the 'exception handling' explicit, we are forced to check
   // for failure at the call sites.
-  void* ParseSourceElements(ZoneListWrapper<Statement>* processor,
+  void* ParseSourceElements(ZoneList<Statement*>* processor,
                             int end_token, bool* ok);
   Statement* ParseStatement(ZoneStringList* labels, bool* ok);
   Statement* ParseFunctionDeclaration(bool* ok);
@@ -378,10 +702,10 @@
                                            bool* ok);
 
   // Parser support
-  virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
-                                 FunctionLiteral* fun,
-                                 bool resolve,
-                                 bool* ok) = 0;
+  VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
+                         FunctionLiteral* fun,
+                         bool resolve,
+                         bool* ok);
 
   bool TargetStackContainsLabel(Handle<String> label);
   BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
@@ -389,6 +713,28 @@
 
   void RegisterTargetUse(BreakTarget* target, Target* stop);
 
+  // Factory methods.
+
+  Statement* EmptyStatement() {
+    static v8::internal::EmptyStatement empty;
+    return &empty;
+  }
+
+  Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
+
+  Handle<String> LookupSymbol(int symbol_id,
+                              Vector<const char> string);
+
+  Handle<String> LookupCachedSymbol(int symbol_id,
+                                    Vector<const char> string);
+
+  Expression* NewCall(Expression* expression,
+                      ZoneList<Expression*>* arguments,
+                      int pos) {
+    return new Call(expression, arguments, pos);
+  }
+
+
   // Create a number literal.
   Literal* NewNumberLiteral(double value);
 
@@ -411,33 +757,23 @@
                             Handle<String> type,
                             Vector< Handle<Object> > arguments);
 
-  // JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
-  // specification section 15.12.1 (and appendix A.8).
-  // The grammar is given section 15.12.1.2 (and appendix A.8.2).
+  ZoneList<Handle<String> > symbol_cache_;
 
-  // Parse JSON input as a single JSON value.
-  Expression* ParseJson(bool* ok);
+  Handle<Script> script_;
+  Scanner scanner_;
 
-  // Parse a single JSON value from input (grammar production JSONValue).
-  // A JSON value is either a (double-quoted) string literal, a number literal,
-  // one of "true", "false", or "null", or an object or array literal.
-  Expression* ParseJsonValue(bool* ok);
-  // Parse a JSON object literal (grammar production JSONObject).
-  // An object literal is a squiggly-braced and comma separated sequence
-  // (possibly empty) of key/value pairs, where the key is a JSON string
-  // literal, the value is a JSON value, and the two are spearated by a colon.
-  // A JavaScript object also allows numbers and identifiers as keys.
-  Expression* ParseJsonObject(bool* ok);
-  // Parses a JSON array literal (grammar production JSONArray). An array
-  // literal is a square-bracketed and comma separated sequence (possibly empty)
-  // of JSON values.
-  // A JavaScript array allows leaving out values from the sequence.
-  Expression* ParseJsonArray(bool* ok);
+  Scope* top_scope_;
+  int with_nesting_level_;
 
-  friend class Target;
-  friend class TargetScope;
-  friend class LexicalScope;
-  friend class TemporaryScope;
+  TemporaryScope* temp_scope_;
+  Mode mode_;
+
+  Target* target_stack_;  // for break, continue statements
+  bool allow_natives_syntax_;
+  v8::Extension* extension_;
+  bool is_pre_parsing_;
+  ScriptDataImpl* pre_data_;
+  FuncNameInferrer* fni_;
 };
 
 
@@ -472,6 +808,52 @@
 };
 
 
+// ----------------------------------------------------------------------------
+// JSON PARSING
+
+// JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
+// specification section 15.12.1 (and appendix A.8).
+// The grammar is given section 15.12.1.2 (and appendix A.8.2).
+class JsonParser BASE_EMBEDDED {
+ public:
+  // Parse JSON input as a single JSON value.
+  // Returns null handle and sets exception if parsing failed.
+  static Handle<Object> Parse(Handle<String> source) {
+    return JsonParser().ParseJson(source);
+  }
+
+ private:
+  JsonParser() { }
+  ~JsonParser() { }
+
+  // Parse a string containing a single JSON value.
+  Handle<Object> ParseJson(Handle<String>);
+  // Parse a single JSON value from input (grammar production JSONValue).
+  // A JSON value is either a (double-quoted) string literal, a number literal,
+  // one of "true", "false", or "null", or an object or array literal.
+  Handle<Object> ParseJsonValue();
+  // Parse a JSON object literal (grammar production JSONObject).
+  // An object literal is a squiggly-braced and comma separated sequence
+  // (possibly empty) of key/value pairs, where the key is a JSON string
+  // literal, the value is a JSON value, and the two are separated by a colon.
+  // A JSON array dosn't allow numbers and identifiers as keys, like a
+  // JavaScript array.
+  Handle<Object> ParseJsonObject();
+  // Parses a JSON array literal (grammar production JSONArray). An array
+  // literal is a square-bracketed and comma separated sequence (possibly empty)
+  // of JSON values.
+  // A JSON array doesn't allow leaving out values from the sequence, nor does
+  // it allow a terminal comma, like a JavaScript array does.
+  Handle<Object> ParseJsonArray();
+
+  // Mark that a parsing error has happened at the current token, and
+  // return a null handle. Primarily for readability.
+  Handle<Object> ReportUnexpectedToken() { return Handle<Object>::null(); }
+  // Converts the currently parsed literal to a JavaScript String.
+  Handle<String> GetString();
+
+  Scanner scanner_;
+};
 } }  // namespace v8::internal
 
 #endif  // V8_PARSER_H_
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index eefaec9..89003ba 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -99,30 +99,12 @@
 
 
 #ifdef __arm__
-bool OS::ArmCpuHasFeature(CpuFeature feature) {
-  const char* search_string = NULL;
+static bool CPUInfoContainsString(const char * search_string) {
   const char* file_name = "/proc/cpuinfo";
-  // Simple detection of VFP at runtime for Linux.
-  // It is based on /proc/cpuinfo, which reveals hardware configuration
-  // to user-space applications.  According to ARM (mid 2009), no similar
-  // facility is universally available on the ARM architectures,
-  // so it's up to individual OSes to provide such.
-  //
   // This is written as a straight shot one pass parser
   // and not using STL string and ifstream because,
   // on Linux, it's reading from a (non-mmap-able)
   // character special device.
-  switch (feature) {
-    case VFP3:
-      search_string = "vfp";
-      break;
-    case ARMv7:
-      search_string = "ARMv7";
-      break;
-    default:
-      UNREACHABLE();
-  }
-
   FILE* f = NULL;
   const char* what = search_string;
 
@@ -149,6 +131,43 @@
   // Did not find string in the proc file.
   return false;
 }
+
+bool OS::ArmCpuHasFeature(CpuFeature feature) {
+  const int max_items = 2;
+  const char* search_strings[max_items] = { NULL, NULL };
+  int search_items = 0;
+  // Simple detection of VFP at runtime for Linux.
+  // It is based on /proc/cpuinfo, which reveals hardware configuration
+  // to user-space applications.  According to ARM (mid 2009), no similar
+  // facility is universally available on the ARM architectures,
+  // so it's up to individual OSes to provide such.
+  switch (feature) {
+    case VFP3:
+      search_strings[0] = "vfpv3";
+      // Some old kernels will report vfp for A8, not vfpv3, so we check for
+      // A8 explicitely. The cpuinfo file report the CPU Part which for Cortex
+      // A8 is 0xc08.
+      search_strings[1] = "0xc08";
+      search_items = 2;
+      ASSERT(search_items <= max_items);
+      break;
+    case ARMv7:
+      search_strings[0] = "ARMv7" ;
+      search_items = 1;
+      ASSERT(search_items <= max_items);
+      break;
+    default:
+      UNREACHABLE();
+  }
+
+  for (int i = 0; i < search_items; ++i) {
+    if (CPUInfoContainsString(search_strings[i])) {
+      return true;
+    }
+  }
+
+  return false;
+}
 #endif  // def __arm__
 
 
@@ -809,8 +828,17 @@
       syscall(SYS_tgkill, vm_tgid_, vm_tid_, SIGPROF);
       // Convert ms to us and subtract 100 us to compensate delays
       // occuring during signal delivery.
-      int result = usleep(sampler_->interval_ * 1000 - 100);
-      ASSERT(result == 0 || errno == EINTR);
+      const useconds_t interval = sampler_->interval_ * 1000 - 100;
+      int result = usleep(interval);
+#ifdef DEBUG
+      if (result != 0 && errno != EINTR) {
+        fprintf(stderr,
+                "SignalSender usleep error; interval = %u, errno = %d\n",
+                interval,
+                errno);
+        ASSERT(result == 0 || errno == EINTR);
+      }
+#endif
       USE(result);
     }
   }
@@ -843,6 +871,7 @@
 
 
 Sampler::~Sampler() {
+  ASSERT(!data_->signal_sender_launched_);
   delete data_;
 }
 
@@ -856,7 +885,7 @@
   struct sigaction sa;
   sa.sa_sigaction = ProfilerSignalHandler;
   sigemptyset(&sa.sa_mask);
-  sa.sa_flags = SA_SIGINFO;
+  sa.sa_flags = SA_RESTART | SA_SIGINFO;
   if (sigaction(SIGPROF, &sa, &data_->old_signal_handler_) != 0) return;
   data_->signal_handler_installed_ = true;
 
diff --git a/src/preparser.h b/src/preparser.h
new file mode 100644
index 0000000..44c55cf
--- /dev/null
+++ b/src/preparser.h
@@ -0,0 +1,1414 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_PREPARSER_H
+#define V8_PREPARSER_H
+
+#include "unicode.h"
+
+namespace v8 {
+namespace preparser {
+
+// Preparsing checks a JavaScript program and emits preparse-data that helps
+// a later parsing to be faster.
+// See preparser-data.h for the data.
+
+// The PreParser checks that the syntax follows the grammar for JavaScript,
+// and collects some information about the program along the way.
+// The grammar check is only performed in order to understand the program
+// sufficiently to deduce some information about it, that can be used
+// to speed up later parsing. Finding errors is not the goal of pre-parsing,
+// rather it is to speed up properly written and correct programs.
+// That means that contextual checks (like a label being declared where
+// it is used) are generally omitted.
+
+namespace i = v8::internal;
+
+enum StatementType {
+  kUnknownStatement
+};
+
+enum ExpressionType {
+  kUnknownExpression,
+  kIdentifierExpression,  // Used to detect labels.
+  kThisExpression,
+  kThisPropertyExpression
+};
+
+enum IdentifierType {
+  kUnknownIdentifier
+};
+
+enum SourceElementTypes {
+  kUnknownSourceElements
+};
+
+
+typedef int SourceElements;
+typedef int Expression;
+typedef int Statement;
+typedef int Identifier;
+typedef int Arguments;
+
+
+template <typename Scanner, typename PreParserLog>
+class PreParser {
+ public:
+  PreParser() : scope_(NULL), allow_lazy_(true) { }
+  ~PreParser() { }
+
+  // Pre-parse the program from the character stream; returns true on
+  // success (even if parsing failed, the pre-parse data successfully
+  // captured the syntax error), and false if a stack-overflow happened
+  // during parsing.
+  bool PreParseProgram(Scanner* scanner,
+                       PreParserLog* log,
+                       bool allow_lazy) {
+    allow_lazy_ = allow_lazy;
+    scanner_ = scanner;
+    log_ = log;
+    Scope top_scope(&scope_, kTopLevelScope);
+    bool ok = true;
+    ParseSourceElements(i::Token::EOS, &ok);
+    bool stack_overflow = scanner_->stack_overflow();
+    if (!ok && !stack_overflow) {
+      ReportUnexpectedToken(scanner_->current_token());
+    }
+    return !stack_overflow;
+  }
+
+ private:
+  enum ScopeType {
+    kTopLevelScope,
+    kFunctionScope
+  };
+
+  class Scope {
+   public:
+    Scope(Scope** variable, ScopeType type)
+        : variable_(variable),
+          prev_(*variable),
+          type_(type),
+          materialized_literal_count_(0),
+          expected_properties_(0),
+          with_nesting_count_(0) {
+      *variable = this;
+    }
+    ~Scope() { *variable_ = prev_; }
+    void NextMaterializedLiteralIndex() { materialized_literal_count_++; }
+    void AddProperty() { expected_properties_++; }
+    ScopeType type() { return type_; }
+    int expected_properties() { return expected_properties_; }
+    int materialized_literal_count() { return materialized_literal_count_; }
+    bool IsInsideWith() { return with_nesting_count_ != 0; }
+    void EnterWith() { with_nesting_count_++; }
+    void LeaveWith() { with_nesting_count_--; }
+
+   private:
+    Scope** const variable_;
+    Scope* const prev_;
+    const ScopeType type_;
+    int materialized_literal_count_;
+    int expected_properties_;
+    int with_nesting_count_;
+  };
+
+  // Types that allow us to recognize simple this-property assignments.
+  // A simple this-property assignment is a statement on the form
+  // "this.propertyName = {primitive constant or function parameter name);"
+  // where propertyName isn't "__proto__".
+  // The result is only relevant if the function body contains only
+  // simple this-property assignments.
+
+  // Report syntax error
+  void ReportUnexpectedToken(i::Token::Value token);
+  void ReportMessageAt(int start_pos,
+                       int end_pos,
+                       const char* type,
+                       const char* name_opt) {
+    log_->LogMessage(start_pos, end_pos, type, name_opt);
+  }
+
+  // All ParseXXX functions take as the last argument an *ok parameter
+  // which is set to false if parsing failed; it is unchanged otherwise.
+  // By making the 'exception handling' explicit, we are forced to check
+  // for failure at the call sites.
+  SourceElements ParseSourceElements(int end_token, bool* ok);
+  Statement ParseStatement(bool* ok);
+  Statement ParseFunctionDeclaration(bool* ok);
+  Statement ParseNativeDeclaration(bool* ok);
+  Statement ParseBlock(bool* ok);
+  Statement ParseVariableStatement(bool* ok);
+  Statement ParseVariableDeclarations(bool accept_IN, int* num_decl, bool* ok);
+  Statement ParseExpressionOrLabelledStatement(bool* ok);
+  Statement ParseIfStatement(bool* ok);
+  Statement ParseContinueStatement(bool* ok);
+  Statement ParseBreakStatement(bool* ok);
+  Statement ParseReturnStatement(bool* ok);
+  Statement ParseWithStatement(bool* ok);
+  Statement ParseSwitchStatement(bool* ok);
+  Statement ParseDoWhileStatement(bool* ok);
+  Statement ParseWhileStatement(bool* ok);
+  Statement ParseForStatement(bool* ok);
+  Statement ParseThrowStatement(bool* ok);
+  Statement ParseTryStatement(bool* ok);
+  Statement ParseDebuggerStatement(bool* ok);
+
+  Expression ParseExpression(bool accept_IN, bool* ok);
+  Expression ParseAssignmentExpression(bool accept_IN, bool* ok);
+  Expression ParseConditionalExpression(bool accept_IN, bool* ok);
+  Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
+  Expression ParseUnaryExpression(bool* ok);
+  Expression ParsePostfixExpression(bool* ok);
+  Expression ParseLeftHandSideExpression(bool* ok);
+  Expression ParseNewExpression(bool* ok);
+  Expression ParseMemberExpression(bool* ok);
+  Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok);
+  Expression ParsePrimaryExpression(bool* ok);
+  Expression ParseArrayLiteral(bool* ok);
+  Expression ParseObjectLiteral(bool* ok);
+  Expression ParseRegExpLiteral(bool seen_equal, bool* ok);
+  Expression ParseV8Intrinsic(bool* ok);
+
+  Arguments ParseArguments(bool* ok);
+  Expression ParseFunctionLiteral(bool* ok);
+
+  Identifier ParseIdentifier(bool* ok);
+  Identifier ParseIdentifierName(bool* ok);
+  Identifier ParseIdentifierOrGetOrSet(bool* is_get, bool* is_set, bool* ok);
+
+  Identifier GetIdentifierSymbol();
+  unsigned int HexDigitValue(char digit);
+  Expression GetStringSymbol();
+
+
+  i::Token::Value peek() { return scanner_->peek(); }
+  i::Token::Value Next() {
+    i::Token::Value next = scanner_->Next();
+    return next;
+  }
+
+  void Consume(i::Token::Value token) {
+    Next();
+  }
+
+  void Expect(i::Token::Value token, bool* ok) {
+    if (Next() != token) {
+      *ok = false;
+    }
+  }
+
+  bool Check(i::Token::Value token) {
+    i::Token::Value next = peek();
+    if (next == token) {
+      Consume(next);
+      return true;
+    }
+    return false;
+  }
+  void ExpectSemicolon(bool* ok);
+
+  static int Precedence(i::Token::Value tok, bool accept_IN);
+
+  Scanner* scanner_;
+  PreParserLog* log_;
+  Scope* scope_;
+  bool allow_lazy_;
+};
+
+
+#define CHECK_OK  ok);  \
+  if (!*ok) return -1;  \
+  ((void)0
+#define DUMMY )  // to make indentation work
+#undef DUMMY
+
+
+template <typename Scanner, typename Log>
+void PreParser<Scanner, Log>::ReportUnexpectedToken(i::Token::Value token) {
+  // We don't report stack overflows here, to avoid increasing the
+  // stack depth even further.  Instead we report it after parsing is
+  // over, in ParseProgram.
+  if (token == i::Token::ILLEGAL && scanner_->stack_overflow()) {
+    return;
+  }
+  typename Scanner::Location source_location = scanner_->location();
+
+  // Four of the tokens are treated specially
+  switch (token) {
+  case i::Token::EOS:
+    return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
+                           "unexpected_eos", NULL);
+  case i::Token::NUMBER:
+    return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
+                           "unexpected_token_number", NULL);
+  case i::Token::STRING:
+    return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
+                           "unexpected_token_string", NULL);
+  case i::Token::IDENTIFIER:
+    return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
+                           "unexpected_token_identifier", NULL);
+  default:
+    const char* name = i::Token::String(token);
+    ReportMessageAt(source_location.beg_pos, source_location.end_pos,
+                    "unexpected_token", name);
+  }
+}
+
+
+template <typename Scanner, typename Log>
+SourceElements PreParser<Scanner, Log>::ParseSourceElements(int end_token,
+                                                            bool* ok) {
+  // SourceElements ::
+  //   (Statement)* <end_token>
+
+  while (peek() != end_token) {
+    ParseStatement(CHECK_OK);
+  }
+  return kUnknownSourceElements;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseStatement(bool* ok) {
+  // Statement ::
+  //   Block
+  //   VariableStatement
+  //   EmptyStatement
+  //   ExpressionStatement
+  //   IfStatement
+  //   IterationStatement
+  //   ContinueStatement
+  //   BreakStatement
+  //   ReturnStatement
+  //   WithStatement
+  //   LabelledStatement
+  //   SwitchStatement
+  //   ThrowStatement
+  //   TryStatement
+  //   DebuggerStatement
+
+  // Note: Since labels can only be used by 'break' and 'continue'
+  // statements, which themselves are only valid within blocks,
+  // iterations or 'switch' statements (i.e., BreakableStatements),
+  // labels can be simply ignored in all other cases; except for
+  // trivial labeled break statements 'label: break label' which is
+  // parsed into an empty statement.
+
+  // Keep the source position of the statement
+  switch (peek()) {
+    case i::Token::LBRACE:
+      return ParseBlock(ok);
+
+    case i::Token::CONST:
+    case i::Token::VAR:
+      return ParseVariableStatement(ok);
+
+    case i::Token::SEMICOLON:
+      Next();
+      return kUnknownStatement;
+
+    case i::Token::IF:
+      return  ParseIfStatement(ok);
+
+    case i::Token::DO:
+      return ParseDoWhileStatement(ok);
+
+    case i::Token::WHILE:
+      return ParseWhileStatement(ok);
+
+    case i::Token::FOR:
+      return ParseForStatement(ok);
+
+    case i::Token::CONTINUE:
+      return ParseContinueStatement(ok);
+
+    case i::Token::BREAK:
+      return ParseBreakStatement(ok);
+
+    case i::Token::RETURN:
+      return ParseReturnStatement(ok);
+
+    case i::Token::WITH:
+      return ParseWithStatement(ok);
+
+    case i::Token::SWITCH:
+      return ParseSwitchStatement(ok);
+
+    case i::Token::THROW:
+      return ParseThrowStatement(ok);
+
+    case i::Token::TRY:
+      return ParseTryStatement(ok);
+
+    case i::Token::FUNCTION:
+      return ParseFunctionDeclaration(ok);
+
+    case i::Token::NATIVE:
+      return ParseNativeDeclaration(ok);
+
+    case i::Token::DEBUGGER:
+      return ParseDebuggerStatement(ok);
+
+    default:
+      return ParseExpressionOrLabelledStatement(ok);
+  }
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseFunctionDeclaration(bool* ok) {
+  // FunctionDeclaration ::
+  //   'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
+  Expect(i::Token::FUNCTION, CHECK_OK);
+  ParseIdentifier(CHECK_OK);
+  ParseFunctionLiteral(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+// Language extension which is only enabled for source files loaded
+// through the API's extension mechanism.  A native function
+// declaration is resolved by looking up the function through a
+// callback provided by the extension.
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseNativeDeclaration(bool* ok) {
+  Expect(i::Token::NATIVE, CHECK_OK);
+  Expect(i::Token::FUNCTION, CHECK_OK);
+  ParseIdentifier(CHECK_OK);
+  Expect(i::Token::LPAREN, CHECK_OK);
+  bool done = (peek() == i::Token::RPAREN);
+  while (!done) {
+    ParseIdentifier(CHECK_OK);
+    done = (peek() == i::Token::RPAREN);
+    if (!done) {
+      Expect(i::Token::COMMA, CHECK_OK);
+    }
+  }
+  Expect(i::Token::RPAREN, CHECK_OK);
+  Expect(i::Token::SEMICOLON, CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseBlock(bool* ok) {
+  // Block ::
+  //   '{' Statement* '}'
+
+  // Note that a Block does not introduce a new execution scope!
+  // (ECMA-262, 3rd, 12.2)
+  //
+  Expect(i::Token::LBRACE, CHECK_OK);
+  while (peek() != i::Token::RBRACE) {
+    ParseStatement(CHECK_OK);
+  }
+  Expect(i::Token::RBRACE, CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseVariableStatement(bool* ok) {
+  // VariableStatement ::
+  //   VariableDeclarations ';'
+
+  Statement result = ParseVariableDeclarations(true, NULL, CHECK_OK);
+  ExpectSemicolon(CHECK_OK);
+  return result;
+}
+
+
+// If the variable declaration declares exactly one non-const
+// variable, then *var is set to that variable. In all other cases,
+// *var is untouched; in particular, it is the caller's responsibility
+// to initialize it properly. This mechanism is also used for the parsing
+// of 'for-in' loops.
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseVariableDeclarations(bool accept_IN,
+                                                  int* num_decl,
+                                                  bool* ok) {
+  // VariableDeclarations ::
+  //   ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
+
+  if (peek() == i::Token::VAR) {
+    Consume(i::Token::VAR);
+  } else if (peek() == i::Token::CONST) {
+    Consume(i::Token::CONST);
+  } else {
+    *ok = false;
+    return 0;
+  }
+
+  // The scope of a variable/const declared anywhere inside a function
+  // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). .
+  int nvars = 0;  // the number of variables declared
+  do {
+    // Parse variable name.
+    if (nvars > 0) Consume(i::Token::COMMA);
+    ParseIdentifier(CHECK_OK);
+    nvars++;
+    if (peek() == i::Token::ASSIGN) {
+      Expect(i::Token::ASSIGN, CHECK_OK);
+      ParseAssignmentExpression(accept_IN, CHECK_OK);
+    }
+  } while (peek() == i::Token::COMMA);
+
+  if (num_decl != NULL) *num_decl = nvars;
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseExpressionOrLabelledStatement(
+    bool* ok) {
+  // ExpressionStatement | LabelledStatement ::
+  //   Expression ';'
+  //   Identifier ':' Statement
+
+  Expression expr = ParseExpression(true, CHECK_OK);
+  if (peek() == i::Token::COLON && expr == kIdentifierExpression) {
+    Consume(i::Token::COLON);
+    return ParseStatement(ok);
+  }
+  // Parsed expression statement.
+  ExpectSemicolon(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseIfStatement(bool* ok) {
+  // IfStatement ::
+  //   'if' '(' Expression ')' Statement ('else' Statement)?
+
+  Expect(i::Token::IF, CHECK_OK);
+  Expect(i::Token::LPAREN, CHECK_OK);
+  ParseExpression(true, CHECK_OK);
+  Expect(i::Token::RPAREN, CHECK_OK);
+  ParseStatement(CHECK_OK);
+  if (peek() == i::Token::ELSE) {
+    Next();
+    ParseStatement(CHECK_OK);
+  }
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseContinueStatement(bool* ok) {
+  // ContinueStatement ::
+  //   'continue' [no line terminator] Identifier? ';'
+
+  Expect(i::Token::CONTINUE, CHECK_OK);
+  i::Token::Value tok = peek();
+  if (!scanner_->has_line_terminator_before_next() &&
+      tok != i::Token::SEMICOLON &&
+      tok != i::Token::RBRACE &&
+      tok != i::Token::EOS) {
+    ParseIdentifier(CHECK_OK);
+  }
+  ExpectSemicolon(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseBreakStatement(bool* ok) {
+  // BreakStatement ::
+  //   'break' [no line terminator] Identifier? ';'
+
+  Expect(i::Token::BREAK, CHECK_OK);
+  i::Token::Value tok = peek();
+  if (!scanner_->has_line_terminator_before_next() &&
+      tok != i::Token::SEMICOLON &&
+      tok != i::Token::RBRACE &&
+      tok != i::Token::EOS) {
+    ParseIdentifier(CHECK_OK);
+  }
+  ExpectSemicolon(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseReturnStatement(bool* ok) {
+  // ReturnStatement ::
+  //   'return' [no line terminator] Expression? ';'
+
+  // Consume the return token. It is necessary to do the before
+  // reporting any errors on it, because of the way errors are
+  // reported (underlining).
+  Expect(i::Token::RETURN, CHECK_OK);
+
+  // An ECMAScript program is considered syntactically incorrect if it
+  // contains a return statement that is not within the body of a
+  // function. See ECMA-262, section 12.9, page 67.
+  // This is not handled during preparsing.
+
+  i::Token::Value tok = peek();
+  if (!scanner_->has_line_terminator_before_next() &&
+      tok != i::Token::SEMICOLON &&
+      tok != i::Token::RBRACE &&
+      tok != i::Token::EOS) {
+    ParseExpression(true, CHECK_OK);
+  }
+  ExpectSemicolon(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseWithStatement(bool* ok) {
+  // WithStatement ::
+  //   'with' '(' Expression ')' Statement
+  Expect(i::Token::WITH, CHECK_OK);
+  Expect(i::Token::LPAREN, CHECK_OK);
+  ParseExpression(true, CHECK_OK);
+  Expect(i::Token::RPAREN, CHECK_OK);
+
+  scope_->EnterWith();
+  ParseStatement(CHECK_OK);
+  scope_->LeaveWith();
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseSwitchStatement(bool* ok) {
+  // SwitchStatement ::
+  //   'switch' '(' Expression ')' '{' CaseClause* '}'
+
+  Expect(i::Token::SWITCH, CHECK_OK);
+  Expect(i::Token::LPAREN, CHECK_OK);
+  ParseExpression(true, CHECK_OK);
+  Expect(i::Token::RPAREN, CHECK_OK);
+
+  Expect(i::Token::LBRACE, CHECK_OK);
+  i::Token::Value token = peek();
+  while (token != i::Token::RBRACE) {
+    if (token == i::Token::CASE) {
+      Expect(i::Token::CASE, CHECK_OK);
+      ParseExpression(true, CHECK_OK);
+      Expect(i::Token::COLON, CHECK_OK);
+    } else if (token == i::Token::DEFAULT) {
+      Expect(i::Token::DEFAULT, CHECK_OK);
+      Expect(i::Token::COLON, CHECK_OK);
+    } else {
+      ParseStatement(CHECK_OK);
+    }
+    token = peek();
+  }
+  Expect(i::Token::RBRACE, CHECK_OK);
+
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseDoWhileStatement(bool* ok) {
+  // DoStatement ::
+  //   'do' Statement 'while' '(' Expression ')' ';'
+
+  Expect(i::Token::DO, CHECK_OK);
+  ParseStatement(CHECK_OK);
+  Expect(i::Token::WHILE, CHECK_OK);
+  Expect(i::Token::LPAREN, CHECK_OK);
+  ParseExpression(true, CHECK_OK);
+  Expect(i::Token::RPAREN, CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseWhileStatement(bool* ok) {
+  // WhileStatement ::
+  //   'while' '(' Expression ')' Statement
+
+  Expect(i::Token::WHILE, CHECK_OK);
+  Expect(i::Token::LPAREN, CHECK_OK);
+  ParseExpression(true, CHECK_OK);
+  Expect(i::Token::RPAREN, CHECK_OK);
+  ParseStatement(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseForStatement(bool* ok) {
+  // ForStatement ::
+  //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
+
+  Expect(i::Token::FOR, CHECK_OK);
+  Expect(i::Token::LPAREN, CHECK_OK);
+  if (peek() != i::Token::SEMICOLON) {
+    if (peek() == i::Token::VAR || peek() == i::Token::CONST) {
+      int decl_count;
+      ParseVariableDeclarations(false, &decl_count, CHECK_OK);
+      if (peek() == i::Token::IN && decl_count == 1) {
+        Expect(i::Token::IN, CHECK_OK);
+        ParseExpression(true, CHECK_OK);
+        Expect(i::Token::RPAREN, CHECK_OK);
+
+        ParseStatement(CHECK_OK);
+        return kUnknownStatement;
+      }
+    } else {
+      ParseExpression(false, CHECK_OK);
+      if (peek() == i::Token::IN) {
+        Expect(i::Token::IN, CHECK_OK);
+        ParseExpression(true, CHECK_OK);
+        Expect(i::Token::RPAREN, CHECK_OK);
+
+        ParseStatement(CHECK_OK);
+        return kUnknownStatement;
+      }
+    }
+  }
+
+  // Parsed initializer at this point.
+  Expect(i::Token::SEMICOLON, CHECK_OK);
+
+  if (peek() != i::Token::SEMICOLON) {
+    ParseExpression(true, CHECK_OK);
+  }
+  Expect(i::Token::SEMICOLON, CHECK_OK);
+
+  if (peek() != i::Token::RPAREN) {
+    ParseExpression(true, CHECK_OK);
+  }
+  Expect(i::Token::RPAREN, CHECK_OK);
+
+  ParseStatement(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseThrowStatement(bool* ok) {
+  // ThrowStatement ::
+  //   'throw' [no line terminator] Expression ';'
+
+  Expect(i::Token::THROW, CHECK_OK);
+  if (scanner_->has_line_terminator_before_next()) {
+    typename Scanner::Location pos = scanner_->location();
+    ReportMessageAt(pos.beg_pos, pos.end_pos,
+                    "newline_after_throw", NULL);
+    *ok = false;
+    return NULL;
+  }
+  ParseExpression(true, CHECK_OK);
+  ExpectSemicolon(CHECK_OK);
+
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseTryStatement(bool* ok) {
+  // TryStatement ::
+  //   'try' Block Catch
+  //   'try' Block Finally
+  //   'try' Block Catch Finally
+  //
+  // Catch ::
+  //   'catch' '(' Identifier ')' Block
+  //
+  // Finally ::
+  //   'finally' Block
+
+  // In preparsing, allow any number of catch/finally blocks, including zero
+  // of both.
+
+  Expect(i::Token::TRY, CHECK_OK);
+
+  ParseBlock(CHECK_OK);
+
+  bool catch_or_finally_seen = false;
+  if (peek() == i::Token::CATCH) {
+    Expect(i::Token::CATCH, CHECK_OK);
+    Expect(i::Token::LPAREN, CHECK_OK);
+    ParseIdentifier(CHECK_OK);
+    Expect(i::Token::RPAREN, CHECK_OK);
+    ParseBlock(CHECK_OK);
+    catch_or_finally_seen = true;
+  }
+  if (peek() == i::Token::FINALLY) {
+    Expect(i::Token::FINALLY, CHECK_OK);
+    ParseBlock(CHECK_OK);
+    catch_or_finally_seen = true;
+  }
+  if (!catch_or_finally_seen) {
+    *ok = false;
+  }
+  return kUnknownStatement;
+}
+
+
+template <typename Scanner, typename Log>
+Statement PreParser<Scanner, Log>::ParseDebuggerStatement(bool* ok) {
+  // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser
+  // contexts this is used as a statement which invokes the debugger as if a
+  // break point is present.
+  // DebuggerStatement ::
+  //   'debugger' ';'
+
+  Expect(i::Token::DEBUGGER, CHECK_OK);
+  ExpectSemicolon(CHECK_OK);
+  return kUnknownStatement;
+}
+
+
+// Precedence = 1
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseExpression(bool accept_IN, bool* ok) {
+  // Expression ::
+  //   AssignmentExpression
+  //   Expression ',' AssignmentExpression
+
+  Expression result = ParseAssignmentExpression(accept_IN, CHECK_OK);
+  while (peek() == i::Token::COMMA) {
+    Expect(i::Token::COMMA, CHECK_OK);
+    ParseAssignmentExpression(accept_IN, CHECK_OK);
+    result = kUnknownExpression;
+  }
+  return result;
+}
+
+
+// Precedence = 2
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseAssignmentExpression(bool accept_IN,
+                                                              bool* ok) {
+  // AssignmentExpression ::
+  //   ConditionalExpression
+  //   LeftHandSideExpression AssignmentOperator AssignmentExpression
+
+  Expression expression = ParseConditionalExpression(accept_IN, CHECK_OK);
+
+  if (!i::Token::IsAssignmentOp(peek())) {
+    // Parsed conditional expression only (no assignment).
+    return expression;
+  }
+
+  i::Token::Value op = Next();  // Get assignment operator.
+  ParseAssignmentExpression(accept_IN, CHECK_OK);
+
+  if ((op == i::Token::ASSIGN) && (expression == kThisPropertyExpression)) {
+    scope_->AddProperty();
+  }
+
+  return kUnknownExpression;
+}
+
+
+// Precedence = 3
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseConditionalExpression(bool accept_IN,
+                                                               bool* ok) {
+  // ConditionalExpression ::
+  //   LogicalOrExpression
+  //   LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
+
+  // We start using the binary expression parser for prec >= 4 only!
+  Expression expression = ParseBinaryExpression(4, accept_IN, CHECK_OK);
+  if (peek() != i::Token::CONDITIONAL) return expression;
+  Consume(i::Token::CONDITIONAL);
+  // In parsing the first assignment expression in conditional
+  // expressions we always accept the 'in' keyword; see ECMA-262,
+  // section 11.12, page 58.
+  ParseAssignmentExpression(true, CHECK_OK);
+  Expect(i::Token::COLON, CHECK_OK);
+  ParseAssignmentExpression(accept_IN, CHECK_OK);
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+int PreParser<Scanner, Log>::Precedence(i::Token::Value tok, bool accept_IN) {
+  if (tok == i::Token::IN && !accept_IN)
+    return 0;  // 0 precedence will terminate binary expression parsing
+
+  return i::Token::Precedence(tok);
+}
+
+
+// Precedence >= 4
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseBinaryExpression(int prec,
+                                                          bool accept_IN,
+                                                          bool* ok) {
+  Expression result = ParseUnaryExpression(CHECK_OK);
+  for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
+    // prec1 >= 4
+    while (Precedence(peek(), accept_IN) == prec1) {
+      Next();
+      ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
+      result = kUnknownExpression;
+    }
+  }
+  return result;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseUnaryExpression(bool* ok) {
+  // UnaryExpression ::
+  //   PostfixExpression
+  //   'delete' UnaryExpression
+  //   'void' UnaryExpression
+  //   'typeof' UnaryExpression
+  //   '++' UnaryExpression
+  //   '--' UnaryExpression
+  //   '+' UnaryExpression
+  //   '-' UnaryExpression
+  //   '~' UnaryExpression
+  //   '!' UnaryExpression
+
+  i::Token::Value op = peek();
+  if (i::Token::IsUnaryOp(op) || i::Token::IsCountOp(op)) {
+    op = Next();
+    ParseUnaryExpression(ok);
+    return kUnknownExpression;
+  } else {
+    return ParsePostfixExpression(ok);
+  }
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParsePostfixExpression(bool* ok) {
+  // PostfixExpression ::
+  //   LeftHandSideExpression ('++' | '--')?
+
+  Expression expression = ParseLeftHandSideExpression(CHECK_OK);
+  if (!scanner_->has_line_terminator_before_next() &&
+      i::Token::IsCountOp(peek())) {
+    Next();
+    return kUnknownExpression;
+  }
+  return expression;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseLeftHandSideExpression(bool* ok) {
+  // LeftHandSideExpression ::
+  //   (NewExpression | MemberExpression) ...
+
+  Expression result;
+  if (peek() == i::Token::NEW) {
+    result = ParseNewExpression(CHECK_OK);
+  } else {
+    result = ParseMemberExpression(CHECK_OK);
+  }
+
+  while (true) {
+    switch (peek()) {
+      case i::Token::LBRACK: {
+        Consume(i::Token::LBRACK);
+        ParseExpression(true, CHECK_OK);
+        Expect(i::Token::RBRACK, CHECK_OK);
+        if (result == kThisExpression) {
+          result = kThisPropertyExpression;
+        } else {
+          result = kUnknownExpression;
+        }
+        break;
+      }
+
+      case i::Token::LPAREN: {
+        ParseArguments(CHECK_OK);
+        result = kUnknownExpression;
+        break;
+      }
+
+      case i::Token::PERIOD: {
+        Consume(i::Token::PERIOD);
+        ParseIdentifierName(CHECK_OK);
+        if (result == kThisExpression) {
+          result = kThisPropertyExpression;
+        } else {
+          result = kUnknownExpression;
+        }
+        break;
+      }
+
+      default:
+        return result;
+    }
+  }
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseNewExpression(bool* ok) {
+  // NewExpression ::
+  //   ('new')+ MemberExpression
+
+  // The grammar for new expressions is pretty warped. The keyword
+  // 'new' can either be a part of the new expression (where it isn't
+  // followed by an argument list) or a part of the member expression,
+  // where it must be followed by an argument list. To accommodate
+  // this, we parse the 'new' keywords greedily and keep track of how
+  // many we have parsed. This information is then passed on to the
+  // member expression parser, which is only allowed to match argument
+  // lists as long as it has 'new' prefixes left
+  unsigned new_count = 0;
+  do {
+    Consume(i::Token::NEW);
+    new_count++;
+  } while (peek() == i::Token::NEW);
+
+  return ParseMemberWithNewPrefixesExpression(new_count, ok);
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseMemberExpression(bool* ok) {
+  return ParseMemberWithNewPrefixesExpression(0, ok);
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseMemberWithNewPrefixesExpression(
+    unsigned new_count, bool* ok) {
+  // MemberExpression ::
+  //   (PrimaryExpression | FunctionLiteral)
+  //     ('[' Expression ']' | '.' Identifier | Arguments)*
+
+  // Parse the initial primary or function expression.
+  Expression result = NULL;
+  if (peek() == i::Token::FUNCTION) {
+    Consume(i::Token::FUNCTION);
+    if (peek() == i::Token::IDENTIFIER) {
+      ParseIdentifier(CHECK_OK);
+    }
+    result = ParseFunctionLiteral(CHECK_OK);
+  } else {
+    result = ParsePrimaryExpression(CHECK_OK);
+  }
+
+  while (true) {
+    switch (peek()) {
+      case i::Token::LBRACK: {
+        Consume(i::Token::LBRACK);
+        ParseExpression(true, CHECK_OK);
+        Expect(i::Token::RBRACK, CHECK_OK);
+        if (result == kThisExpression) {
+          result = kThisPropertyExpression;
+        } else {
+          result = kUnknownExpression;
+        }
+        break;
+      }
+      case i::Token::PERIOD: {
+        Consume(i::Token::PERIOD);
+        ParseIdentifierName(CHECK_OK);
+        if (result == kThisExpression) {
+          result = kThisPropertyExpression;
+        } else {
+          result = kUnknownExpression;
+        }
+        break;
+      }
+      case i::Token::LPAREN: {
+        if (new_count == 0) return result;
+        // Consume one of the new prefixes (already parsed).
+        ParseArguments(CHECK_OK);
+        new_count--;
+        result = kUnknownExpression;
+        break;
+      }
+      default:
+        return result;
+    }
+  }
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParsePrimaryExpression(bool* ok) {
+  // PrimaryExpression ::
+  //   'this'
+  //   'null'
+  //   'true'
+  //   'false'
+  //   Identifier
+  //   Number
+  //   String
+  //   ArrayLiteral
+  //   ObjectLiteral
+  //   RegExpLiteral
+  //   '(' Expression ')'
+
+  Expression result = kUnknownExpression;
+  switch (peek()) {
+    case i::Token::THIS: {
+      Next();
+      result = kThisExpression;
+      break;
+    }
+
+    case i::Token::IDENTIFIER: {
+      ParseIdentifier(CHECK_OK);
+      result = kIdentifierExpression;
+      break;
+    }
+
+    case i::Token::NULL_LITERAL:
+    case i::Token::TRUE_LITERAL:
+    case i::Token::FALSE_LITERAL:
+    case i::Token::NUMBER: {
+      Next();
+      break;
+    }
+    case i::Token::STRING: {
+      Next();
+      result = GetStringSymbol();
+      break;
+    }
+
+    case i::Token::ASSIGN_DIV:
+      result = ParseRegExpLiteral(true, CHECK_OK);
+      break;
+
+    case i::Token::DIV:
+      result = ParseRegExpLiteral(false, CHECK_OK);
+      break;
+
+    case i::Token::LBRACK:
+      result = ParseArrayLiteral(CHECK_OK);
+      break;
+
+    case i::Token::LBRACE:
+      result = ParseObjectLiteral(CHECK_OK);
+      break;
+
+    case i::Token::LPAREN:
+      Consume(i::Token::LPAREN);
+      result = ParseExpression(true, CHECK_OK);
+      Expect(i::Token::RPAREN, CHECK_OK);
+      if (result == kIdentifierExpression) result = kUnknownExpression;
+      break;
+
+    case i::Token::MOD:
+      result = ParseV8Intrinsic(CHECK_OK);
+      break;
+
+    default: {
+      Next();
+      *ok = false;
+      return kUnknownExpression;
+    }
+  }
+
+  return result;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseArrayLiteral(bool* ok) {
+  // ArrayLiteral ::
+  //   '[' Expression? (',' Expression?)* ']'
+  Expect(i::Token::LBRACK, CHECK_OK);
+  while (peek() != i::Token::RBRACK) {
+    if (peek() != i::Token::COMMA) {
+      ParseAssignmentExpression(true, CHECK_OK);
+    }
+    if (peek() != i::Token::RBRACK) {
+      Expect(i::Token::COMMA, CHECK_OK);
+    }
+  }
+  Expect(i::Token::RBRACK, CHECK_OK);
+
+  scope_->NextMaterializedLiteralIndex();
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseObjectLiteral(bool* ok) {
+  // ObjectLiteral ::
+  //   '{' (
+  //       ((IdentifierName | String | Number) ':' AssignmentExpression)
+  //     | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
+  //    )*[','] '}'
+
+  Expect(i::Token::LBRACE, CHECK_OK);
+  while (peek() != i::Token::RBRACE) {
+    i::Token::Value next = peek();
+    switch (next) {
+      case i::Token::IDENTIFIER: {
+        bool is_getter = false;
+        bool is_setter = false;
+        ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
+        if ((is_getter || is_setter) && peek() != i::Token::COLON) {
+            i::Token::Value name = Next();
+            if (name != i::Token::IDENTIFIER &&
+                name != i::Token::NUMBER &&
+                name != i::Token::STRING &&
+                !i::Token::IsKeyword(name)) {
+              *ok = false;
+              return kUnknownExpression;
+            }
+            ParseFunctionLiteral(CHECK_OK);
+            if (peek() != i::Token::RBRACE) {
+              Expect(i::Token::COMMA, CHECK_OK);
+            }
+            continue;  // restart the while
+        }
+        break;
+      }
+      case i::Token::STRING:
+        Consume(next);
+        GetStringSymbol();
+        break;
+      case i::Token::NUMBER:
+        Consume(next);
+        break;
+      default:
+        if (i::Token::IsKeyword(next)) {
+          Consume(next);
+        } else {
+          // Unexpected token.
+          *ok = false;
+          return kUnknownExpression;
+        }
+    }
+
+    Expect(i::Token::COLON, CHECK_OK);
+    ParseAssignmentExpression(true, CHECK_OK);
+
+    // TODO(1240767): Consider allowing trailing comma.
+    if (peek() != i::Token::RBRACE) Expect(i::Token::COMMA, CHECK_OK);
+  }
+  Expect(i::Token::RBRACE, CHECK_OK);
+
+  scope_->NextMaterializedLiteralIndex();
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseRegExpLiteral(bool seen_equal,
+                                                       bool* ok) {
+  if (!scanner_->ScanRegExpPattern(seen_equal)) {
+    Next();
+    typename Scanner::Location location = scanner_->location();
+    ReportMessageAt(location.beg_pos, location.end_pos,
+                    "unterminated_regexp", NULL);
+    *ok = false;
+    return kUnknownExpression;
+  }
+
+  scope_->NextMaterializedLiteralIndex();
+
+  if (!scanner_->ScanRegExpFlags()) {
+    Next();
+    typename Scanner::Location location = scanner_->location();
+    ReportMessageAt(location.beg_pos, location.end_pos,
+                    "invalid_regexp_flags", NULL);
+    *ok = false;
+    return kUnknownExpression;
+  }
+  Next();
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+Arguments PreParser<Scanner, Log>::ParseArguments(bool* ok) {
+  // Arguments ::
+  //   '(' (AssignmentExpression)*[','] ')'
+
+  Expect(i::Token::LPAREN, CHECK_OK);
+  bool done = (peek() == i::Token::RPAREN);
+  int argc = 0;
+  while (!done) {
+    ParseAssignmentExpression(true, CHECK_OK);
+    argc++;
+    done = (peek() == i::Token::RPAREN);
+    if (!done) Expect(i::Token::COMMA, CHECK_OK);
+  }
+  Expect(i::Token::RPAREN, CHECK_OK);
+  return argc;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseFunctionLiteral(bool* ok) {
+  // Function ::
+  //   '(' FormalParameterList? ')' '{' FunctionBody '}'
+
+  // Parse function body.
+  ScopeType outer_scope_type = scope_->type();
+  bool inside_with = scope_->IsInsideWith();
+  Scope function_scope(&scope_, kFunctionScope);
+
+  //  FormalParameterList ::
+  //    '(' (Identifier)*[','] ')'
+  Expect(i::Token::LPAREN, CHECK_OK);
+  bool done = (peek() == i::Token::RPAREN);
+  while (!done) {
+    ParseIdentifier(CHECK_OK);
+    done = (peek() == i::Token::RPAREN);
+    if (!done) {
+      Expect(i::Token::COMMA, CHECK_OK);
+    }
+  }
+  Expect(i::Token::RPAREN, CHECK_OK);
+
+  Expect(i::Token::LBRACE, CHECK_OK);
+  int function_block_pos = scanner_->location().beg_pos;
+
+  // Determine if the function will be lazily compiled.
+  // Currently only happens to top-level functions.
+  // Optimistically assume that all top-level functions are lazily compiled.
+  bool is_lazily_compiled =
+      (outer_scope_type == kTopLevelScope && !inside_with && allow_lazy_);
+
+  if (is_lazily_compiled) {
+    log_->PauseRecording();
+    ParseSourceElements(i::Token::RBRACE, ok);
+    log_->ResumeRecording();
+    if (!*ok) return kUnknownExpression;
+
+    Expect(i::Token::RBRACE, CHECK_OK);
+
+    int end_pos = scanner_->location().end_pos;
+    log_->LogFunction(function_block_pos, end_pos,
+                      function_scope.materialized_literal_count(),
+                      function_scope.expected_properties());
+  } else {
+    ParseSourceElements(i::Token::RBRACE, CHECK_OK);
+    Expect(i::Token::RBRACE, CHECK_OK);
+  }
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::ParseV8Intrinsic(bool* ok) {
+  // CallRuntime ::
+  //   '%' Identifier Arguments
+
+  Expect(i::Token::MOD, CHECK_OK);
+  ParseIdentifier(CHECK_OK);
+  ParseArguments(CHECK_OK);
+
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+void PreParser<Scanner, Log>::ExpectSemicolon(bool* ok) {
+  // Check for automatic semicolon insertion according to
+  // the rules given in ECMA-262, section 7.9, page 21.
+  i::Token::Value tok = peek();
+  if (tok == i::Token::SEMICOLON) {
+    Next();
+    return;
+  }
+  if (scanner_->has_line_terminator_before_next() ||
+      tok == i::Token::RBRACE ||
+      tok == i::Token::EOS) {
+    return;
+  }
+  Expect(i::Token::SEMICOLON, ok);
+}
+
+
+template <typename Scanner, typename Log>
+Identifier PreParser<Scanner, Log>::GetIdentifierSymbol() {
+  const char* literal_chars = scanner_->literal_string();
+  int literal_length = scanner_->literal_length();
+  int identifier_pos = scanner_->location().beg_pos;
+
+  log_->LogSymbol(identifier_pos, literal_chars, literal_length);
+
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+Expression PreParser<Scanner, Log>::GetStringSymbol() {
+  const char* literal_chars = scanner_->literal_string();
+  int literal_length = scanner_->literal_length();
+
+  int literal_position = scanner_->location().beg_pos;
+  log_->LogSymbol(literal_position, literal_chars, literal_length);
+
+  return kUnknownExpression;
+}
+
+
+template <typename Scanner, typename Log>
+Identifier PreParser<Scanner, Log>::ParseIdentifier(bool* ok) {
+  Expect(i::Token::IDENTIFIER, ok);
+  return GetIdentifierSymbol();
+}
+
+
+template <typename Scanner, typename Log>
+Identifier PreParser<Scanner, Log>::ParseIdentifierName(bool* ok) {
+  i::Token::Value next = Next();
+  if (i::Token::IsKeyword(next)) {
+    int pos = scanner_->location().beg_pos;
+    const char* keyword = i::Token::String(next);
+    log_->LogSymbol(pos, keyword, strlen(keyword));
+    return kUnknownExpression;
+  }
+  if (next == i::Token::IDENTIFIER) {
+    return GetIdentifierSymbol();
+  }
+  *ok = false;
+  return kUnknownIdentifier;
+}
+
+
+// This function reads an identifier and determines whether or not it
+// is 'get' or 'set'.  The reason for not using ParseIdentifier and
+// checking on the output is that this involves heap allocation which
+// we can't do during preparsing.
+template <typename Scanner, typename Log>
+Identifier PreParser<Scanner, Log>::ParseIdentifierOrGetOrSet(bool* is_get,
+                                                   bool* is_set,
+                                                   bool* ok) {
+  Expect(i::Token::IDENTIFIER, CHECK_OK);
+  if (scanner_->literal_length() == 3) {
+    const char* token = scanner_->literal_string();
+    *is_get = strncmp(token, "get", 3) == 0;
+    *is_set = !*is_get && strncmp(token, "set", 3) == 0;
+  }
+  return GetIdentifierSymbol();
+}
+
+#undef CHECK_OK
+} }  // v8::preparser
+
+#endif  // V8_PREPARSER_H
diff --git a/src/regexp.js b/src/regexp.js
index 51f4b09..9e708fd 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -71,9 +71,6 @@
     }
   }
 
-  if (!isConstructorCall) {
-    regExpCache.type = 'none';
-  }
   %RegExpInitializeObject(object, pattern, global, ignoreCase, multiline);
 
   // Call internal function to compile the pattern.
@@ -121,22 +118,6 @@
 }
 
 
-function RegExpCache() {
-  this.type = 'none';
-  this.regExp = 0;
-  this.subject = 0;
-  this.replaceString = 0;
-  this.answer = 0;
-  // answerSaved marks whether the contents of answer is valid for a cache
-  // hit in RegExpExec, StringMatch and StringSplit.
-  this.answerSaved = false;
-  this.splitLimit = 0;  // Used only when type is "split".
-}
-
-
-var regExpCache = new RegExpCache();
-
-
 function BuildResultFromMatchInfo(lastMatchInfo, s) {
   var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
   var result = %_RegExpConstructResult(numResults, lastMatchInfo[CAPTURE0], s);
@@ -178,32 +159,6 @@
                         ['RegExp.prototype.exec', this]);
   }
 
-  var cache = regExpCache;
-  var saveAnswer = false;
-
-  var lastIndex = this.lastIndex;
-
-  // Since cache.subject is always a string, a matching input can not
-  // cause visible side-effects when converted to a string, so we can omit
-  // the conversion required by the specification.
-  // Likewise, the regexp.lastIndex and regexp.global properties are value
-  // properties that are not configurable, so reading them can also not cause
-  // any side effects (converting lastIndex to a number can, though).
-  if (%_ObjectEquals(cache.type, 'exec') &&
-      %_ObjectEquals(0, lastIndex) &&
-      %_IsRegExpEquivalent(cache.regExp, this) &&
-      %_ObjectEquals(cache.subject, string)) {
-    if (cache.answerSaved) {
-      // The regexp.lastIndex value must be 0 for non-global RegExps, and for
-      // global RegExps we only cache negative results, which gives a lastIndex
-      // of zero as well.
-      this.lastIndex = 0;
-      return %_RegExpCloneResult(cache.answer);
-    } else {
-      saveAnswer = true;
-    }
-  }
-
   if (%_ArgumentsLength() === 0) {
     var regExpInput = LAST_INPUT(lastMatchInfo);
     if (IS_UNDEFINED(regExpInput)) {
@@ -217,11 +172,13 @@
   } else {
     s = ToString(string);
   }
-  var global = this.global;
+  var lastIndex = this.lastIndex;
 
   // Conversion is required by the ES5 specification (RegExp.prototype.exec
   // algorithm, step 5) even if the value is discarded for non-global RegExps.
   var i = TO_INTEGER(lastIndex);
+
+  var global = this.global;
   if (global) {
     if (i < 0 || i > s.length) {
       this.lastIndex = 0;
@@ -237,16 +194,9 @@
 
   if (matchIndices === null) {
     if (global) {
-      // Cache negative result only if initial lastIndex was zero.
       this.lastIndex = 0;
-      if (lastIndex !== 0) return matchIndices;
     }
-    cache.regExp = this;
-    cache.subject = s;            // Always a string.
-    cache.answer = null;
-    cache.answerSaved = true;     // Safe since no cloning is needed.
-    cache.type = 'exec';
-    return matchIndices;        // No match.
+    return null;
   }
 
   // Successful match.
@@ -254,17 +204,9 @@
   var result = BuildResultFromMatchInfo(matchIndices, s);
 
   if (global) {
-    // Don't cache positive results for global regexps.
     this.lastIndex = lastMatchInfo[CAPTURE1];
-  } else {
-    cache.regExp = this;
-    cache.subject = s;
-    if (saveAnswer) cache.answer = %_RegExpCloneResult(result);
-    cache.answerSaved = saveAnswer;
-    cache.type = 'exec';
   }
   return result;
-
 }
 
 
@@ -289,33 +231,22 @@
     string = regExpInput;
   }
 
-  var lastIndex = this.lastIndex;
-
-  var cache = regExpCache;
-  if (%_ObjectEquals(cache.type, 'test') &&
-      %_IsRegExpEquivalent(cache.regExp, this) &&
-      %_ObjectEquals(cache.subject, string) &&
-      %_ObjectEquals(0, lastIndex)) {
-    // The regexp.lastIndex value must be 0 for non-global RegExps, and for
-    // global RegExps we only cache negative results, which gives a resulting
-    // lastIndex of zero as well.
-    if (global) this.lastIndex = 0;
-    return cache.answer;
-  }
-
   var s;
   if (IS_STRING(string)) {
     s = string;
   } else {
     s = ToString(string);
   }
-  var length = s.length;
+
+  var lastIndex = this.lastIndex;
 
   // Conversion is required by the ES5 specification (RegExp.prototype.exec
   // algorithm, step 5) even if the value is discarded for non-global RegExps.
   var i = TO_INTEGER(lastIndex);
+  
+  var global = this.global;
   if (global) {
-    if (i < 0 || i > length) {
+    if (i < 0 || i > s.length) {
       this.lastIndex = 0;
       return false;
     }
@@ -323,8 +254,6 @@
     i = 0;
   }
 
-  var global = this.global;
-
   // Remove irrelevant preceeding '.*' in a test regexp. The expression
   // checks whether this.source starts with '.*' and that the third
   // char is not a '?'
@@ -334,7 +263,7 @@
     if (!%_ObjectEquals(regexp_key, this)) {
       regexp_key = this;
       regexp_val = new $RegExp(this.source.substring(2, this.source.length),
-                               (this.global ? 'g' : '')
+                               (global ? 'g' : '')
                                + (this.ignoreCase ? 'i' : '')
                                + (this.multiline ? 'm' : ''));
     }
@@ -345,24 +274,13 @@
   // matchIndices is either null or the lastMatchInfo array.
   var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
 
-  var result = (matchIndices !== null);
-  if (result) {
-    lastMatchInfoOverride = null;
+  if (matchIndices === null) {
+    if (global) this.lastIndex = 0;
+    return false;
   }
-  if (global) {
-    if (result) {
-      this.lastIndex = lastMatchInfo[CAPTURE1];
-      return true;
-    } else {
-      this.lastIndex = 0;
-      if (lastIndex !== 0) return false;
-    }
-  }
-  cache.type = 'test';
-  cache.regExp = this;
-  cache.subject = s;
-  cache.answer = result;
-  return result;
+  lastMatchInfoOverride = null;
+  if (global) this.lastIndex = lastMatchInfo[CAPTURE1];
+  return true;
 }
 
 
@@ -510,7 +428,6 @@
     return IS_UNDEFINED(regExpInput) ? "" : regExpInput;
   }
   function RegExpSetInput(string) {
-    regExpCache.type = 'none';
     LAST_INPUT(lastMatchInfo) = ToString(string);
   };
 
diff --git a/src/runtime.cc b/src/runtime.cc
index f701c03..5534db5 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1424,66 +1424,6 @@
 }
 
 
-static MaybeObject* Runtime_RegExpCloneResult(Arguments args) {
-  ASSERT(args.length() == 1);
-  Map* regexp_result_map;
-  {
-    AssertNoAllocation no_gc;
-    HandleScope handles;
-    regexp_result_map = Top::global_context()->regexp_result_map();
-  }
-  if (!args[0]->IsJSArray()) return args[0];
-
-  JSArray* result = JSArray::cast(args[0]);
-  // Arguments to RegExpCloneResult should always be fresh RegExp exec call
-  // results (either a fresh JSRegExpResult or null).
-  // If the argument is not a JSRegExpResult, or isn't unmodified, just return
-  // the argument uncloned.
-  if (result->map() != regexp_result_map) return result;
-
-  // Having the original JSRegExpResult map guarantees that we have
-  // fast elements and no properties except the two in-object properties.
-  ASSERT(result->HasFastElements());
-  ASSERT(result->properties() == Heap::empty_fixed_array());
-  ASSERT_EQ(2, regexp_result_map->inobject_properties());
-
-  Object* new_array_alloc;
-  { MaybeObject* maybe_new_array_alloc =
-        Heap::AllocateRaw(JSRegExpResult::kSize, NEW_SPACE, OLD_POINTER_SPACE);
-    if (!maybe_new_array_alloc->ToObject(&new_array_alloc)) {
-      return maybe_new_array_alloc;
-    }
-  }
-
-  // Set HeapObject map to JSRegExpResult map.
-  reinterpret_cast<HeapObject*>(new_array_alloc)->set_map(regexp_result_map);
-
-  JSArray* new_array = JSArray::cast(new_array_alloc);
-
-  // Copy JSObject properties.
-  new_array->set_properties(result->properties());  // Empty FixedArray.
-
-  // Copy JSObject elements as copy-on-write.
-  FixedArray* elements = FixedArray::cast(result->elements());
-  if (elements != Heap::empty_fixed_array()) {
-    elements->set_map(Heap::fixed_cow_array_map());
-  }
-  new_array->set_elements(elements);
-
-  // Copy JSArray length.
-  new_array->set_length(result->length());
-
-  // Copy JSRegExpResult in-object property fields input and index.
-  new_array->FastPropertyAtPut(JSRegExpResult::kIndexIndex,
-                               result->FastPropertyAt(
-                                   JSRegExpResult::kIndexIndex));
-  new_array->FastPropertyAtPut(JSRegExpResult::kInputIndex,
-                               result->FastPropertyAt(
-                                   JSRegExpResult::kInputIndex));
-  return new_array;
-}
-
-
 static MaybeObject* Runtime_RegExpInitializeObject(Arguments args) {
   AssertNoAllocation no_alloc;
   ASSERT(args.length() == 5);
@@ -7129,20 +7069,31 @@
 }
 
 
+static MaybeObject* Runtime_ParseJson(Arguments args) {
+  HandleScope scope;
+  ASSERT_EQ(1, args.length());
+  CONVERT_ARG_CHECKED(String, source, 0);
+
+  Handle<Object> result = JsonParser::Parse(source);
+  if (result.is_null()) {
+    // Syntax error or stack overflow in scanner.
+    ASSERT(Top::has_pending_exception());
+    return Failure::Exception();
+  }
+  return *result;
+}
+
+
 static MaybeObject* Runtime_CompileString(Arguments args) {
   HandleScope scope;
-  ASSERT_EQ(2, args.length());
+  ASSERT_EQ(1, args.length());
   CONVERT_ARG_CHECKED(String, source, 0);
-  CONVERT_ARG_CHECKED(Oddball, is_json, 1)
 
   // Compile source string in the global context.
   Handle<Context> context(Top::context()->global_context());
-  Compiler::ValidationState validate = (is_json->IsTrue())
-    ? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON;
   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
                                                             context,
-                                                            true,
-                                                            validate);
+                                                            true);
   if (shared.is_null()) return Failure::Exception();
   Handle<JSFunction> fun =
       Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED);
@@ -7157,8 +7108,7 @@
   Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
       source,
       Handle<Context>(Top::context()),
-      Top::context()->IsGlobalContext(),
-      Compiler::DONT_VALIDATE_JSON);
+      Top::context()->IsGlobalContext());
   if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
   Handle<JSFunction> compiled = Factory::NewFunctionFromSharedFunctionInfo(
       shared,
@@ -8881,12 +8831,6 @@
 }
 
 
-static MaybeObject* Runtime_GetCFrames(Arguments args) {
-  // See bug 906.
-  return Heap::undefined_value();
-}
-
-
 static MaybeObject* Runtime_GetThreadCount(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 1);
@@ -9370,8 +9314,7 @@
   Handle<SharedFunctionInfo> shared =
       Compiler::CompileEval(function_source,
                             context,
-                            context->IsGlobalContext(),
-                            Compiler::DONT_VALIDATE_JSON);
+                            context->IsGlobalContext());
   if (shared.is_null()) return Failure::Exception();
   Handle<JSFunction> compiled_function =
       Factory::NewFunctionFromSharedFunctionInfo(shared, context);
@@ -9442,8 +9385,7 @@
   Handle<SharedFunctionInfo> shared =
       Compiler::CompileEval(source,
                             context,
-                            true,
-                            Compiler::DONT_VALIDATE_JSON);
+                            true);
   if (shared.is_null()) return Failure::Exception();
   Handle<JSFunction> compiled_function =
       Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared,
diff --git a/src/runtime.h b/src/runtime.h
index 8057d8b..756099b 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -162,7 +162,9 @@
   F(RegExpExecMultiple, 4, 1) \
   F(RegExpInitializeObject, 5, 1) \
   F(RegExpConstructResult, 3, 1) \
-  F(RegExpCloneResult, 1, 1) \
+  \
+  /* JSON */ \
+  F(ParseJson, 1, 1) \
   \
   /* Strings */ \
   F(StringCharCodeAt, 2, 1) \
@@ -222,7 +224,7 @@
   /* Numbers */ \
   \
   /* Globals */ \
-  F(CompileString, 2, 1) \
+  F(CompileString, 1, 1) \
   F(GlobalPrint, 1, 1) \
   \
   /* Eval */ \
@@ -322,7 +324,6 @@
   F(GetScopeCount, 2, 1) \
   F(GetScopeDetails, 3, 1) \
   F(DebugPrintScopes, 0, 1) \
-  F(GetCFrames, 1, 1) \
   F(GetThreadCount, 1, 1) \
   F(GetThreadDetails, 2, 1) \
   F(SetDisableBreak, 1, 1) \
@@ -423,7 +424,7 @@
 // ----------------------------------------------------------------------------
 // INLINE_AND_RUNTIME_FUNCTION_LIST defines all inlined functions accessed
 // with a native call of the form %_name from within JS code that also have
-  // a corresponding runtime function, that is called for slow cases.
+// a corresponding runtime function, that is called for slow cases.
 // Entries have the form F(name, number of arguments, number of return values).
 #define INLINE_RUNTIME_FUNCTION_LIST(F) \
   F(IsConstructCall, 0, 1)                                                   \
@@ -435,7 +436,6 @@
   F(StringCompare, 2, 1)                                                     \
   F(RegExpExec, 4, 1)                                                        \
   F(RegExpConstructResult, 3, 1)                                             \
-  F(RegExpCloneResult, 1, 1)                                                 \
   F(GetFromCache, 2, 1)                                                      \
   F(NumberToString, 1, 1)                                                    \
   F(SwapElements, 3, 1)
diff --git a/src/scanner-base.cc b/src/scanner-base.cc
new file mode 100644
index 0000000..6e9d40e
--- /dev/null
+++ b/src/scanner-base.cc
@@ -0,0 +1,167 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Features shared by parsing and pre-parsing scanners.
+
+#include "scanner-base.h"
+
+namespace v8 {
+namespace internal {
+
+// ----------------------------------------------------------------------------
+// Keyword Matcher
+
+KeywordMatcher::FirstState KeywordMatcher::first_states_[] = {
+  { "break",  KEYWORD_PREFIX, Token::BREAK },
+  { NULL,     C,              Token::ILLEGAL },
+  { NULL,     D,              Token::ILLEGAL },
+  { "else",   KEYWORD_PREFIX, Token::ELSE },
+  { NULL,     F,              Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     I,              Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     N,              Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { "return", KEYWORD_PREFIX, Token::RETURN },
+  { "switch", KEYWORD_PREFIX, Token::SWITCH },
+  { NULL,     T,              Token::ILLEGAL },
+  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
+  { NULL,     V,              Token::ILLEGAL },
+  { NULL,     W,              Token::ILLEGAL }
+};
+
+
+void KeywordMatcher::Step(unibrow::uchar input) {
+  switch (state_) {
+    case INITIAL: {
+      // matching the first character is the only state with significant fanout.
+      // Match only lower-case letters in range 'b'..'w'.
+      unsigned int offset = input - kFirstCharRangeMin;
+      if (offset < kFirstCharRangeLength) {
+        state_ = first_states_[offset].state;
+        if (state_ == KEYWORD_PREFIX) {
+          keyword_ = first_states_[offset].keyword;
+          counter_ = 1;
+          keyword_token_ = first_states_[offset].token;
+        }
+        return;
+      }
+      break;
+    }
+    case KEYWORD_PREFIX:
+      if (static_cast<unibrow::uchar>(keyword_[counter_]) == input) {
+        counter_++;
+        if (keyword_[counter_] == '\0') {
+          state_ = KEYWORD_MATCHED;
+          token_ = keyword_token_;
+        }
+        return;
+      }
+      break;
+    case KEYWORD_MATCHED:
+      token_ = Token::IDENTIFIER;
+      break;
+    case C:
+      if (MatchState(input, 'a', CA)) return;
+      if (MatchState(input, 'o', CO)) return;
+      break;
+    case CA:
+      if (MatchKeywordStart(input, "case", 2, Token::CASE)) return;
+      if (MatchKeywordStart(input, "catch", 2, Token::CATCH)) return;
+      break;
+    case CO:
+      if (MatchState(input, 'n', CON)) return;
+      break;
+    case CON:
+      if (MatchKeywordStart(input, "const", 3, Token::CONST)) return;
+      if (MatchKeywordStart(input, "continue", 3, Token::CONTINUE)) return;
+      break;
+    case D:
+      if (MatchState(input, 'e', DE)) return;
+      if (MatchKeyword(input, 'o', KEYWORD_MATCHED, Token::DO)) return;
+      break;
+    case DE:
+      if (MatchKeywordStart(input, "debugger", 2, Token::DEBUGGER)) return;
+      if (MatchKeywordStart(input, "default", 2, Token::DEFAULT)) return;
+      if (MatchKeywordStart(input, "delete", 2, Token::DELETE)) return;
+      break;
+    case F:
+      if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return;
+      if (MatchKeywordStart(input, "finally", 1, Token::FINALLY)) return;
+      if (MatchKeywordStart(input, "for", 1, Token::FOR)) return;
+      if (MatchKeywordStart(input, "function", 1, Token::FUNCTION)) return;
+      break;
+    case I:
+      if (MatchKeyword(input, 'f', KEYWORD_MATCHED, Token::IF)) return;
+      if (MatchKeyword(input, 'n', IN, Token::IN)) return;
+      break;
+    case IN:
+      token_ = Token::IDENTIFIER;
+      if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) {
+        return;
+      }
+      break;
+    case N:
+      if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return;
+      if (MatchKeywordStart(input, "new", 1, Token::NEW)) return;
+      if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return;
+      break;
+    case T:
+      if (MatchState(input, 'h', TH)) return;
+      if (MatchState(input, 'r', TR)) return;
+      if (MatchKeywordStart(input, "typeof", 1, Token::TYPEOF)) return;
+      break;
+    case TH:
+      if (MatchKeywordStart(input, "this", 2, Token::THIS)) return;
+      if (MatchKeywordStart(input, "throw", 2, Token::THROW)) return;
+      break;
+    case TR:
+      if (MatchKeywordStart(input, "true", 2, Token::TRUE_LITERAL)) return;
+      if (MatchKeyword(input, 'y', KEYWORD_MATCHED, Token::TRY)) return;
+      break;
+    case V:
+      if (MatchKeywordStart(input, "var", 1, Token::VAR)) return;
+      if (MatchKeywordStart(input, "void", 1, Token::VOID)) return;
+      break;
+    case W:
+      if (MatchKeywordStart(input, "while", 1, Token::WHILE)) return;
+      if (MatchKeywordStart(input, "with", 1, Token::WITH)) return;
+      break;
+    case UNMATCHABLE:
+      break;
+  }
+  // On fallthrough, it's a failure.
+  state_ = UNMATCHABLE;
+}
+
+} }  // namespace v8::internal
diff --git a/src/scanner-base.h b/src/scanner-base.h
new file mode 100644
index 0000000..500870b
--- /dev/null
+++ b/src/scanner-base.h
@@ -0,0 +1,165 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Features shared by parsing and pre-parsing scanners.
+
+#ifndef V8_SCANNER_BASE_H_
+#define V8_SCANNER_BASE_H_
+
+#include "token.h"
+#include "unicode.h"
+
+namespace v8 {
+namespace internal {
+
+class KeywordMatcher {
+//  Incrementally recognize keywords.
+//
+//  Recognized keywords:
+//      break case catch const* continue debugger* default delete do else
+//      finally false for function if in instanceof native* new null
+//      return switch this throw true try typeof var void while with
+//
+//  *: Actually "future reserved keywords". These are the only ones we
+//     recognized, the remaining are allowed as identifiers.
+ public:
+  KeywordMatcher()
+      : state_(INITIAL),
+        token_(Token::IDENTIFIER),
+        keyword_(NULL),
+        counter_(0),
+        keyword_token_(Token::ILLEGAL) {}
+
+  Token::Value token() { return token_; }
+
+  inline void AddChar(unibrow::uchar input) {
+    if (state_ != UNMATCHABLE) {
+      Step(input);
+    }
+  }
+
+  void Fail() {
+    token_ = Token::IDENTIFIER;
+    state_ = UNMATCHABLE;
+  }
+
+ private:
+  enum State {
+    UNMATCHABLE,
+    INITIAL,
+    KEYWORD_PREFIX,
+    KEYWORD_MATCHED,
+    C,
+    CA,
+    CO,
+    CON,
+    D,
+    DE,
+    F,
+    I,
+    IN,
+    N,
+    T,
+    TH,
+    TR,
+    V,
+    W
+  };
+
+  struct FirstState {
+    const char* keyword;
+    State state;
+    Token::Value token;
+  };
+
+  // Range of possible first characters of a keyword.
+  static const unsigned int kFirstCharRangeMin = 'b';
+  static const unsigned int kFirstCharRangeMax = 'w';
+  static const unsigned int kFirstCharRangeLength =
+      kFirstCharRangeMax - kFirstCharRangeMin + 1;
+  // State map for first keyword character range.
+  static FirstState first_states_[kFirstCharRangeLength];
+
+  // If input equals keyword's character at position, continue matching keyword
+  // from that position.
+  inline bool MatchKeywordStart(unibrow::uchar input,
+                                const char* keyword,
+                                int position,
+                                Token::Value token_if_match) {
+    if (input == static_cast<unibrow::uchar>(keyword[position])) {
+      state_ = KEYWORD_PREFIX;
+      this->keyword_ = keyword;
+      this->counter_ = position + 1;
+      this->keyword_token_ = token_if_match;
+      return true;
+    }
+    return false;
+  }
+
+  // If input equals match character, transition to new state and return true.
+  inline bool MatchState(unibrow::uchar input, char match, State new_state) {
+    if (input == static_cast<unibrow::uchar>(match)) {
+      state_ = new_state;
+      return true;
+    }
+    return false;
+  }
+
+  inline bool MatchKeyword(unibrow::uchar input,
+                           char match,
+                           State new_state,
+                           Token::Value keyword_token) {
+    if (input != static_cast<unibrow::uchar>(match)) {
+      return false;
+    }
+    state_ = new_state;
+    token_ = keyword_token;
+    return true;
+  }
+
+  void Step(unibrow::uchar input);
+
+  // Current state.
+  State state_;
+  // Token for currently added characters.
+  Token::Value token_;
+
+  // Matching a specific keyword string (there is only one possible valid
+  // keyword with the current prefix).
+  const char* keyword_;
+  int counter_;
+  Token::Value keyword_token_;
+};
+
+
+
+
+
+
+} }  // namespace v8::internal
+
+#endif  // V8_SCANNER_BASE_H_
diff --git a/src/scanner.cc b/src/scanner.cc
index 79d63f1..a24952a 100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -184,142 +184,6 @@
   pos_ = pos;
 }
 
-
-// ----------------------------------------------------------------------------
-// Keyword Matcher
-
-KeywordMatcher::FirstState KeywordMatcher::first_states_[] = {
-  { "break",  KEYWORD_PREFIX, Token::BREAK },
-  { NULL,     C,              Token::ILLEGAL },
-  { NULL,     D,              Token::ILLEGAL },
-  { "else",   KEYWORD_PREFIX, Token::ELSE },
-  { NULL,     F,              Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     I,              Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     N,              Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { "return", KEYWORD_PREFIX, Token::RETURN },
-  { "switch", KEYWORD_PREFIX, Token::SWITCH },
-  { NULL,     T,              Token::ILLEGAL },
-  { NULL,     UNMATCHABLE,    Token::ILLEGAL },
-  { NULL,     V,              Token::ILLEGAL },
-  { NULL,     W,              Token::ILLEGAL }
-};
-
-
-void KeywordMatcher::Step(uc32 input) {
-  switch (state_) {
-    case INITIAL: {
-      // matching the first character is the only state with significant fanout.
-      // Match only lower-case letters in range 'b'..'w'.
-      unsigned int offset = input - kFirstCharRangeMin;
-      if (offset < kFirstCharRangeLength) {
-        state_ = first_states_[offset].state;
-        if (state_ == KEYWORD_PREFIX) {
-          keyword_ = first_states_[offset].keyword;
-          counter_ = 1;
-          keyword_token_ = first_states_[offset].token;
-        }
-        return;
-      }
-      break;
-    }
-    case KEYWORD_PREFIX:
-      if (keyword_[counter_] == input) {
-        ASSERT_NE(input, '\0');
-        counter_++;
-        if (keyword_[counter_] == '\0') {
-          state_ = KEYWORD_MATCHED;
-          token_ = keyword_token_;
-        }
-        return;
-      }
-      break;
-    case KEYWORD_MATCHED:
-      token_ = Token::IDENTIFIER;
-      break;
-    case C:
-      if (MatchState(input, 'a', CA)) return;
-      if (MatchState(input, 'o', CO)) return;
-      break;
-    case CA:
-      if (MatchKeywordStart(input, "case", 2, Token::CASE)) return;
-      if (MatchKeywordStart(input, "catch", 2, Token::CATCH)) return;
-      break;
-    case CO:
-      if (MatchState(input, 'n', CON)) return;
-      break;
-    case CON:
-      if (MatchKeywordStart(input, "const", 3, Token::CONST)) return;
-      if (MatchKeywordStart(input, "continue", 3, Token::CONTINUE)) return;
-      break;
-    case D:
-      if (MatchState(input, 'e', DE)) return;
-      if (MatchKeyword(input, 'o', KEYWORD_MATCHED, Token::DO)) return;
-      break;
-    case DE:
-      if (MatchKeywordStart(input, "debugger", 2, Token::DEBUGGER)) return;
-      if (MatchKeywordStart(input, "default", 2, Token::DEFAULT)) return;
-      if (MatchKeywordStart(input, "delete", 2, Token::DELETE)) return;
-      break;
-    case F:
-      if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return;
-      if (MatchKeywordStart(input, "finally", 1, Token::FINALLY)) return;
-      if (MatchKeywordStart(input, "for", 1, Token::FOR)) return;
-      if (MatchKeywordStart(input, "function", 1, Token::FUNCTION)) return;
-      break;
-    case I:
-      if (MatchKeyword(input, 'f', KEYWORD_MATCHED, Token::IF)) return;
-      if (MatchKeyword(input, 'n', IN, Token::IN)) return;
-      break;
-    case IN:
-      token_ = Token::IDENTIFIER;
-      if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) {
-        return;
-      }
-      break;
-    case N:
-      if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return;
-      if (MatchKeywordStart(input, "new", 1, Token::NEW)) return;
-      if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return;
-      break;
-    case T:
-      if (MatchState(input, 'h', TH)) return;
-      if (MatchState(input, 'r', TR)) return;
-      if (MatchKeywordStart(input, "typeof", 1, Token::TYPEOF)) return;
-      break;
-    case TH:
-      if (MatchKeywordStart(input, "this", 2, Token::THIS)) return;
-      if (MatchKeywordStart(input, "throw", 2, Token::THROW)) return;
-      break;
-    case TR:
-      if (MatchKeywordStart(input, "true", 2, Token::TRUE_LITERAL)) return;
-      if (MatchKeyword(input, 'y', KEYWORD_MATCHED, Token::TRY)) return;
-      break;
-    case V:
-      if (MatchKeywordStart(input, "var", 1, Token::VAR)) return;
-      if (MatchKeywordStart(input, "void", 1, Token::VOID)) return;
-      break;
-    case W:
-      if (MatchKeywordStart(input, "while", 1, Token::WHILE)) return;
-      if (MatchKeywordStart(input, "with", 1, Token::WITH)) return;
-      break;
-    default:
-      UNREACHABLE();
-  }
-  // On fallthrough, it's a failure.
-  state_ = UNMATCHABLE;
-}
-
-
-
 // ----------------------------------------------------------------------------
 // Scanner::LiteralScope
 
diff --git a/src/scanner.h b/src/scanner.h
index 6e5333b..1f49fd0 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -30,6 +30,7 @@
 
 #include "token.h"
 #include "char-predicates-inl.h"
+#include "scanner-base.h"
 
 namespace v8 {
 namespace internal {
@@ -142,127 +143,6 @@
 };
 
 
-class KeywordMatcher {
-//  Incrementally recognize keywords.
-//
-//  Recognized keywords:
-//      break case catch const* continue debugger* default delete do else
-//      finally false for function if in instanceof native* new null
-//      return switch this throw true try typeof var void while with
-//
-//  *: Actually "future reserved keywords". These are the only ones we
-//     recognized, the remaining are allowed as identifiers.
- public:
-  KeywordMatcher()
-      : state_(INITIAL),
-        token_(Token::IDENTIFIER),
-        keyword_(NULL),
-        counter_(0),
-        keyword_token_(Token::ILLEGAL) {}
-
-  Token::Value token() { return token_; }
-
-  inline void AddChar(uc32 input) {
-    if (state_ != UNMATCHABLE) {
-      Step(input);
-    }
-  }
-
-  void Fail() {
-    token_ = Token::IDENTIFIER;
-    state_ = UNMATCHABLE;
-  }
-
- private:
-  enum State {
-    UNMATCHABLE,
-    INITIAL,
-    KEYWORD_PREFIX,
-    KEYWORD_MATCHED,
-    C,
-    CA,
-    CO,
-    CON,
-    D,
-    DE,
-    F,
-    I,
-    IN,
-    N,
-    T,
-    TH,
-    TR,
-    V,
-    W
-  };
-
-  struct FirstState {
-    const char* keyword;
-    State state;
-    Token::Value token;
-  };
-
-  // Range of possible first characters of a keyword.
-  static const unsigned int kFirstCharRangeMin = 'b';
-  static const unsigned int kFirstCharRangeMax = 'w';
-  static const unsigned int kFirstCharRangeLength =
-      kFirstCharRangeMax - kFirstCharRangeMin + 1;
-  // State map for first keyword character range.
-  static FirstState first_states_[kFirstCharRangeLength];
-
-  // If input equals keyword's character at position, continue matching keyword
-  // from that position.
-  inline bool MatchKeywordStart(uc32 input,
-                                const char* keyword,
-                                int position,
-                                Token::Value token_if_match) {
-    if (input == keyword[position]) {
-      state_ = KEYWORD_PREFIX;
-      this->keyword_ = keyword;
-      this->counter_ = position + 1;
-      this->keyword_token_ = token_if_match;
-      return true;
-    }
-    return false;
-  }
-
-  // If input equals match character, transition to new state and return true.
-  inline bool MatchState(uc32 input, char match, State new_state) {
-    if (input == match) {
-      state_ = new_state;
-      return true;
-    }
-    return false;
-  }
-
-  inline bool MatchKeyword(uc32 input,
-                           char match,
-                           State new_state,
-                           Token::Value keyword_token) {
-    if (input != match) {
-      return false;
-    }
-    state_ = new_state;
-    token_ = keyword_token;
-    return true;
-  }
-
-  void Step(uc32 input);
-
-  // Current state.
-  State state_;
-  // Token for currently added characters.
-  Token::Value token_;
-
-  // Matching a specific keyword string (there is only one possible valid
-  // keyword with the current prefix).
-  const char* keyword_;
-  int counter_;
-  Token::Value keyword_token_;
-};
-
-
-enum ParserMode { PARSE, PREPARSE };
 enum ParserLanguage { JAVASCRIPT, JSON };
 
 
@@ -296,6 +176,9 @@
   // Returns the next token.
   Token::Value Next();
 
+  // Returns the current token again.
+  Token::Value current_token() { return current_.token; }
+
   // One token look-ahead (past the token returned by Next()).
   Token::Value peek() const { return next_.token; }
 
diff --git a/src/string.js b/src/string.js
index d97f632..d82ce05 100644
--- a/src/string.js
+++ b/src/string.js
@@ -144,16 +144,6 @@
 }
 
 
-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
@@ -172,33 +162,12 @@
   var subject = TO_STRING_INLINE(this);
   if (IS_REGEXP(regexp)) {
     if (!regexp.global) return regexp.exec(subject);
-
-    var cache = regExpCache;
-    var saveAnswer = false;
-
-    if (%_ObjectEquals(cache.type, 'match') &&
-        %_IsRegExpEquivalent(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;
+    return %StringMatch(subject, regexp, lastMatchInfo);
   }
   // 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);
 }
 
@@ -231,7 +200,6 @@
   if (IS_REGEXP(search)) {
     %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]);
     if (IS_FUNCTION(replace)) {
-      regExpCache.type = 'none';
       if (search.global) {
         return StringReplaceGlobalRegExpWithFunction(subject, search, replace);
       } else {
@@ -273,24 +241,10 @@
 
 // Helper function for regular expressions in String.prototype.replace.
 function StringReplaceRegExp(subject, regexp, replace) {
-  var cache = regExpCache;
-  if (%_ObjectEquals(cache.type, 'replace') &&
-      %_IsRegExpEquivalent(cache.regExp, regexp) &&
-      %_ObjectEquals(cache.replaceString, replace) &&
-      %_ObjectEquals(cache.subject, subject)) {
-    return cache.answer;
-  }
-  replace = TO_STRING_INLINE(replace);
-  var answer = %StringReplaceRegExpWithString(subject,
-                                              regexp,
-                                              replace,
-                                              lastMatchInfo);
-  cache.subject = subject;
-  cache.regExp = regexp;
-  cache.replaceString = replace;
-  cache.answer = answer;
-  cache.type = 'replace';
-  return answer;
+  return %StringReplaceRegExpWithString(subject,
+                                        regexp,
+                                        TO_STRING_INLINE(replace),
+                                        lastMatchInfo);
 }
 
 
@@ -605,34 +559,12 @@
     return result;
   }
 
-  var cache = regExpCache;
-  var saveAnswer = false;
-
-  if (%_ObjectEquals(cache.type, 'split') &&
-      %_IsRegExpEquivalent(cache.regExp, separator) &&
-      %_ObjectEquals(cache.subject, subject) &&
-      %_ObjectEquals(cache.splitLimit, limit)) {
-    if (cache.answerSaved) {
-      return CloneDenseArray(cache.answer);
-    } else {
-      saveAnswer = true;
-    }
-  }
-
-  cache.type = 'split';
-  cache.regExp = separator;
-  cache.subject = subject;
-  cache.splitLimit = limit;
-
   %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
 
   if (length === 0) {
-    cache.answerSaved = true;
-    if (splitMatch(separator, subject, 0, 0) != null) {
-      cache.answer = [];
+    if (DoRegExpExec(separator, subject, 0, 0) != null) {
       return [];
     }
-    cache.answer = [subject];
     return [subject];
   }
 
@@ -680,8 +612,6 @@
 
     startIndex = currentIndex = endIndex;
   }
-  if (saveAnswer) cache.answer = CloneDenseArray(result);
-  cache.answerSaved = saveAnswer;
   return result;
 }
 
diff --git a/src/stub-cache.h b/src/stub-cache.h
index 07d2197..9d947e4 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -241,13 +241,15 @@
   static void Clear();
 
   // Generate code for probing the stub cache table.
-  // If extra != no_reg it might be used as am extra scratch register.
+  // Arguments extra and extra2 may be used to pass additional scratch
+  // registers. Set to no_reg if not needed.
   static void GenerateProbe(MacroAssembler* masm,
                             Code::Flags flags,
                             Register receiver,
                             Register name,
                             Register scratch,
-                            Register extra);
+                            Register extra,
+                            Register extra2 = no_reg);
 
   enum Table {
     kPrimary,
diff --git a/src/token.h b/src/token.h
index ebc7fea..74d9539 100644
--- a/src/token.h
+++ b/src/token.h
@@ -28,6 +28,8 @@
 #ifndef V8_TOKEN_H_
 #define V8_TOKEN_H_
 
+#include "checks.h"
+
 namespace v8 {
 namespace internal {
 
diff --git a/src/top.h b/src/top.h
index e97289f..bc3a85e 100644
--- a/src/top.h
+++ b/src/top.h
@@ -105,7 +105,11 @@
   Address handler_;   // try-blocks are chained through the stack
 
 #ifdef USE_SIMULATOR
+#ifdef V8_TARGET_ARCH_ARM
   assembler::arm::Simulator* simulator_;
+#elif V8_TARGET_ARCH_MIPS
+  assembler::mips::Simulator* simulator_;
+#endif
 #endif  // USE_SIMULATOR
 
 #ifdef ENABLE_LOGGING_AND_PROFILING
diff --git a/src/utils.cc b/src/utils.cc
index 45a4cd6..7096ba3 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -37,34 +37,6 @@
 namespace internal {
 
 
-// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
-// figure 3-3, page 48, where the function is called clp2.
-uint32_t RoundUpToPowerOf2(uint32_t x) {
-  ASSERT(x <= 0x80000000u);
-  x = x - 1;
-  x = x | (x >> 1);
-  x = x | (x >> 2);
-  x = x | (x >> 4);
-  x = x | (x >> 8);
-  x = x | (x >> 16);
-  return x + 1;
-}
-
-
-// Thomas Wang, Integer Hash Functions.
-// http://www.concentric.net/~Ttwang/tech/inthash.htm
-uint32_t ComputeIntegerHash(uint32_t key) {
-  uint32_t hash = key;
-  hash = ~hash + (hash << 15);  // hash = (hash << 15) - hash - 1;
-  hash = hash ^ (hash >> 12);
-  hash = hash + (hash << 2);
-  hash = hash ^ (hash >> 4);
-  hash = hash * 2057;  // hash = (hash + (hash << 3)) + (hash << 11);
-  hash = hash ^ (hash >> 16);
-  return hash;
-}
-
-
 void PrintF(const char* format, ...) {
   va_list arguments;
   va_start(arguments, format);
@@ -274,12 +246,4 @@
 }
 
 
-int TenToThe(int exponent) {
-  ASSERT(exponent <= 9);
-  ASSERT(exponent >= 1);
-  int answer = 10;
-  for (int i = 1; i < exponent; i++) answer *= 10;
-  return answer;
-}
-
 } }  // namespace v8::internal
diff --git a/src/utils.h b/src/utils.h
index ffdb639..069be4f 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -31,6 +31,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "checks.h"
+
 namespace v8 {
 namespace internal {
 
@@ -142,7 +144,19 @@
 
 // Returns the smallest power of two which is >= x. If you pass in a
 // number that is already a power of two, it is returned as is.
-uint32_t RoundUpToPowerOf2(uint32_t x);
+// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
+// figure 3-3, page 48, where the function is called clp2.
+static inline uint32_t RoundUpToPowerOf2(uint32_t x) {
+  ASSERT(x <= 0x80000000u);
+  x = x - 1;
+  x = x | (x >> 1);
+  x = x | (x >> 2);
+  x = x | (x >> 4);
+  x = x | (x >> 8);
+  x = x | (x >> 16);
+  return x + 1;
+}
+
 
 
 template <typename T>
@@ -216,65 +230,18 @@
 // ----------------------------------------------------------------------------
 // Hash function.
 
-uint32_t ComputeIntegerHash(uint32_t key);
-
-
-// ----------------------------------------------------------------------------
-// I/O support.
-
-#if __GNUC__ >= 4
-// On gcc we can ask the compiler to check the types of %d-style format
-// specifiers and their associated arguments.  TODO(erikcorry) fix this
-// so it works on MacOSX.
-#if defined(__MACH__) && defined(__APPLE__)
-#define PRINTF_CHECKING
-#else  // MacOsX.
-#define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
-#endif
-#else
-#define PRINTF_CHECKING
-#endif
-
-// Our version of printf().
-void PRINTF_CHECKING PrintF(const char* format, ...);
-
-// Our version of fflush.
-void Flush();
-
-
-// Read a line of characters after printing the prompt to stdout. The resulting
-// char* needs to be disposed off with DeleteArray by the caller.
-char* ReadLine(const char* prompt);
-
-
-// Read and return the raw bytes in a file. the size of the buffer is returned
-// in size.
-// The returned buffer must be freed by the caller.
-byte* ReadBytes(const char* filename, int* size, bool verbose = true);
-
-
-// Write size chars from str to the file given by filename.
-// The file is overwritten. Returns the number of chars written.
-int WriteChars(const char* filename,
-               const char* str,
-               int size,
-               bool verbose = true);
-
-
-// Write size bytes to the file given by filename.
-// The file is overwritten. Returns the number of bytes written.
-int WriteBytes(const char* filename,
-               const byte* bytes,
-               int size,
-               bool verbose = true);
-
-
-// Write the C code
-// const char* <varname> = "<str>";
-// const int <varname>_len = <len>;
-// to the file given by filename. Only the first len chars are written.
-int WriteAsCFile(const char* filename, const char* varname,
-                 const char* str, int size, bool verbose = true);
+// Thomas Wang, Integer Hash Functions.
+// http://www.concentric.net/~Ttwang/tech/inthash.htm
+static inline uint32_t ComputeIntegerHash(uint32_t key) {
+  uint32_t hash = key;
+  hash = ~hash + (hash << 15);  // hash = (hash << 15) - hash - 1;
+  hash = hash ^ (hash >> 12);
+  hash = hash + (hash << 2);
+  hash = hash ^ (hash >> 4);
+  hash = hash * 2057;  // hash = (hash + (hash << 3)) + (hash << 11);
+  hash = hash ^ (hash >> 16);
+  return hash;
+}
 
 
 // ----------------------------------------------------------------------------
@@ -416,23 +383,6 @@
 };
 
 
-// A temporary assignment sets a (non-local) variable to a value on
-// construction and resets it the value on destruction.
-template <typename T>
-class TempAssign {
- public:
-  TempAssign(T* var, T value): var_(var), old_value_(*var) {
-    *var = value;
-  }
-
-  ~TempAssign() { *var_ = old_value_; }
-
- private:
-  T* var_;
-  T old_value_;
-};
-
-
 template <typename T, int kSize>
 class EmbeddedVector : public Vector<T> {
  public:
@@ -484,13 +434,6 @@
   return Vector<char>(data, (length < max) ? length : max);
 }
 
-template <typename T>
-inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
-                                             int length) {
-  return Vector< Handle<Object> >(
-      reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
-}
-
 
 /*
  * A class that collects values into a backing store.
@@ -699,156 +642,6 @@
 };
 
 
-// Simple support to read a file into a 0-terminated C-string.
-// The returned buffer must be freed by the caller.
-// On return, *exits tells whether the file existed.
-Vector<const char> ReadFile(const char* filename,
-                            bool* exists,
-                            bool verbose = true);
-
-
-// Simple wrapper that allows an ExternalString to refer to a
-// Vector<const char>. Doesn't assume ownership of the data.
-class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
- public:
-  explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
-
-  virtual const char* data() const { return data_.start(); }
-
-  virtual size_t length() const { return data_.length(); }
-
- private:
-  Vector<const char> data_;
-};
-
-
-// Helper class for building result strings in a character buffer. The
-// purpose of the class is to use safe operations that checks the
-// buffer bounds on all operations in debug mode.
-class StringBuilder {
- public:
-  // Create a string builder with a buffer of the given size. The
-  // buffer is allocated through NewArray<char> and must be
-  // deallocated by the caller of Finalize().
-  explicit StringBuilder(int size);
-
-  StringBuilder(char* buffer, int size)
-      : buffer_(buffer, size), position_(0) { }
-
-  ~StringBuilder() { if (!is_finalized()) Finalize(); }
-
-  int size() const { return buffer_.length(); }
-
-  // Get the current position in the builder.
-  int position() const {
-    ASSERT(!is_finalized());
-    return position_;
-  }
-
-  // Reset the position.
-  void Reset() { position_ = 0; }
-
-  // Add a single character to the builder. It is not allowed to add
-  // 0-characters; use the Finalize() method to terminate the string
-  // instead.
-  void AddCharacter(char c) {
-    ASSERT(c != '\0');
-    ASSERT(!is_finalized() && position_ < buffer_.length());
-    buffer_[position_++] = c;
-  }
-
-  // Add an entire string to the builder. Uses strlen() internally to
-  // compute the length of the input string.
-  void AddString(const char* s);
-
-  // Add the first 'n' characters of the given string 's' to the
-  // builder. The input string must have enough characters.
-  void AddSubstring(const char* s, int n);
-
-  // Add formatted contents to the builder just like printf().
-  void AddFormatted(const char* format, ...);
-
-  // Add character padding to the builder. If count is non-positive,
-  // nothing is added to the builder.
-  void AddPadding(char c, int count);
-
-  // Finalize the string by 0-terminating it and returning the buffer.
-  char* Finalize();
-
- private:
-  Vector<char> buffer_;
-  int position_;
-
-  bool is_finalized() const { return position_ < 0; }
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
-};
-
-
-// Custom memcpy implementation for platforms where the standard version
-// may not be good enough.
-// TODO(lrn): Check whether some IA32 platforms should be excluded.
-#if defined(V8_TARGET_ARCH_IA32)
-
-// TODO(lrn): Extend to other platforms as needed.
-
-typedef void (*MemCopyFunction)(void* dest, const void* src, size_t size);
-
-// Implemented in codegen-<arch>.cc.
-MemCopyFunction CreateMemCopyFunction();
-
-// Copy memory area to disjoint memory area.
-static inline void MemCopy(void* dest, const void* src, size_t size) {
-  static MemCopyFunction memcopy = CreateMemCopyFunction();
-  (*memcopy)(dest, src, size);
-#ifdef DEBUG
-  CHECK_EQ(0, memcmp(dest, src, size));
-#endif
-}
-
-
-// Limit below which the extra overhead of the MemCopy function is likely
-// to outweigh the benefits of faster copying.
-// TODO(lrn): Try to find a more precise value.
-static const int kMinComplexMemCopy = 64;
-
-#else  // V8_TARGET_ARCH_IA32
-
-static inline void MemCopy(void* dest, const void* src, size_t size) {
-  memcpy(dest, src, size);
-}
-
-static const int kMinComplexMemCopy = 256;
-
-#endif  // V8_TARGET_ARCH_IA32
-
-
-// Copy from ASCII/16bit chars to ASCII/16bit chars.
-template <typename sourcechar, typename sinkchar>
-static inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
-  sinkchar* limit = dest + chars;
-#ifdef V8_HOST_CAN_READ_UNALIGNED
-  if (sizeof(*dest) == sizeof(*src)) {
-    if (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest))) {
-      MemCopy(dest, src, chars * sizeof(*dest));
-      return;
-    }
-    // Number of characters in a uintptr_t.
-    static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest);  // NOLINT
-    while (dest <= limit - kStepSize) {
-      *reinterpret_cast<uintptr_t*>(dest) =
-          *reinterpret_cast<const uintptr_t*>(src);
-      dest += kStepSize;
-      src += kStepSize;
-    }
-  }
-#endif
-  while (dest < limit) {
-    *dest++ = static_cast<sinkchar>(*src++);
-  }
-}
-
-
 // Compare ASCII/16bit chars to ASCII/16bit chars.
 template <typename lchar, typename rchar>
 static inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
@@ -877,54 +670,14 @@
 }
 
 
-template <typename T>
-static inline void MemsetPointer(T** dest, T* value, int counter) {
-#if defined(V8_HOST_ARCH_IA32)
-#define STOS "stosl"
-#elif defined(V8_HOST_ARCH_X64)
-#define STOS "stosq"
-#endif
-
-#if defined(__GNUC__) && defined(STOS)
-  asm volatile(
-      "cld;"
-      "rep ; " STOS
-      : "+&c" (counter), "+&D" (dest)
-      : "a" (value)
-      : "memory", "cc");
-#else
-  for (int i = 0; i < counter; i++) {
-    dest[i] = value;
-  }
-#endif
-
-#undef STOS
-}
-
-
-// Copies data from |src| to |dst|.  The data spans MUST not overlap.
-inline void CopyWords(Object** dst, Object** src, int num_words) {
-  ASSERT(Min(dst, src) + num_words <= Max(dst, src));
-  ASSERT(num_words > 0);
-
-  // Use block copying memcpy if the segment we're copying is
-  // enough to justify the extra call/setup overhead.
-  static const int kBlockCopyLimit = 16;
-
-  if (num_words >= kBlockCopyLimit) {
-    memcpy(dst, src, num_words * kPointerSize);
-  } else {
-    int remaining = num_words;
-    do {
-      remaining--;
-      *dst++ = *src++;
-    } while (remaining > 0);
-  }
-}
-
-
 // Calculate 10^exponent.
-int TenToThe(int exponent);
+static inline int TenToThe(int exponent) {
+  ASSERT(exponent <= 9);
+  ASSERT(exponent >= 1);
+  int answer = 10;
+  for (int i = 1; i < exponent; i++) answer *= 10;
+  return answer;
+}
 
 
 // The type-based aliasing rule allows the compiler to assume that pointers of
diff --git a/src/v8.h b/src/v8.h
index 9dbdf4c..1cb8d2f 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -56,7 +56,7 @@
 #include "globals.h"
 #include "checks.h"
 #include "allocation.h"
-#include "utils.h"
+#include "v8utils.h"
 #include "flags.h"
 
 // Objects & heap
diff --git a/src/v8natives.js b/src/v8natives.js
index 88aea9c..50a2774 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -140,7 +140,7 @@
                          'be the global object from which eval originated');
   }
 
-  var f = %CompileString(x, false);
+  var f = %CompileString(x);
   if (!IS_FUNCTION(f)) return f;
 
   return f.call(this);
@@ -151,7 +151,7 @@
 function GlobalExecScript(expr, lang) {
   // NOTE: We don't care about the character casing.
   if (!lang || /javascript/i.test(lang)) {
-    var f = %CompileString(ToString(expr), false);
+    var f = %CompileString(ToString(expr));
     f.call(%GlobalReceiver(global));
   }
   return null;
@@ -1177,7 +1177,7 @@
 
   // The call to SetNewFunctionAttributes will ensure the prototype
   // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
-  var f = %CompileString(source, false)();
+  var f = %CompileString(source)();
   %FunctionSetName(f, "anonymous");
   return %SetNewFunctionAttributes(f);
 }
diff --git a/src/v8utils.h b/src/v8utils.h
new file mode 100644
index 0000000..a907c9f
--- /dev/null
+++ b/src/v8utils.h
@@ -0,0 +1,301 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_V8UTILS_H_
+#define V8_V8UTILS_H_
+
+#include "utils.h"
+
+namespace v8 {
+namespace internal {
+
+// ----------------------------------------------------------------------------
+// I/O support.
+
+#if __GNUC__ >= 4
+// On gcc we can ask the compiler to check the types of %d-style format
+// specifiers and their associated arguments.  TODO(erikcorry) fix this
+// so it works on MacOSX.
+#if defined(__MACH__) && defined(__APPLE__)
+#define PRINTF_CHECKING
+#else  // MacOsX.
+#define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
+#endif
+#else
+#define PRINTF_CHECKING
+#endif
+
+// Our version of printf().
+void PRINTF_CHECKING PrintF(const char* format, ...);
+
+// Our version of fflush.
+void Flush();
+
+
+// Read a line of characters after printing the prompt to stdout. The resulting
+// char* needs to be disposed off with DeleteArray by the caller.
+char* ReadLine(const char* prompt);
+
+
+// Read and return the raw bytes in a file. the size of the buffer is returned
+// in size.
+// The returned buffer must be freed by the caller.
+byte* ReadBytes(const char* filename, int* size, bool verbose = true);
+
+
+// Write size chars from str to the file given by filename.
+// The file is overwritten. Returns the number of chars written.
+int WriteChars(const char* filename,
+               const char* str,
+               int size,
+               bool verbose = true);
+
+
+// Write size bytes to the file given by filename.
+// The file is overwritten. Returns the number of bytes written.
+int WriteBytes(const char* filename,
+               const byte* bytes,
+               int size,
+               bool verbose = true);
+
+
+// Write the C code
+// const char* <varname> = "<str>";
+// const int <varname>_len = <len>;
+// to the file given by filename. Only the first len chars are written.
+int WriteAsCFile(const char* filename, const char* varname,
+                 const char* str, int size, bool verbose = true);
+
+
+// Data structures
+
+template <typename T>
+inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
+                                             int length) {
+  return Vector< Handle<Object> >(
+      reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
+}
+
+// Memory
+
+// Copies data from |src| to |dst|.  The data spans MUST not overlap.
+inline void CopyWords(Object** dst, Object** src, int num_words) {
+  ASSERT(Min(dst, src) + num_words <= Max(dst, src));
+  ASSERT(num_words > 0);
+
+  // Use block copying memcpy if the segment we're copying is
+  // enough to justify the extra call/setup overhead.
+  static const int kBlockCopyLimit = 16;
+
+  if (num_words >= kBlockCopyLimit) {
+    memcpy(dst, src, num_words * kPointerSize);
+  } else {
+    int remaining = num_words;
+    do {
+      remaining--;
+      *dst++ = *src++;
+    } while (remaining > 0);
+  }
+}
+
+
+template <typename T>
+static inline void MemsetPointer(T** dest, T* value, int counter) {
+#if defined(V8_HOST_ARCH_IA32)
+#define STOS "stosl"
+#elif defined(V8_HOST_ARCH_X64)
+#define STOS "stosq"
+#endif
+
+#if defined(__GNUC__) && defined(STOS)
+  asm volatile(
+      "cld;"
+      "rep ; " STOS
+      : "+&c" (counter), "+&D" (dest)
+      : "a" (value)
+      : "memory", "cc");
+#else
+  for (int i = 0; i < counter; i++) {
+    dest[i] = value;
+  }
+#endif
+
+#undef STOS
+}
+
+
+// Simple wrapper that allows an ExternalString to refer to a
+// Vector<const char>. Doesn't assume ownership of the data.
+class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
+ public:
+  explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
+
+  virtual const char* data() const { return data_.start(); }
+
+  virtual size_t length() const { return data_.length(); }
+
+ private:
+  Vector<const char> data_;
+};
+
+
+// Simple support to read a file into a 0-terminated C-string.
+// The returned buffer must be freed by the caller.
+// On return, *exits tells whether the file existed.
+Vector<const char> ReadFile(const char* filename,
+                            bool* exists,
+                            bool verbose = true);
+
+
+// Helper class for building result strings in a character buffer. The
+// purpose of the class is to use safe operations that checks the
+// buffer bounds on all operations in debug mode.
+class StringBuilder {
+ public:
+  // Create a string builder with a buffer of the given size. The
+  // buffer is allocated through NewArray<char> and must be
+  // deallocated by the caller of Finalize().
+  explicit StringBuilder(int size);
+
+  StringBuilder(char* buffer, int size)
+      : buffer_(buffer, size), position_(0) { }
+
+  ~StringBuilder() { if (!is_finalized()) Finalize(); }
+
+  int size() const { return buffer_.length(); }
+
+  // Get the current position in the builder.
+  int position() const {
+    ASSERT(!is_finalized());
+    return position_;
+  }
+
+  // Reset the position.
+  void Reset() { position_ = 0; }
+
+  // Add a single character to the builder. It is not allowed to add
+  // 0-characters; use the Finalize() method to terminate the string
+  // instead.
+  void AddCharacter(char c) {
+    ASSERT(c != '\0');
+    ASSERT(!is_finalized() && position_ < buffer_.length());
+    buffer_[position_++] = c;
+  }
+
+  // Add an entire string to the builder. Uses strlen() internally to
+  // compute the length of the input string.
+  void AddString(const char* s);
+
+  // Add the first 'n' characters of the given string 's' to the
+  // builder. The input string must have enough characters.
+  void AddSubstring(const char* s, int n);
+
+  // Add formatted contents to the builder just like printf().
+  void AddFormatted(const char* format, ...);
+
+  // Add character padding to the builder. If count is non-positive,
+  // nothing is added to the builder.
+  void AddPadding(char c, int count);
+
+  // Finalize the string by 0-terminating it and returning the buffer.
+  char* Finalize();
+
+ private:
+  Vector<char> buffer_;
+  int position_;
+
+  bool is_finalized() const { return position_ < 0; }
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
+};
+
+
+// Custom memcpy implementation for platforms where the standard version
+// may not be good enough.
+#if defined(V8_TARGET_ARCH_IA32)
+
+// The default memcpy on ia32 architectures is generally not as efficient
+// as possible. (If any further ia32 platforms are introduced where the
+// memcpy function is efficient, exclude them from this branch).
+
+typedef void (*MemCopyFunction)(void* dest, const void* src, size_t size);
+
+// Implemented in codegen-<arch>.cc.
+MemCopyFunction CreateMemCopyFunction();
+
+// Copy memory area to disjoint memory area.
+static inline void MemCopy(void* dest, const void* src, size_t size) {
+  static MemCopyFunction memcopy = CreateMemCopyFunction();
+  (*memcopy)(dest, src, size);
+#ifdef DEBUG
+  CHECK_EQ(0, memcmp(dest, src, size));
+#endif
+}
+
+// Limit below which the extra overhead of the MemCopy function is likely
+// to outweigh the benefits of faster copying.
+static const int kMinComplexMemCopy = 64;
+
+#else  // V8_TARGET_ARCH_IA32
+
+static inline void MemCopy(void* dest, const void* src, size_t size) {
+  memcpy(dest, src, size);
+}
+
+static const int kMinComplexMemCopy = 256;
+
+#endif  // V8_TARGET_ARCH_IA32
+
+
+// Copy from ASCII/16bit chars to ASCII/16bit chars.
+template <typename sourcechar, typename sinkchar>
+static inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
+  sinkchar* limit = dest + chars;
+#ifdef V8_HOST_CAN_READ_UNALIGNED
+  if (sizeof(*dest) == sizeof(*src)) {
+    if (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest))) {
+      MemCopy(dest, src, chars * sizeof(*dest));
+      return;
+    }
+    // Number of characters in a uintptr_t.
+    static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest);  // NOLINT
+    while (dest <= limit - kStepSize) {
+      *reinterpret_cast<uintptr_t*>(dest) =
+          *reinterpret_cast<const uintptr_t*>(src);
+      dest += kStepSize;
+      src += kStepSize;
+    }
+  }
+#endif
+  while (dest < limit) {
+    *dest++ = static_cast<sinkchar>(*src++);
+  }
+}
+
+} }  // namespace v8::internal
+
+#endif  // V8_V8UTILS_H_
diff --git a/src/version.cc b/src/version.cc
index 4017ae5..5ef2a65 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     5
-#define BUILD_NUMBER      2
+#define BUILD_NUMBER      5
 #define PATCH_LEVEL       0
 #define CANDIDATE_VERSION false
 
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index bf5ee5b..caed7c8 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -296,7 +296,7 @@
 byte* Assembler::spare_buffer_ = NULL;
 
 Assembler::Assembler(void* buffer, int buffer_size)
-    : code_targets_(100) {
+    : code_targets_(100), positions_recorder_(this) {
   if (buffer == NULL) {
     // Do our own buffer management.
     if (buffer_size <= kMinimalBufferSize) {
@@ -337,10 +337,7 @@
   reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
 
   last_pc_ = NULL;
-  current_statement_position_ = RelocInfo::kNoPosition;
-  current_position_ = RelocInfo::kNoPosition;
-  written_statement_position_ = current_statement_position_;
-  written_position_ = current_position_;
+
 #ifdef GENERATED_CODE_COVERAGE
   InitCoverageLog();
 #endif
@@ -845,7 +842,7 @@
 
 
 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
   // 1110 1000 #32-bit disp.
@@ -2935,14 +2932,14 @@
 }
 
 void Assembler::RecordJSReturn() {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
   RecordRelocInfo(RelocInfo::JS_RETURN);
 }
 
 
 void Assembler::RecordDebugBreakSlot() {
-  WriteRecordedPositions();
+  positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
   RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
 }
@@ -2956,47 +2953,6 @@
 }
 
 
-void Assembler::RecordPosition(int pos) {
-  ASSERT(pos != RelocInfo::kNoPosition);
-  ASSERT(pos >= 0);
-  current_position_ = pos;
-}
-
-
-void Assembler::RecordStatementPosition(int pos) {
-  ASSERT(pos != RelocInfo::kNoPosition);
-  ASSERT(pos >= 0);
-  current_statement_position_ = pos;
-}
-
-
-bool Assembler::WriteRecordedPositions() {
-  bool written = false;
-
-  // Write the statement position if it is different from what was written last
-  // time.
-  if (current_statement_position_ != written_statement_position_) {
-    EnsureSpace ensure_space(this);
-    RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
-    written_statement_position_ = current_statement_position_;
-    written = true;
-  }
-
-  // Write the position if it is different from what was written last time and
-  // also different from the written statement position.
-  if (current_position_ != written_position_ &&
-      current_position_ != written_statement_position_) {
-    EnsureSpace ensure_space(this);
-    RecordRelocInfo(RelocInfo::POSITION, current_position_);
-    written_position_ = current_position_;
-    written = true;
-  }
-
-  // Return whether something was written.
-  return written;
-}
-
-
 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
                                   1 << RelocInfo::INTERNAL_REFERENCE;
 
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index bbc1010..c7f7632 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -1174,13 +1174,9 @@
   // Use --debug_code to enable.
   void RecordComment(const char* msg);
 
-  void RecordPosition(int pos);
-  void RecordStatementPosition(int pos);
-  bool WriteRecordedPositions();
-
   int pc_offset() const { return static_cast<int>(pc_ - buffer_); }
-  int current_statement_position() const { return current_statement_position_; }
-  int current_position() const { return current_position_; }
+
+  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
 
   // Check if there is less than kGap bytes available in the buffer.
   // If this is the case, we need to grow the buffer before emitting
@@ -1404,11 +1400,8 @@
   // push-pop elimination
   byte* last_pc_;
 
-  // source position information
-  int current_statement_position_;
-  int current_position_;
-  int written_statement_position_;
-  int written_position_;
+  PositionsRecorder positions_recorder_;
+  friend class PositionsRecorder;
 };
 
 
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 9e6ef3b..e0e4095 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -2956,7 +2956,7 @@
   CodeForStatementPosition(node);
   Load(node->expression());
   Result return_value = frame_->Pop();
-  masm()->WriteRecordedPositions();
+  masm()->positions_recorder()->WriteRecordedPositions();
   if (function_return_is_shadowed_) {
     function_return_.Jump(&return_value);
   } else {
@@ -4866,6 +4866,11 @@
   }
   frame_->Push(&clone);
 
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  node->CalculateEmitStore();
+
   for (int i = 0; i < node->properties()->length(); i++) {
     ObjectLiteral::Property* property = node->properties()->at(i);
     switch (property->kind()) {
@@ -4880,13 +4885,17 @@
           // Duplicate the object as the IC receiver.
           frame_->Dup();
           Load(property->value());
-          Result ignored =
-              frame_->CallStoreIC(Handle<String>::cast(key), false);
-          // A test rax instruction following the store IC call would
-          // indicate the presence of an inlined version of the
-          // store. Add a nop to indicate that there is no such
-          // inlined version.
-          __ nop();
+          if (property->emit_store()) {
+            Result ignored =
+                frame_->CallStoreIC(Handle<String>::cast(key), false);
+            // A test rax instruction following the store IC call would
+            // indicate the presence of an inlined version of the
+            // store. Add a nop to indicate that there is no such
+            // inlined version.
+            __ nop();
+          } else {
+            frame_->Drop(2);
+          }
           break;
         }
         // Fall through
@@ -4896,8 +4905,12 @@
         frame_->Dup();
         Load(property->key());
         Load(property->value());
-        Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3);
-        // Ignore the result.
+        if (property->emit_store()) {
+          // Ignore the result.
+          Result ignored = frame_->CallRuntime(Runtime::kSetProperty, 3);
+        } else {
+          frame_->Drop(3);
+        }
         break;
       }
       case ObjectLiteral::Property::SETTER: {
@@ -6551,86 +6564,6 @@
 }
 
 
-void CodeGenerator::GenerateRegExpCloneResult(ZoneList<Expression*>* args) {
-  ASSERT_EQ(1, args->length());
-
-  Load(args->at(0));
-  Result object_result = frame_->Pop();
-  object_result.ToRegister(rax);
-  object_result.Unuse();
-  {
-    VirtualFrame::SpilledScope spilled_scope;
-
-    Label done;
-    __ JumpIfSmi(rax, &done);
-
-    // Load JSRegExpResult map into rdx.
-    // Arguments to this function should be results of calling RegExp exec,
-    // which is either an unmodified JSRegExpResult or null. Anything not having
-    // the unmodified JSRegExpResult map is returned unmodified.
-    // This also ensures that elements are fast.
-
-    __ movq(rdx, ContextOperand(rsi, Context::GLOBAL_INDEX));
-    __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalContextOffset));
-    __ movq(rdx, ContextOperand(rdx, Context::REGEXP_RESULT_MAP_INDEX));
-    __ cmpq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
-    __ j(not_equal, &done);
-
-    if (FLAG_debug_code) {
-      // Check that object really has empty properties array, as the map
-      // should guarantee.
-      __ CompareRoot(FieldOperand(rax, JSObject::kPropertiesOffset),
-                     Heap::kEmptyFixedArrayRootIndex);
-      __ Check(equal, "JSRegExpResult: default map but non-empty properties.");
-    }
-
-    DeferredAllocateInNewSpace* allocate_fallback =
-        new DeferredAllocateInNewSpace(JSRegExpResult::kSize,
-                                       rbx,
-                                       rdx.bit() | rax.bit());
-
-    // All set, copy the contents to a new object.
-    __ AllocateInNewSpace(JSRegExpResult::kSize,
-                          rbx,
-                          no_reg,
-                          no_reg,
-                          allocate_fallback->entry_label(),
-                          TAG_OBJECT);
-    __ bind(allocate_fallback->exit_label());
-
-    STATIC_ASSERT(JSRegExpResult::kSize % (2 * kPointerSize) == 0);
-    // There is an even number of fields, so unroll the loop once
-    // for efficiency.
-    for (int i = 0; i < JSRegExpResult::kSize; i += 2 * kPointerSize) {
-      STATIC_ASSERT(JSObject::kMapOffset % (2 * kPointerSize) == 0);
-      if (i != JSObject::kMapOffset) {
-        // The map was already loaded into edx.
-        __ movq(rdx, FieldOperand(rax, i));
-      }
-      __ movq(rcx, FieldOperand(rax, i + kPointerSize));
-
-      STATIC_ASSERT(JSObject::kElementsOffset % (2 * kPointerSize) == 0);
-      if (i == JSObject::kElementsOffset) {
-        // If the elements array isn't empty, make it copy-on-write
-        // before copying it.
-        Label empty;
-        __ CompareRoot(rdx, Heap::kEmptyFixedArrayRootIndex);
-        __ j(equal, &empty);
-        __ LoadRoot(kScratchRegister, Heap::kFixedCOWArrayMapRootIndex);
-        __ movq(FieldOperand(rdx, HeapObject::kMapOffset), kScratchRegister);
-        __ bind(&empty);
-      }
-      __ movq(FieldOperand(rbx, i), rdx);
-      __ movq(FieldOperand(rbx, i + kPointerSize), rcx);
-    }
-    __ movq(rax, rbx);
-
-    __ bind(&done);
-  }
-  frame_->Push(rax);
-}
-
-
 class DeferredSearchCache: public DeferredCode {
  public:
   DeferredSearchCache(Register dst,
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 7957324..1853c83 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -656,8 +656,6 @@
 
   void GenerateRegExpConstructResult(ZoneList<Expression*>* args);
 
-  void GenerateRegExpCloneResult(ZoneList<Expression*>* args);
-
   // Support for fast native caches.
   void GenerateGetFromCache(ZoneList<Expression*>* args);
 
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 32d6242..00ea684 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1158,6 +1158,11 @@
   // result_saved is false the result is in rax.
   bool result_saved = false;
 
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  expr->CalculateEmitStore();
+
   for (int i = 0; i < expr->properties()->length(); i++) {
     ObjectLiteral::Property* property = expr->properties()->at(i);
     if (property->IsCompileTimeValue()) continue;
@@ -1179,8 +1184,10 @@
           VisitForAccumulatorValue(value);
           __ Move(rcx, key->handle());
           __ movq(rdx, Operand(rsp, 0));
-          Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
-          EmitCallIC(ic, RelocInfo::CODE_TARGET);
+          if (property->emit_store()) {
+            Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
+            EmitCallIC(ic, RelocInfo::CODE_TARGET);
+          }
           break;
         }
         // Fall through.
@@ -1188,7 +1195,11 @@
         __ push(Operand(rsp, 0));  // Duplicate receiver.
         VisitForStackValue(key);
         VisitForStackValue(value);
-        __ CallRuntime(Runtime::kSetProperty, 3);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kSetProperty, 3);
+        } else {
+          __ Drop(3);
+        }
         break;
       case ObjectLiteral::Property::SETTER:
       case ObjectLiteral::Property::GETTER:
@@ -1706,12 +1717,14 @@
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+    __ Move(rcx, name);
   }
-  __ Move(rcx, name);
   // Record source position for debugger.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   // Call the IC initialization code.
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
@@ -1729,13 +1742,15 @@
   // Code common for calls using the IC.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+    VisitForAccumulatorValue(key);
+    __ movq(rcx, rax);
   }
-  VisitForAccumulatorValue(key);
-  __ movq(rcx, rax);
   // Record source position for debugger.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   // Call the IC initialization code.
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count,
@@ -1751,11 +1766,13 @@
   // Code common for calls using the call stub.
   ZoneList<Expression*>* args = expr->arguments();
   int arg_count = args->length();
-  for (int i = 0; i < arg_count; i++) {
-    VisitForStackValue(args->at(i));
+  { PreserveStatementPositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
   }
   // Record source position for debugger.
-  SetSourcePosition(expr->position());
+  SetSourcePosition(expr->position(), FORCED_POSITION);
   InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
   CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
   __ CallStub(&stub);
@@ -1776,37 +1793,38 @@
     // resolve the function we need to call and the receiver of the
     // call.  The we call the resolved function using the given
     // arguments.
-    VisitForStackValue(fun);
-    __ PushRoot(Heap::kUndefinedValueRootIndex);  // Reserved receiver slot.
-
-    // Push the arguments.
     ZoneList<Expression*>* args = expr->arguments();
     int arg_count = args->length();
-    for (int i = 0; i < arg_count; i++) {
-      VisitForStackValue(args->at(i));
-    }
+    { PreserveStatementPositionScope pos_scope(masm()->positions_recorder());
+      VisitForStackValue(fun);
+      __ PushRoot(Heap::kUndefinedValueRootIndex);  // Reserved receiver slot.
 
-    // Push copy of the function - found below the arguments.
-    __ push(Operand(rsp, (arg_count + 1) * kPointerSize));
+      // Push the arguments.
+      for (int i = 0; i < arg_count; i++) {
+        VisitForStackValue(args->at(i));
+      }
 
-    // Push copy of the first argument or undefined if it doesn't exist.
-    if (arg_count > 0) {
-      __ push(Operand(rsp, arg_count * kPointerSize));
-    } else {
+      // Push copy of the function - found below the arguments.
+      __ push(Operand(rsp, (arg_count + 1) * kPointerSize));
+
+      // Push copy of the first argument or undefined if it doesn't exist.
+      if (arg_count > 0) {
+        __ push(Operand(rsp, arg_count * kPointerSize));
+      } else {
       __ PushRoot(Heap::kUndefinedValueRootIndex);
+      }
+
+      // Push the receiver of the enclosing function and do runtime call.
+      __ push(Operand(rbp, (2 + scope()->num_parameters()) * kPointerSize));
+      __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
+
+      // The runtime call returns a pair of values in rax (function) and
+      // rdx (receiver). Touch up the stack with the right values.
+      __ movq(Operand(rsp, (arg_count + 0) * kPointerSize), rdx);
+      __ movq(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
     }
-
-    // Push the receiver of the enclosing function and do runtime call.
-    __ push(Operand(rbp, (2 + scope()->num_parameters()) * kPointerSize));
-    __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 3);
-
-    // The runtime call returns a pair of values in rax (function) and
-    // rdx (receiver). Touch up the stack with the right values.
-    __ movq(Operand(rsp, (arg_count + 0) * kPointerSize), rdx);
-    __ movq(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
-
     // Record source position for debugger.
-    SetSourcePosition(expr->position());
+    SetSourcePosition(expr->position(), FORCED_POSITION);
     InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
     CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE);
     __ CallStub(&stub);
@@ -1823,35 +1841,37 @@
     // Call to a lookup slot (dynamically introduced variable).
     Label slow, done;
 
-    // Generate code for loading from variables potentially shadowed
-    // by eval-introduced variables.
-    EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
-                                    NOT_INSIDE_TYPEOF,
-                                    &slow,
-                                    &done);
+    { PreserveStatementPositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLoadFromSlotFastCase(var->AsSlot(),
+                                      NOT_INSIDE_TYPEOF,
+                                      &slow,
+                                      &done);
 
-    __ bind(&slow);
-    // Call the runtime to find the function to call (returned in rax)
-    // and the object holding it (returned in rdx).
-    __ push(context_register());
-    __ Push(var->name());
-    __ CallRuntime(Runtime::kLoadContextSlot, 2);
-    __ push(rax);  // Function.
-    __ push(rdx);  // Receiver.
+      __ bind(&slow);
+      // Call the runtime to find the function to call (returned in rax)
+      // and the object holding it (returned in rdx).
+      __ push(context_register());
+      __ Push(var->name());
+      __ CallRuntime(Runtime::kLoadContextSlot, 2);
+      __ push(rax);  // Function.
+      __ push(rdx);  // Receiver.
 
-    // If fast case code has been generated, emit code to push the
-    // function and receiver and have the slow path jump around this
-    // code.
-    if (done.is_linked()) {
-      NearLabel call;
-      __ jmp(&call);
-      __ bind(&done);
-      // Push function.
-      __ push(rax);
-      // Push global receiver.
-      __ movq(rbx, CodeGenerator::GlobalObject());
-      __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
-      __ bind(&call);
+      // If fast case code has been generated, emit code to push the
+      // function and receiver and have the slow path jump around this
+      // code.
+      if (done.is_linked()) {
+        NearLabel call;
+        __ jmp(&call);
+        __ bind(&done);
+        // Push function.
+        __ push(rax);
+        // Push global receiver.
+        __ movq(rbx, CodeGenerator::GlobalObject());
+        __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
+        __ bind(&call);
+      }
     }
 
     EmitCallWithStub(expr);
@@ -1862,18 +1882,24 @@
     Literal* key = prop->key()->AsLiteral();
     if (key != NULL && key->handle()->IsSymbol()) {
       // Call to a named property, use call IC.
-      VisitForStackValue(prop->obj());
+      { PreserveStatementPositionScope scope(masm()->positions_recorder());
+        VisitForStackValue(prop->obj());
+      }
       EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
     } else {
       // Call to a keyed property.
       // For a synthetic property use keyed load IC followed by function call,
       // for a regular property use KeyedCallIC.
-      VisitForStackValue(prop->obj());
+      { PreserveStatementPositionScope scope(masm()->positions_recorder());
+        VisitForStackValue(prop->obj());
+      }
       if (prop->is_synthetic()) {
-        VisitForAccumulatorValue(prop->key());
-        __ movq(rdx, Operand(rsp, 0));
+        { PreserveStatementPositionScope scope(masm()->positions_recorder());
+          VisitForAccumulatorValue(prop->key());
+          __ movq(rdx, Operand(rsp, 0));
+        }
         // Record source code position for IC call.
-        SetSourcePosition(prop->position());
+        SetSourcePosition(prop->position(), FORCED_POSITION);
         Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
         EmitCallIC(ic, RelocInfo::CODE_TARGET);
         // Pop receiver.
@@ -1898,7 +1924,9 @@
         loop_depth() == 0) {
       lit->set_try_full_codegen(true);
     }
-    VisitForStackValue(fun);
+    { PreserveStatementPositionScope scope(masm()->positions_recorder());
+      VisitForStackValue(fun);
+    }
     // Load global receiver object.
     __ movq(rbx, CodeGenerator::GlobalObject());
     __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 1d95b7f..9ec7814 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -33,7 +33,6 @@
 #include "ic-inl.h"
 #include "runtime.h"
 #include "stub-cache.h"
-#include "utils.h"
 
 namespace v8 {
 namespace internal {
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 3891e1d..24609bf 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -273,9 +273,11 @@
                               Register receiver,
                               Register name,
                               Register scratch,
-                              Register extra) {
+                              Register extra,
+                              Register extra2) {
   Label miss;
-  USE(extra);  // The register extra is not used on the X64 platform.
+  USE(extra);   // The register extra is not used on the X64 platform.
+  USE(extra2);  // The register extra2 is not used on the X64 platform.
   // Make sure that code is valid. The shifting code relies on the
   // entry size being 16.
   ASSERT(sizeof(Entry) == 16);
@@ -287,6 +289,10 @@
   ASSERT(!scratch.is(receiver));
   ASSERT(!scratch.is(name));
 
+  // Check scratch register is valid, extra and extra2 are unused.
+  ASSERT(!scratch.is(no_reg));
+  ASSERT(extra2.is(no_reg));
+
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(receiver, &miss);
 
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index d59e2f5..748e3e8 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -902,6 +902,7 @@
 // Debug event handler which re-issues a debug break until a limit has been
 // reached.
 int max_break_point_hit_count = 0;
+bool terminate_after_max_break_point_hit = false;
 static void DebugEventBreakMax(v8::DebugEvent event,
                                v8::Handle<v8::Object> exec_state,
                                v8::Handle<v8::Object> event_data,
@@ -909,12 +910,17 @@
   // When hitting a debug event listener there must be a break set.
   CHECK_NE(v8::internal::Debug::break_id(), 0);
 
-  if (event == v8::Break && break_point_hit_count < max_break_point_hit_count) {
-    // Count the number of breaks.
-    break_point_hit_count++;
+  if (event == v8::Break) {
+    if (break_point_hit_count < max_break_point_hit_count) {
+      // Count the number of breaks.
+      break_point_hit_count++;
 
-    // Set the break flag again to come back here as soon as possible.
-    v8::Debug::DebugBreak();
+      // Set the break flag again to come back here as soon as possible.
+      v8::Debug::DebugBreak();
+    } else if (terminate_after_max_break_point_hit) {
+      // Terminate execution after the last break if requested.
+      v8::V8::TerminateExecution();
+    }
   }
 }
 
@@ -6892,4 +6898,33 @@
   CheckDebuggerUnloaded();
 }
 
+
+// Test that setting the terminate execution flag during debug break processing.
+TEST(DebugBreakLoop) {
+  v8::HandleScope scope;
+  DebugLocalContext env;
+
+  // Receive 100 breaks and terminate.
+  max_break_point_hit_count = 100;
+  terminate_after_max_break_point_hit = true;
+
+  // Register a debug event listener which sets the break flag and counts.
+  v8::Debug::SetDebugEventListener(DebugEventBreakMax);
+
+  // Function with infinite loop.
+  CompileRun("function f() { while (true) { } }");
+
+  // Set the debug break to enter the debugger as soon as possible.
+  v8::Debug::DebugBreak();
+
+  // Call function with infinite loop.
+  CompileRun("f();");
+  CHECK_EQ(100, break_point_hit_count);
+
+  // Get rid of the debug event listener.
+  v8::Debug::SetDebugEventListener(NULL);
+  CheckDebuggerUnloaded();
+}
+
+
 #endif  // ENABLE_DEBUGGER_SUPPORT
diff --git a/test/cctest/test-lock.cc b/test/cctest/test-lock.cc
index 5eecfce..9039e02 100644
--- a/test/cctest/test-lock.cc
+++ b/test/cctest/test-lock.cc
@@ -60,4 +60,5 @@
   sem->Signal();
   ok = sem->Wait(1000);
   CHECK(ok);
+  delete sem;
 }
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 02503f2..7ae8dcf 100755
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -26,6 +26,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "v8.h"
 
@@ -34,7 +35,8 @@
 #include "parser.h"
 #include "utils.h"
 #include "execution.h"
-
+#include "scanner.h"
+#include "preparser.h"
 #include "cctest.h"
 
 namespace i = ::v8::internal;
@@ -239,3 +241,32 @@
   i::Vector<const char*> args = pre_impl->BuildArgs();
   CHECK_GT(strlen(message), 0);
 }
+
+
+TEST(StandAlonePreParser) {
+  int marker;
+  i::StackGuard::SetStackLimit(
+      reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+  const char* programs[] = {
+      "{label: 42}",
+      "var x = 42;",
+      "function foo(x, y) { return x + y; }",
+      "native function foo(); return %ArgleBargle(glop);",
+      "var x = new new Function('this.x = 42');",
+      NULL
+  };
+
+  for (int i = 0; programs[i]; i++) {
+    const char* program = programs[i];
+    unibrow::Utf8InputBuffer<256> stream(program, strlen(program));
+    i::CompleteParserRecorder log;
+    i::Scanner scanner;
+    scanner.Initialize(i::Handle<i::String>::null(), &stream, i::JAVASCRIPT);
+    v8::preparser::PreParser<i::Scanner, i::CompleteParserRecorder> preparser;
+    bool result = preparser.PreParseProgram(&scanner, &log, true);
+    CHECK(result);
+    i::ScriptDataImpl data(log.ExtractData());
+    CHECK(!data.has_error());
+  }
+}
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 11a808e..3e6709a 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -64,7 +64,7 @@
   ZoneScope zone_scope(DELETE_ON_EXIT);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData result;
-  return v8::internal::Parser::ParseRegExp(&reader, false, &result);
+  return v8::internal::RegExpParser::ParseRegExp(&reader, false, &result);
 }
 
 
@@ -74,7 +74,7 @@
   ZoneScope zone_scope(DELETE_ON_EXIT);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData result;
-  CHECK(v8::internal::Parser::ParseRegExp(&reader, false, &result));
+  CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
   CHECK(result.tree != NULL);
   CHECK(result.error.is_null());
   SmartPointer<const char> output = result.tree->ToString();
@@ -88,7 +88,7 @@
   ZoneScope zone_scope(DELETE_ON_EXIT);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData result;
-  CHECK(v8::internal::Parser::ParseRegExp(&reader, false, &result));
+  CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
   CHECK(result.tree != NULL);
   CHECK(result.error.is_null());
   return result.simple;
@@ -106,7 +106,7 @@
   ZoneScope zone_scope(DELETE_ON_EXIT);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData result;
-  CHECK(v8::internal::Parser::ParseRegExp(&reader, false, &result));
+  CHECK(v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
   CHECK(result.tree != NULL);
   CHECK(result.error.is_null());
   int min_match = result.tree->min_match();
@@ -365,7 +365,7 @@
   ZoneScope zone_scope(DELETE_ON_EXIT);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData result;
-  CHECK_EQ(false, v8::internal::Parser::ParseRegExp(&reader, false, &result));
+  CHECK(!v8::internal::RegExpParser::ParseRegExp(&reader, false, &result));
   CHECK(result.tree == NULL);
   CHECK(!result.error.is_null());
   SmartPointer<char> str = result.error->ToCString(ALLOW_NULLS);
@@ -473,7 +473,8 @@
   V8::Initialize(NULL);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData compile_data;
-  if (!v8::internal::Parser::ParseRegExp(&reader, multiline, &compile_data))
+  if (!v8::internal::RegExpParser::ParseRegExp(&reader, multiline,
+                                               &compile_data))
     return NULL;
   Handle<String> pattern = Factory::NewStringFromUtf8(CStrVector(input));
   RegExpEngine::Compile(&compile_data, false, multiline, pattern, is_ascii);
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index 6a513e5..1cbaf2b 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -216,6 +216,7 @@
   Vector<char> name = Vector<char>::New(file_name_length + 1);
   OS::SNPrintF(name, "%s.size", file_name_);
   FILE* fp = OS::FOpen(name.start(), "w");
+  name.Dispose();
   fprintf(fp, "new %d\n", new_space_used);
   fprintf(fp, "pointer %d\n", pointer_space_used);
   fprintf(fp, "data %d\n", data_space_used);
@@ -381,6 +382,7 @@
   env.Dispose();
 
   FileByteSink startup_sink(startup_name.start());
+  startup_name.Dispose();
   StartupSerializer startup_serializer(&startup_sink);
   startup_serializer.SerializeStrongReferences();
 
@@ -403,6 +405,7 @@
   Vector<char> name = Vector<char>::New(file_name_length + 1);
   OS::SNPrintF(name, "%s.size", file_name);
   FILE* fp = OS::FOpen(name.start(), "r");
+  name.Dispose();
   int new_size, pointer_size, data_size, code_size, map_size, cell_size;
   int large_size;
 #ifdef _MSC_VER
@@ -438,6 +441,7 @@
     OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
 
     CHECK(Snapshot::Initialize(startup_name.start()));
+    startup_name.Dispose();
 
     const char* file_name = FLAG_testing_serialization_file;
     ReserveSpaceForPartialSnapshot(file_name);
@@ -495,6 +499,7 @@
   env.Dispose();
 
   FileByteSink startup_sink(startup_name.start());
+  startup_name.Dispose();
   StartupSerializer startup_serializer(&startup_sink);
   startup_serializer.SerializeStrongReferences();
 
@@ -519,6 +524,7 @@
     OS::SNPrintF(startup_name, "%s.startup", FLAG_testing_serialization_file);
 
     CHECK(Snapshot::Initialize(startup_name.start()));
+    startup_name.Dispose();
 
     const char* file_name = FLAG_testing_serialization_file;
     ReserveSpaceForPartialSnapshot(file_name);
diff --git a/test/mjsunit/debug-compile-event.js b/test/mjsunit/debug-compile-event.js
index e7ecf47..b00a907 100644
--- a/test/mjsunit/debug-compile-event.js
+++ b/test/mjsunit/debug-compile-event.js
@@ -36,7 +36,6 @@
 var source_count = 0;  // Total number of scources compiled.
 var host_compilations = 0;  // Number of scources compiled through the API.
 var eval_compilations = 0;  // Number of scources compiled through eval.
-var json_compilations = 0;  // Number of scources compiled through JSON.parse.
 
 
 function compileSource(source) {
@@ -62,9 +61,6 @@
           case Debug.ScriptCompilationType.Eval:
             eval_compilations++;
             break;
-          case Debug.ScriptCompilationType.JSON:
-            json_compilations++;
-            break;
         }
       }
 
@@ -74,13 +70,6 @@
         // For source with 'eval' there will be compile events with substrings
         // as well as with with the exact source.
         assertTrue(current_source.indexOf(event_data.script().source()) >= 0);
-      } else if (current_source.indexOf('JSON.parse') == 0) {
-        // For JSON the JSON source will be in parentheses.
-        var s = event_data.script().source();
-        if (s[0] == '(') {
-          s = s.substring(1, s.length - 2);
-        }
-        assertTrue(current_source.indexOf(s) >= 0);
       } else {
         // For source without 'eval' there will be a compile events with the
         // exact source.
@@ -113,7 +102,7 @@
 compileSource('eval("eval(\'(function(){return a;})\')")');
 source_count += 2;  // Using eval causes additional compilation event.
 compileSource('JSON.parse(\'{"a":1,"b":2}\')');
-source_count++;  // Using JSON.parse causes additional compilation event.
+// Using JSON.parse does not causes additional compilation events.
 compileSource('x=1; //@ sourceURL=myscript.js');
 
 // Make sure that the debug event listener was invoked.
@@ -123,10 +112,9 @@
 assertEquals(before_compile_count, after_compile_count);
 
 // Check the actual number of events (no compilation through the API as all
-// source compiled through eval except for one JSON.parse call).
+// source compiled through eval).
 assertEquals(source_count, after_compile_count);
 assertEquals(0, host_compilations);
-assertEquals(source_count - 1, eval_compilations);
-assertEquals(1, json_compilations);
+assertEquals(source_count, eval_compilations);
 
 Debug.setListener(null);
diff --git a/test/mjsunit/mirror-script.js b/test/mjsunit/mirror-script.js
index 8631028..7156170 100644
--- a/test/mjsunit/mirror-script.js
+++ b/test/mjsunit/mirror-script.js
@@ -83,12 +83,10 @@
 
 
 // Test the script mirror for different functions.
-testScriptMirror(function(){}, 'mirror-script.js', 100, 2, 0);
+testScriptMirror(function(){}, 'mirror-script.js', 98, 2, 0);
 testScriptMirror(Math.sin, 'native math.js', -1, 0, 0);
 testScriptMirror(eval('(function(){})'), null, 1, 2, 1, '(function(){})', 87);
 testScriptMirror(eval('(function(){\n  })'), null, 2, 2, 1, '(function(){\n  })', 88);
-testScriptMirror(%CompileString('{"a":1,"b":2}', true), null, 1, 2, 2, '{"a":1,"b":2}');
-testScriptMirror(%CompileString('{"a":1,\n  "b":2}', true), null, 2, 2, 2, '{"a":1,\n  "b":2}');
 
 // Test taking slices of source.
 var mirror = debug.MakeMirror(eval('(function(){\n  1;\n})')).script();
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 3c8cbdb..820dca7 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -45,6 +45,10 @@
 # Skip long running test in debug and allow it to timeout in release mode.
 regress/regress-524: (PASS || TIMEOUT), SKIP if $mode == debug
 
+# Stack manipulations in LiveEdit are buggy - see bug 915
+debug-liveedit-check-stack: SKIP
+debug-liveedit-patch-positions-replace: SKIP
+
 [ $arch == arm ]
 
 # Slow tests which times out in debug mode.
@@ -61,14 +65,9 @@
 # Skip long running test in debug mode on ARM.
 string-indexof-2: PASS, SKIP if $mode == debug
 
-# Stack manipulations in LiveEdit is implemented for ia32 only.
-debug-liveedit-check-stack: SKIP
 
 [ $arch == mips ]
 
-# Stack manipulations in LiveEdit is implemented for ia32 only.
-debug-liveedit-check-stack: SKIP
-
 # Skip all tests on MIPS.
 *: SKIP
 
diff --git a/test/mjsunit/object-literal-conversions.js b/test/mjsunit/object-literal-conversions.js
new file mode 100644
index 0000000..8540d93
--- /dev/null
+++ b/test/mjsunit/object-literal-conversions.js
@@ -0,0 +1,46 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that the various conversions between property names are correctly
+// used when overwriting initializers.
+
+var test1 = { 13: 6, "13": 7 };
+var test2 = { 13: 7, "13.0": 6 };
+var test3 = { "13": 6, 13.0000000000000000: 7 };
+var test4 = { 13.213000: 6, "13.213": 7 };
+
+assertEquals(7, test1[13]);
+assertEquals(7, test2[13]);
+assertEquals(7, test3[13]);
+assertEquals(7, test4[13.213]);
+
+var test5 = { 13: function() {}, "13": 7 };
+var test6 = { 17.31: function() {}, "17.31": 7 };
+
+assertEquals(7, test5[13]);
+assertEquals(7, test6[17.31]);
+  
\ No newline at end of file
diff --git a/test/mjsunit/object-literal-overwrite.js b/test/mjsunit/object-literal-overwrite.js
new file mode 100644
index 0000000..5c58a2d
--- /dev/null
+++ b/test/mjsunit/object-literal-overwrite.js
@@ -0,0 +1,118 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that constants and computed properties are overwriting each other
+// correctly, i.e., the last initializer for any name is stored in the object.
+
+
+// Tests for the full code generator (if active).
+
+var foo1 = {
+  bar: 6,
+  bar: 7
+};
+
+var foo2 = {
+  bar: function(a){},
+  bar: 7
+};
+
+var foo3 = {
+  bar: function(a){},
+  bar: function(b){},
+  bar: 7
+};
+
+var foo4 = {
+  bar: function(b){},
+  bar: 7,
+  bar: function(){return 7},
+};
+
+var foo5 = {
+  13: function(a){},
+  13: 7
+}
+
+var foo6 = {
+  14.31: function(a){},
+  14.31: 7
+}
+
+var foo7 = {
+  15: 6,
+  15: 7
+}
+
+assertEquals(7, foo1.bar);
+assertEquals(7, foo2.bar);
+assertEquals(7, foo3.bar);
+assertEquals(7, foo4.bar());
+assertEquals(7, foo5[13]);
+assertEquals(7, foo6[14.31]);
+assertEquals(7, foo7[15]);
+
+// Test for the classic code generator.
+
+function fun(x) {
+  var inner = { j: function(x) { return x; }, j: 7 }; 
+  return inner.j;
+}
+
+assertEquals(7, fun(7) );
+
+// Check that the initializers of computed properties are executed, even if
+// no store instructions are generated for the literals.
+
+var glob1 = 0;
+
+var bar1 = { x: glob1++, x: glob1++, x: glob1++, x: 7};
+
+assertEquals(3, glob1);
+
+
+var glob2 = 0;
+
+function fun2() {
+  var r = { y: glob2++, y: glob2++, y: glob2++, y: 7};
+  return r.y;
+}
+
+var y = fun2();
+assertEquals(7, y);
+assertEquals(3, glob2);
+
+var glob3 = 0;
+
+function fun3() {
+  var r = { 113: glob3++, 113: glob3++, 113: glob3++, 113: 7};
+  return r[113];
+}
+
+var y = fun3();
+assertEquals(7, y);
+assertEquals(3, glob3);
\ No newline at end of file
diff --git a/test/mjsunit/regress/regress-conditional-position.js b/test/mjsunit/regress/regress-conditional-position.js
new file mode 100644
index 0000000..cd8f7bd
--- /dev/null
+++ b/test/mjsunit/regress/regress-conditional-position.js
@@ -0,0 +1,95 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --always-full-compiler
+
+var functionToCatch;
+var lineNumber;
+
+function catchLineNumber () {
+  var x = {};
+
+  Error.prepareStackTrace = function (error, stackTrace) {
+    stackTrace.some(function (frame) {
+      if (frame.getFunction() == functionToCatch) {
+        lineNumber = frame.getLineNumber();
+        return true;
+      }
+      return false;
+    });
+    return lineNumber;
+  };
+
+  Error.captureStackTrace(x);
+  return x.stack;
+}
+
+function log() {
+  catchLineNumber();
+}
+
+function foo() {}
+
+function test1() {
+  log(foo() == foo()
+      ? 'a'
+      : 'b');
+}
+
+function test2() {
+  var o = { foo: function () {}}
+  log(o.foo() == o.foo()
+      ? 'a'
+      : 'b');
+}
+
+function test3() {
+  var o = { log: log, foo: function() { } };
+  o.log(o.foo() == o.foo()
+      ? 'a'
+      : 'b');
+
+}
+
+function test(f, expectedLineNumber) {
+  functionToCatch = f;
+  f();
+
+  assertEquals(expectedLineNumber, lineNumber);
+}
+
+test(test1, 58);
+test(test2, 65);
+test(test3, 72);
+
+eval(test1.toString() + "//@ sourceUrl=foo");
+eval(test2.toString() + "//@ sourceUrl=foo");
+eval(test3.toString() + "//@ sourceUrl=foo");
+
+test(test1, 2);
+test(test2, 3);
+test(test3, 3);
diff --git a/test/mjsunit/string-externalize.js b/test/mjsunit/string-externalize.js
index 5b1f917..da89786 100644
--- a/test/mjsunit/string-externalize.js
+++ b/test/mjsunit/string-externalize.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --expose-externalize-string
+// Flags: --expose-externalize-string --expose-gc
 
 var size = 1024;
 
@@ -93,3 +93,7 @@
 for (var i = 0; i < 10; i++) {
   test();
 }
+
+// Clean up string to make Valgrind happy.
+gc();
+gc();
diff --git a/test/mjsunit/string-replace-with-empty.js b/test/mjsunit/string-replace-with-empty.js
index 0e1e70a..aa97f27 100644
--- a/test/mjsunit/string-replace-with-empty.js
+++ b/test/mjsunit/string-replace-with-empty.js
@@ -25,33 +25,45 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --expose-externalize-string
+// Flags: --expose-externalize-string --expose-gc
 
-assertEquals("0123", "aa0bb1cc2dd3".replace(/[a-z]/g, ""));
-assertEquals("0123", "\u1234a0bb1cc2dd3".replace(/[\u1234a-z]/g, ""));
+function test() {
+  assertEquals("0123", "aa0bb1cc2dd3".replace(/[a-z]/g, ""));
+  assertEquals("0123", "\u1234a0bb1cc2dd3".replace(/[\u1234a-z]/g, ""));
 
-var expected = "0123";
-var cons = "a0b1c2d3";
-for (var i = 0; i < 5; i++) {
-  expected += expected;
-  cons += cons;
-}
-assertEquals(expected, cons.replace(/[a-z]/g, ""));
-cons = "\u12340b1c2d3";
-for (var i = 0; i < 5; i++) {
-  cons += cons;
-}
-assertEquals(expected, cons.replace(/[\u1234a-z]/g, ""));
+  var expected = "0123";
+  var cons = "a0b1c2d3";
+  for (var i = 0; i < 5; i++) {
+    expected += expected;
+    cons += cons;
+  }
+  assertEquals(expected, cons.replace(/[a-z]/g, ""));
+  cons = "\u12340b1c2d3";
+  for (var i = 0; i < 5; i++) {
+    cons += cons;
+  }
+  assertEquals(expected, cons.replace(/[\u1234a-z]/g, ""));
 
-cons = "a0b1c2d3";
-for (var i = 0; i < 5; i++) {
-  cons += cons;
+  cons = "a0b1c2d3";
+  for (var i = 0; i < 5; i++) {
+    cons += cons;
+  }
+  externalizeString(cons, true/* force two-byte */);
+  assertEquals(expected, cons.replace(/[a-z]/g, ""));
+  cons = "\u12340b1c2d3";
+  for (var i = 0; i < 5; i++) {
+    cons += cons;
+  }
+  externalizeString(cons);
+  assertEquals(expected, cons.replace(/[\u1234a-z]/g, ""));
 }
-externalizeString(cons, true/* force two-byte */);
-assertEquals(expected, cons.replace(/[a-z]/g, ""));
-cons = "\u12340b1c2d3";
-for (var i = 0; i < 5; i++) {
-  cons += cons;
-}
-externalizeString(cons);
-assertEquals(expected, cons.replace(/[\u1234a-z]/g, ""));
+
+test();
+
+// Clear the regexp cache to allow the GC to work.
+"foo".replace(/foo/g, "");
+
+// GC in order to free up things on the C side so we don't get
+// a memory leak.  This makes valgrind happy.
+gc();
+gc();
diff --git a/test/mjsunit/string-split.js b/test/mjsunit/string-split.js
index 59d3ad3..c741f6a 100644
--- a/test/mjsunit/string-split.js
+++ b/test/mjsunit/string-split.js
@@ -27,76 +27,45 @@
 
 expected = ["A", undefined, "B", "bold", "/", "B", "and", undefined, "CODE", "coded", "/", "CODE", ""];
 result = "A<B>bold</B>and<CODE>coded</CODE>".split(/<(\/)?([^<>]+)>/);
-assertArrayEquals(expected, result, 1);
+assertArrayEquals(expected, result);
 
-expected = ["a", "b"];
-result = "ab".split(/a*?/);
-assertArrayEquals(expected, result, 2);
 
-expected = ["", "b"];
-result = "ab".split(/a*/);
-assertArrayEquals(expected, result, 3);
+assertArrayEquals(["a", "b"], "ab".split(/a*?/));
 
-expected = ["a"];
-result = "ab".split(/a*?/, 1);
-assertArrayEquals(expected, result, 4);
+assertArrayEquals(["", "b"], "ab".split(/a*/));
 
-expected = [""];
-result = "ab".split(/a*/, 1);
-assertArrayEquals(expected, result, 5);
+assertArrayEquals(["a"], "ab".split(/a*?/, 1));
 
-expected = ["as","fas","fas","f"];
-result = "asdfasdfasdf".split("d");
-assertArrayEquals(expected, result, 6);
+assertArrayEquals([""], "ab".split(/a*/, 1));
 
-expected = ["as","fas","fas","f"];
-result = "asdfasdfasdf".split("d", -1);
-assertArrayEquals(expected, result, 7);
+assertArrayEquals(["as","fas","fas","f"], "asdfasdfasdf".split("d"));
 
-expected = ["as", "fas"];
-result = "asdfasdfasdf".split("d", 2);
-assertArrayEquals(expected, result, 8);
+assertArrayEquals(["as","fas","fas","f"], "asdfasdfasdf".split("d", -1));
 
-expected = [];
-result = "asdfasdfasdf".split("d", 0);
-assertArrayEquals(expected, result, 9);
+assertArrayEquals(["as", "fas"], "asdfasdfasdf".split("d", 2));
 
-expected = ["as","fas","fas",""];
-result = "asdfasdfasd".split("d");
-assertArrayEquals(expected, result, 10);
+assertArrayEquals([], "asdfasdfasdf".split("d", 0));
 
-expected = [];
-result = "".split("");
-assertArrayEquals(expected, result, 11);
+assertArrayEquals(["as","fas","fas",""], "asdfasdfasd".split("d"));
 
-expected = [""]
-result = "".split("a");
-assertArrayEquals(expected, result, 12);
+assertArrayEquals([], "".split(""));
 
-expected = ["a","b"]
-result = "axxb".split(/x*/);
-assertArrayEquals(expected, result, 13);
+assertArrayEquals([""], "".split("a"));
 
-expected = ["a","b"]
-result = "axxb".split(/x+/);
-assertArrayEquals(expected, result, 14);
+assertArrayEquals(["a","b"], "axxb".split(/x*/));
 
-expected = ["a","","b"]
-result = "axxb".split(/x/);
-assertArrayEquals(expected, result, 15);
+assertArrayEquals(["a","b"], "axxb".split(/x+/));
+
+assertArrayEquals(["a","","b"], "axxb".split(/x/));
 
 // This was http://b/issue?id=1151354
-expected = ["div", "#id", ".class"]
-result = "div#id.class".split(/(?=[#.])/);
-assertArrayEquals(expected, result, 16);
+assertArrayEquals(["div", "#id", ".class"], "div#id.class".split(/(?=[#.])/));
 
-expected = ["div", "#i", "d", ".class"]
-result = "div#id.class".split(/(?=[d#.])/);
-assertArrayEquals(expected, result, 17);
 
-expected = ["a", "b", "c"]
-result = "abc".split(/(?=.)/);
-assertArrayEquals(expected, result, 18);
+assertArrayEquals(["div", "#i", "d", ".class"], "div#id.class".split(/(?=[d#.])/));
+
+assertArrayEquals(["a", "b", "c"], "abc".split(/(?=.)/));
+
 
 /* "ab".split(/((?=.))/)
  * 
@@ -108,19 +77,23 @@
  * 
  * Opera seems to have this right.  The others make no sense.
  */
-expected = ["a", "", "b"]
-result = "ab".split(/((?=.))/);
-assertArrayEquals(expected, result, 19);
+assertArrayEquals(["a", "", "b"], "ab".split(/((?=.))/));
 
 /* "ab".split(/(?=)/)
  *
  * KJS:   a,b
  * SM:    ab
  * IE:    a,b
- * Opera: a,b
+ * Opera: a,bb
  * V8:    a,b
  */
-expected = ["a", "b"]
-result = "ab".split(/(?=)/);
-assertArrayEquals(expected, result, 20);
+assertArrayEquals(["a", "b"], "ab".split(/(?=)/));
 
+
+// For issue http://code.google.com/p/v8/issues/detail?id=924
+// Splitting the empty string is a special case.
+assertEquals([""], ''.split());
+assertEquals([""], ''.split(/./));
+assertEquals([], ''.split(/.?/));
+assertEquals([], ''.split(/.??/));
+assertEquals([], ''.split(/()()/));
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 17d556f..3e40fcc 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -426,6 +426,8 @@
         '../../src/rewriter.h',
         '../../src/runtime.cc',
         '../../src/runtime.h',
+        '../../src/scanner-base.cc',
+        '../../src/scanner-base.h',
         '../../src/scanner.cc',
         '../../src/scanner.h',
         '../../src/scopeinfo.cc',
diff --git a/tools/ll_prof.py b/tools/ll_prof.py
index 563084d..8390d4a 100755
--- a/tools/ll_prof.py
+++ b/tools/ll_prof.py
@@ -353,7 +353,7 @@
     r"code-info,([^,]+),(\d+)")
 
   _CODE_CREATE_RE = re.compile(
-    r"code-creation,([^,]+),(0x[a-f0-9]+),(\d+),\"([^\"]*)\"(?:,(\d+))?")
+    r"code-creation,([^,]+),(0x[a-f0-9]+),(\d+),\"(.*)\"(?:,(\d+))?")
 
   _CODE_MOVE_RE = re.compile(
     r"code-move,(0x[a-f0-9]+),(0x[a-f0-9]+)")
@@ -910,7 +910,7 @@
       start = time.time()
       mmap_info = trace_reader.ReadMmap(header, offset)
       if mmap_info.filename == V8_GC_FAKE_MMAP:
-        log_reader.ReadUpToGC()
+        log_reader.ReadUpToGC(code_info)
       else:
         library_repo.Load(mmap_info, code_map, options)
       mmap_time += time.time() - start
diff --git a/tools/presubmit.py b/tools/presubmit.py
index e69c9a8..ebf8bd8 100755
--- a/tools/presubmit.py
+++ b/tools/presubmit.py
@@ -195,7 +195,7 @@
               or (name in CppLintProcessor.IGNORE_LINT))
 
   def GetPathsToSearch(self):
-    return ['src', 'public', 'samples', join('test', 'cctest')]
+    return ['src', 'include', 'samples', join('test', 'cctest')]
 
   def ProcessFiles(self, files, path):
     good_files_cache = FileContentsCache('.cpplint-cache')
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index 08558cc..5f93c78 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -115,6 +115,7 @@
 		89A88E180E71A6960043BA31 /* property.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16D0E719B8F00D62E90 /* property.cc */; };
 		89A88E190E71A6970043BA31 /* rewriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16F0E719B8F00D62E90 /* rewriter.cc */; };
 		89A88E1A0E71A69B0043BA31 /* runtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1710E719B8F00D62E90 /* runtime.cc */; };
+		89A88E1B0E71A69D0043BA31 /* scanner-base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner-base.cc */; };
 		89A88E1B0E71A69D0043BA31 /* scanner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner.cc */; };
 		89A88E1C0E71A69E0043BA31 /* scopeinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1760E719B8F00D62E90 /* scopeinfo.cc */; };
 		89A88E1D0E71A6A00043BA31 /* scopes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1780E719B8F00D62E90 /* scopes.cc */; };
@@ -177,6 +178,7 @@
 		89F23C6C0E78D5B2006B2466 /* property.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16D0E719B8F00D62E90 /* property.cc */; };
 		89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF16F0E719B8F00D62E90 /* rewriter.cc */; };
 		89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1710E719B8F00D62E90 /* runtime.cc */; };
+		89F23C6F0E78D5B2006B2466 /* scanner-base.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner-base.cc */; };
 		89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1730E719B8F00D62E90 /* scanner.cc */; };
 		89F23C700E78D5B2006B2466 /* scopeinfo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1760E719B8F00D62E90 /* scopeinfo.cc */; };
 		89F23C710E78D5B2006B2466 /* scopes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1780E719B8F00D62E90 /* scopes.cc */; };
@@ -481,6 +483,8 @@
 		897FF1700E719B8F00D62E90 /* rewriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rewriter.h; sourceTree = "<group>"; };
 		897FF1710E719B8F00D62E90 /* runtime.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = runtime.cc; sourceTree = "<group>"; };
 		897FF1720E719B8F00D62E90 /* runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = runtime.h; sourceTree = "<group>"; };
+		897FF1730E719B8F00D62E90 /* scanner-base.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scanner-base.cc; sourceTree = "<group>"; };
+		897FF1740E719B8F00D62E90 /* scanner-base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scanner-base.h; sourceTree = "<group>"; };
 		897FF1730E719B8F00D62E90 /* scanner.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scanner.cc; sourceTree = "<group>"; };
 		897FF1740E719B8F00D62E90 /* scanner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scanner.h; sourceTree = "<group>"; };
 		897FF1750E719B8F00D62E90 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
@@ -943,6 +947,8 @@
 				897FF1700E719B8F00D62E90 /* rewriter.h */,
 				897FF1710E719B8F00D62E90 /* runtime.cc */,
 				897FF1720E719B8F00D62E90 /* runtime.h */,
+				897FF1730E719B8F00D62E90 /* scanner-base.cc */,
+				897FF1740E719B8F00D62E90 /* scanner-base.h */,
 				897FF1730E719B8F00D62E90 /* scanner.cc */,
 				897FF1740E719B8F00D62E90 /* scanner.h */,
 				897FF1760E719B8F00D62E90 /* scopeinfo.cc */,
@@ -1348,6 +1354,7 @@
 				58950D630F5551AF00F3E8BA /* register-allocator.cc in Sources */,
 				89A88E190E71A6970043BA31 /* rewriter.cc in Sources */,
 				89A88E1A0E71A69B0043BA31 /* runtime.cc in Sources */,
+				89A88E1B0E71A69D0043BA31 /* scanner-base.cc in Sources */,
 				89A88E1B0E71A69D0043BA31 /* scanner.cc in Sources */,
 				89A88E1C0E71A69E0043BA31 /* scopeinfo.cc in Sources */,
 				89A88E1D0E71A6A00043BA31 /* scopes.cc in Sources */,
@@ -1472,6 +1479,7 @@
 				58950D640F5551B500F3E8BA /* register-allocator.cc in Sources */,
 				89F23C6D0E78D5B2006B2466 /* rewriter.cc in Sources */,
 				89F23C6E0E78D5B2006B2466 /* runtime.cc in Sources */,
+				89F23C6F0E78D5B2006B2466 /* scanner-base.cc in Sources */,
 				89F23C6F0E78D5B2006B2466 /* scanner.cc in Sources */,
 				89F23C700E78D5B2006B2466 /* scopeinfo.cc in Sources */,
 				89F23C710E78D5B2006B2466 /* scopes.cc in Sources */,
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
index 62d4501..bddf38e 100644
--- a/tools/visual_studio/v8_base.vcproj
+++ b/tools/visual_studio/v8_base.vcproj
@@ -882,6 +882,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\scanner-base.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\scanner-base.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\scanner.cc"
 				>
 			</File>