Update V8 to r5675 as required by WebKit r70209

Change-Id: Ib10adb470d41ca8c109ead5fc893b880e18d489f
diff --git a/AUTHORS b/AUTHORS
index 2403fbb..3749ceb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,6 +6,7 @@
 Google Inc.
 Sigma Designs Inc.
 ARM Ltd.
+Hewlett-Packard Development Company, LP
 
 Alexander Botero-Lowry <alexbl@FreeBSD.org>
 Alexandre Vassalotti <avassalotti@gmail.com>
diff --git a/Android.v8common.mk b/Android.v8common.mk
index 113eec4..59ea39d 100644
--- a/Android.v8common.mk
+++ b/Android.v8common.mk
@@ -8,6 +8,7 @@
 	src/ast.cc \
 	src/bootstrapper.cc \
 	src/builtins.cc \
+	src/cached-powers.cc \
 	src/checks.cc \
 	src/code-stubs.cc \
 	src/codegen.cc \
@@ -65,7 +66,9 @@
 	src/serialize.cc \
 	src/snapshot-common.cc \
 	src/spaces.cc \
+	src/string-search.cc \
 	src/string-stream.cc \
+	src/strtod.cc \
 	src/stub-cache.cc \
 	src/token.cc \
 	src/top.cc \
diff --git a/ChangeLog b/ChangeLog
index 66fb731..36ed4fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,65 @@
+2010-10-20: Version 2.5.1
+
+        Fixed bug causing spurious out of memory exceptions
+        (issue http://crbug.com/54580).
+
+        Fixed compilation error on Solaris platform (issue 901).
+
+        Fixed error in strtod (string to floating point number conversion)
+        due to glibc's use of 80-bit floats in the FPU on 32-bit linux.
+
+        Adjusted randomized allocations of executable memory to have 64k
+        granularity (issue http://crbug.com/56036).
+
+        Supported profiling using kernel perf_events on linux.  Added ll_prof
+        script to tools and --ll-prof flag to V8.
+
+
+2010-10-18: Version 2.5.0
+
+        Fixed bug in cache handling of lastIndex on global regexps
+        (issue http://crbug.com/58740).
+
+        Added USE_SIMULATOR macro that explicitly indicates that we wish to use
+        the simulator as the execution engine (by Mark Lam <mark.lam@palm.com>
+	from Hewlett-Packard Development Company, LP).
+
+        Fixed compilation error on ARM with gcc 4.4 (issue 894).
+
+
+2010-10-13: Version 2.4.9
+
+        Fixed a bug in the handling of conditional expressions in test
+        contexts in compiler for top-level code.
+
+        Added "//@ sourceURL" information to the StackTrace API.
+
+        Exposed RegExp construction through the API.
+
+
+2010-10-04: Version 2.4.8
+
+        Fixed a bug in ResumeProfilerEx causing it to not always write out the
+        whole snapshot (issue 868).
+
+        Performance improvements on all platforms.
+
+
+2010-09-30: Version 2.4.7
+
+        Changed the command-line flag --max-new-space-size to be in kB and the
+        flag --max-old-space-size to be in MB (previously they were in bytes).
+
+        Added Debug::CancelDebugBreak to the debugger API.
+
+        Fixed a bug in getters for negative numeric property names
+        (https://bugs.webkit.org/show_bug.cgi?id=46689).
+
+        Performance improvements on all platforms.
+
+
 2010-09-27: Version 2.4.6
+
         Fixed assertion failure related to copy-on-write arrays (issue 876).
 
         Fixed build failure of 64-bit V8 on Windows.
@@ -12,6 +73,7 @@
 
 
 2010-09-22: Version 2.4.5
+
         Changed the RegExp benchmark to exercise the regexp engine on different
         inputs by scrambling the input strings.
 
diff --git a/SConstruct b/SConstruct
index 2a39583..a36a96f 100644
--- a/SConstruct
+++ b/SConstruct
@@ -206,7 +206,8 @@
     },
     'simulator:arm': {
       'CCFLAGS':      ['-m32'],
-      'LINKFLAGS':    ['-m32']
+      'LINKFLAGS':    ['-m32'],
+      'CPPDEFINES':   ['USE_SIMULATOR']
     },
     'arch:mips': {
       'CPPDEFINES':   ['V8_TARGET_ARCH_MIPS'],
@@ -217,7 +218,8 @@
     },
     'simulator:mips': {
       'CCFLAGS':      ['-m32'],
-      'LINKFLAGS':    ['-m32']
+      'LINKFLAGS':    ['-m32'],
+      'CPPDEFINES':   ['USE_SIMULATOR']
     },
     'arch:x64': {
       'CPPDEFINES':   ['V8_TARGET_ARCH_X64'],
@@ -663,17 +665,17 @@
   'toolchain': {
     'values': ['gcc', 'msvc'],
     'default': TOOLCHAIN_GUESS,
-    'help': 'the toolchain to use (' + TOOLCHAIN_GUESS + ')'
+    'help': 'the toolchain to use (%s)' % TOOLCHAIN_GUESS
   },
   'os': {
     'values': ['freebsd', 'linux', 'macos', 'win32', 'android', 'openbsd', 'solaris'],
     'default': OS_GUESS,
-    'help': 'the os to build for (' + OS_GUESS + ')'
+    'help': 'the os to build for (%s)' % OS_GUESS
   },
   'arch': {
     'values':['arm', 'ia32', 'x64', 'mips'],
     'default': ARCH_GUESS,
-    'help': 'the architecture to build for (' + ARCH_GUESS + ')'
+    'help': 'the architecture to build for (%s)' % ARCH_GUESS
   },
   'regexp': {
     'values': ['native', 'interpreted'],
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index 99a8a43..ef76b1b 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/7.0.540.0/DEPS
-http://v8.googlecode.com/svn/trunk@5532
+http://src.chromium.org/svn/releases/8.0.561.0/DEPS
+http://v8.googlecode.com/svn/trunk@5675
diff --git a/benchmarks/base.js b/benchmarks/base.js
index 0388da6..ffabf24 100644
--- a/benchmarks/base.js
+++ b/benchmarks/base.js
@@ -78,7 +78,7 @@
 // Scores are not comparable across versions. Bump the version if
 // you're making changes that will affect that scores, e.g. if you add
 // a new benchmark or change an existing one.
-BenchmarkSuite.version = '6 (candidate)';
+BenchmarkSuite.version = '6';
 
 
 // To make the benchmark results predictable, we replace Math.random
diff --git a/include/v8-debug.h b/include/v8-debug.h
old mode 100644
new mode 100755
index 414fd86..4314727
--- a/include/v8-debug.h
+++ b/include/v8-debug.h
@@ -253,9 +253,12 @@
   static bool SetDebugEventListener(v8::Handle<v8::Object> that,
                                     Handle<Value> data = Handle<Value>());
 
-  // Break execution of JavaScript.
+  // Schedule a debugger break to happen when JavaScript code is run.
   static void DebugBreak();
 
+  // Remove scheduled debugger break if it has not happened yet.
+  static void CancelDebugBreak();
+
   // Break execution of JavaScript (this method can be invoked from a
   // non-VM thread) for further client command execution on a VM
   // thread. Client data is then passed in EventDetails to
diff --git a/include/v8-profiler.h b/include/v8-profiler.h
index 27da418..fb492d9 100644
--- a/include/v8-profiler.h
+++ b/include/v8-profiler.h
@@ -245,7 +245,9 @@
     kString = 2,     // A string.
     kObject = 3,     // A JS object (except for arrays and strings).
     kCode = 4,       // Compiled code.
-    kClosure = 5     // Function closure.
+    kClosure = 5,    // Function closure.
+    kRegExp = 6,     // RegExp.
+    kHeapNumber = 7  // Number stored in the heap.
   };
 
   /** Returns node type (see HeapGraphNode::Type). */
diff --git a/include/v8.h b/include/v8.h
index 0613d58..ef9a411 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -758,8 +758,9 @@
     kFunctionName = 1 << 3,
     kIsEval = 1 << 4,
     kIsConstructor = 1 << 5,
+    kScriptNameOrSourceURL = 1 << 6,
     kOverview = kLineNumber | kColumnOffset | kScriptName | kFunctionName,
-    kDetailed = kOverview | kIsEval | kIsConstructor
+    kDetailed = kOverview | kIsEval | kIsConstructor | kScriptNameOrSourceURL
   };
 
   /**
@@ -819,6 +820,13 @@
   Local<String> GetScriptName() const;
 
   /**
+   * Returns the name of the resource that contains the script for the
+   * function for this StackFrame or sourceURL value if the script name
+   * is undefined and its source ends with //@ sourceURL=... string.
+   */
+  Local<String> GetScriptNameOrSourceURL() const;
+
+  /**
    * Returns the name of the function associated with this stack frame.
    */
   Local<String> GetFunctionName() const;
@@ -1359,6 +1367,53 @@
 };
 
 
+/**
+ * An instance of the built-in RegExp constructor (ECMA-262, 15.10).
+ */
+class RegExp : public Value {
+ public:
+  /**
+   * Regular expression flag bits. They can be or'ed to enable a set
+   * of flags.
+   */
+  enum Flags {
+    kNone = 0,
+    kGlobal = 1,
+    kIgnoreCase = 2,
+    kMultiline = 4
+  };
+
+  /**
+   * Creates a regular expression from the given pattern string and
+   * the flags bit field. May throw a JavaScript exception as
+   * described in ECMA-262, 15.10.4.1.
+   *
+   * For example,
+   *   RegExp::New(v8::String::New("foo"),
+   *               static_cast<RegExp::Flags>(kGlobal | kMultiline))
+   * is equivalent to evaluating "/foo/gm".
+   */
+  V8EXPORT static Local<RegExp> New(Handle<String> pattern,
+                                    Flags flags);
+
+  /**
+   * Returns the value of the source property: a string representing
+   * the regular expression.
+   */
+  V8EXPORT Local<String> GetSource() const;
+
+  /**
+   * Returns the flags bit field.
+   */
+  V8EXPORT Flags GetFlags() const;
+
+  static inline RegExp* Cast(v8::Value* obj);
+
+ private:
+  V8EXPORT static void CheckCast(v8::Value* obj);
+};
+
+
 enum PropertyAttribute {
   None       = 0,
   ReadOnly   = 1 << 0,
@@ -3617,6 +3672,14 @@
 }
 
 
+RegExp* RegExp::Cast(v8::Value* value) {
+#ifdef V8_ENABLE_CHECKS
+  CheckCast(value);
+#endif
+  return static_cast<RegExp*>(value);
+}
+
+
 Object* Object::Cast(v8::Value* value) {
 #ifdef V8_ENABLE_CHECKS
   CheckCast(value);
diff --git a/src/SConscript b/src/SConscript
index 7fae8d4..8995d48 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -42,6 +42,7 @@
     ast.cc
     bootstrapper.cc
     builtins.cc
+    cached-powers.cc
     checks.cc
     circular-queue.cc
     code-stubs.cc
@@ -100,7 +101,9 @@
     serialize.cc
     snapshot-common.cc
     spaces.cc
+    string-search.cc
     string-stream.cc
+    strtod.cc
     stub-cache.cc
     token.cc
     top.cc
@@ -113,7 +116,6 @@
     variables.cc
     version.cc
     virtual-frame.cc
-    vm-state.cc
     zone.cc
     """),
   'arch:arm': Split("""
diff --git a/src/api.cc b/src/api.cc
index 5f480c9..962723d 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -28,6 +28,7 @@
 #include "v8.h"
 
 #include "api.h"
+
 #include "arguments.h"
 #include "bootstrapper.h"
 #include "compiler.h"
@@ -36,6 +37,7 @@
 #include "global-handles.h"
 #include "heap-profiler.h"
 #include "messages.h"
+#include "parser.h"
 #include "platform.h"
 #include "profile-generator-inl.h"
 #include "serialize.h"
@@ -134,27 +136,27 @@
   heap_stats.new_space_size = &new_space_size;
   int new_space_capacity;
   heap_stats.new_space_capacity = &new_space_capacity;
-  int old_pointer_space_size;
+  intptr_t old_pointer_space_size;
   heap_stats.old_pointer_space_size = &old_pointer_space_size;
-  int old_pointer_space_capacity;
+  intptr_t old_pointer_space_capacity;
   heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
-  int old_data_space_size;
+  intptr_t old_data_space_size;
   heap_stats.old_data_space_size = &old_data_space_size;
-  int old_data_space_capacity;
+  intptr_t old_data_space_capacity;
   heap_stats.old_data_space_capacity = &old_data_space_capacity;
-  int code_space_size;
+  intptr_t code_space_size;
   heap_stats.code_space_size = &code_space_size;
-  int code_space_capacity;
+  intptr_t code_space_capacity;
   heap_stats.code_space_capacity = &code_space_capacity;
-  int map_space_size;
+  intptr_t map_space_size;
   heap_stats.map_space_size = &map_space_size;
-  int map_space_capacity;
+  intptr_t map_space_capacity;
   heap_stats.map_space_capacity = &map_space_capacity;
-  int cell_space_size;
+  intptr_t cell_space_size;
   heap_stats.cell_space_size = &cell_space_size;
-  int cell_space_capacity;
+  intptr_t cell_space_capacity;
   heap_stats.cell_space_capacity = &cell_space_capacity;
-  int lo_space_size;
+  intptr_t lo_space_size;
   heap_stats.lo_space_size = &lo_space_size;
   int global_handle_count;
   heap_stats.global_handle_count = &global_handle_count;
@@ -166,9 +168,9 @@
   heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
   int destroyed_global_handle_count;
   heap_stats.destroyed_global_handle_count = &destroyed_global_handle_count;
-  int memory_allocator_size;
+  intptr_t memory_allocator_size;
   heap_stats.memory_allocator_size = &memory_allocator_size;
-  int memory_allocator_capacity;
+  intptr_t memory_allocator_capacity;
   heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
   int objects_per_type[LAST_TYPE + 1] = {0};
   heap_stats.objects_per_type = objects_per_type;
@@ -1135,13 +1137,13 @@
 
 ScriptData* ScriptData::PreCompile(const char* input, int length) {
   unibrow::Utf8InputBuffer<> buf(input, length);
-  return i::PreParse(i::Handle<i::String>(), &buf, NULL);
+  return i::Parser::PreParse(i::Handle<i::String>(), &buf, NULL);
 }
 
 
 ScriptData* ScriptData::PreCompile(v8::Handle<String> source) {
   i::Handle<i::String> str = Utils::OpenHandle(*source);
-  return i::PreParse(str, NULL, NULL);
+  return i::Parser::PreParse(str, NULL, NULL);
 }
 
 
@@ -1677,6 +1679,21 @@
 }
 
 
+Local<String> StackFrame::GetScriptNameOrSourceURL() const {
+  if (IsDeadCheck("v8::StackFrame::GetScriptNameOrSourceURL()")) {
+    return Local<String>();
+  }
+  ENTER_V8;
+  HandleScope scope;
+  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+  i::Handle<i::Object> name = GetProperty(self, "scriptNameOrSourceURL");
+  if (!name->IsString()) {
+    return Local<String>();
+  }
+  return scope.Close(Local<String>::Cast(Utils::ToLocal(name)));
+}
+
+
 Local<String> StackFrame::GetFunctionName() const {
   if (IsDeadCheck("v8::StackFrame::GetFunctionName()")) return Local<String>();
   ENTER_V8;
@@ -1989,6 +2006,15 @@
 }
 
 
+void v8::RegExp::CheckCast(v8::Value* that) {
+  if (IsDeadCheck("v8::RegExp::Cast()")) return;
+  i::Handle<i::Object> obj = Utils::OpenHandle(that);
+  ApiCheck(obj->IsJSRegExp(),
+           "v8::RegExp::Cast()",
+           "Could not convert to regular expression");
+}
+
+
 bool Value::BooleanValue() const {
   if (IsDeadCheck("v8::Value::BooleanValue()")) return false;
   LOG_API("BooleanValue");
@@ -3710,6 +3736,57 @@
 }
 
 
+static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
+  char flags_buf[3];
+  int num_flags = 0;
+  if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
+  if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
+  if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
+  ASSERT(num_flags <= static_cast<int>(ARRAY_SIZE(flags_buf)));
+  return i::Factory::LookupSymbol(
+      i::Vector<const char>(flags_buf, num_flags));
+}
+
+
+Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
+                                  Flags flags) {
+  EnsureInitialized("v8::RegExp::New()");
+  LOG_API("RegExp::New");
+  ENTER_V8;
+  EXCEPTION_PREAMBLE();
+  i::Handle<i::JSRegExp> obj = i::Execution::NewJSRegExp(
+      Utils::OpenHandle(*pattern),
+      RegExpFlagsToString(flags),
+      &has_pending_exception);
+  EXCEPTION_BAILOUT_CHECK(Local<v8::RegExp>());
+  return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
+}
+
+
+Local<v8::String> v8::RegExp::GetSource() const {
+  if (IsDeadCheck("v8::RegExp::GetSource()")) return Local<v8::String>();
+  i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
+  return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
+}
+
+
+// Assert that the static flags cast in GetFlags is valid.
+#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag)        \
+  STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) ==     \
+                static_cast<int>(i::JSRegExp::internal_flag))
+REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
+REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
+REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
+REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
+#undef REGEXP_FLAG_ASSERT_EQ
+
+v8::RegExp::Flags v8::RegExp::GetFlags() const {
+  if (IsDeadCheck("v8::RegExp::GetFlags()")) return v8::RegExp::kNone;
+  i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
+  return static_cast<RegExp::Flags>(obj->GetFlags().value());
+}
+
+
 Local<v8::Array> v8::Array::New(int length) {
   EnsureInitialized("v8::Array::New()");
   LOG_API("Array::New");
@@ -4265,6 +4342,11 @@
 }
 
 
+void Debug::CancelDebugBreak() {
+  i::StackGuard::Continue(i::DEBUGBREAK);
+}
+
+
 void Debug::DebugBreakForCommand(ClientData* data) {
   if (!i::V8::IsRunning()) return;
   i::Debugger::EnqueueDebugCommand(data);
diff --git a/src/api.h b/src/api.h
index 5c67136..e179e35 100644
--- a/src/api.h
+++ b/src/api.h
@@ -174,6 +174,8 @@
       v8::internal::Handle<v8::internal::JSFunction> obj);
   static inline Local<String> ToLocal(
       v8::internal::Handle<v8::internal::String> obj);
+  static inline Local<RegExp> ToLocal(
+      v8::internal::Handle<v8::internal::JSRegExp> obj);
   static inline Local<Object> ToLocal(
       v8::internal::Handle<v8::internal::JSObject> obj);
   static inline Local<Array> ToLocal(
@@ -209,6 +211,8 @@
       OpenHandle(const ObjectTemplate* that);
   static inline v8::internal::Handle<v8::internal::Object>
       OpenHandle(const Data* data);
+  static inline v8::internal::Handle<v8::internal::JSRegExp>
+      OpenHandle(const RegExp* data);
   static inline v8::internal::Handle<v8::internal::JSObject>
       OpenHandle(const v8::Object* data);
   static inline v8::internal::Handle<v8::internal::JSArray>
@@ -265,6 +269,7 @@
 MAKE_TO_LOCAL(ToLocal, Object, Value)
 MAKE_TO_LOCAL(ToLocal, JSFunction, Function)
 MAKE_TO_LOCAL(ToLocal, String, String)
+MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp)
 MAKE_TO_LOCAL(ToLocal, JSObject, Object)
 MAKE_TO_LOCAL(ToLocal, JSArray, Array)
 MAKE_TO_LOCAL(ToLocal, Proxy, External)
@@ -297,6 +302,7 @@
 MAKE_OPEN_HANDLE(Signature, SignatureInfo)
 MAKE_OPEN_HANDLE(TypeSwitch, TypeSwitchInfo)
 MAKE_OPEN_HANDLE(Data, Object)
+MAKE_OPEN_HANDLE(RegExp, JSRegExp)
 MAKE_OPEN_HANDLE(Object, JSObject)
 MAKE_OPEN_HANDLE(Array, JSArray)
 MAKE_OPEN_HANDLE(String, String)
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 8f801cf..b3b0766 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -935,11 +935,8 @@
     __ orr(r2, r1, r0);
     __ tst(r2, Operand(kSmiTagMask));
     __ b(ne, &not_two_smis);
-    __ sub(r0, r1, r0);
-    __ b(vc, &smi_done);
-    // Correct the sign in case of overflow.
-    __ rsb(r0, r0, Operand(0, RelocInfo::NONE));
-    __ bind(&smi_done);
+    __ mov(r1, Operand(r1, ASR, 1));
+    __ sub(r0, r1, Operand(r0, ASR, 1));
     __ Ret();
     __ bind(&not_two_smis);
   } else if (FLAG_debug_code) {
@@ -2300,13 +2297,7 @@
 
 
 void StackCheckStub::Generate(MacroAssembler* masm) {
-  // Do tail-call to runtime routine.  Runtime routines expect at least one
-  // argument, so give it a Smi.
-  __ mov(r0, Operand(Smi::FromInt(0)));
-  __ push(r0);
-  __ TailCallRuntime(Runtime::kStackGuard, 1, 1);
-
-  __ Ret();
+  __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
 }
 
 
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index d273e75..684106c 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -175,7 +175,7 @@
 
   // Adjust for function-level loop nesting.
   ASSERT_EQ(0, loop_nesting_);
-  loop_nesting_ = info->loop_nesting();
+  loop_nesting_ = info->is_in_loop() ? 1 : 0;
 
   {
     CodeGenState state(this);
@@ -339,7 +339,7 @@
   }
 
   // Adjust for function-level loop nesting.
-  ASSERT(loop_nesting_ == info->loop_nesting());
+  ASSERT(loop_nesting_ == info->is_in_loop()? 1 : 0);
   loop_nesting_ = 0;
 
   // Code generation state must be reset.
@@ -3132,9 +3132,9 @@
 
   // Build the function info and instantiate it.
   Handle<SharedFunctionInfo> function_info =
-      Compiler::BuildFunctionInfo(node, script(), this);
-  // Check for stack-overflow exception.
-  if (HasStackOverflow()) {
+      Compiler::BuildFunctionInfo(node, script());
+  if (function_info.is_null()) {
+    SetStackOverflow();
     ASSERT(frame_->height() == original_height);
     return;
   }
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 1483c0b..e6fd607 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -207,9 +207,7 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  // Takes a function literal, generates code for it. This function should only
-  // be called by compiler.cc.
-  static Handle<Code> MakeCode(CompilationInfo* info);
+  static bool MakeCode(CompilationInfo* info);
 
   // Printing of AST, etc. as requested by flags.
   static void MakeCodePrologue(CompilationInfo* info);
@@ -449,9 +447,6 @@
   void Branch(bool if_true, JumpTarget* target);
   void CheckStack();
 
-  static InlineFunctionGenerator FindInlineFunctionGenerator(
-      Runtime::FunctionId function_id);
-
   bool CheckForInlineRuntimeCall(CallRuntime* node);
 
   static Handle<Code> ComputeLazyCompile(int argc);
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 9fc0c09..2855ca4 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -62,6 +62,13 @@
   SetFunctionPosition(function());
   Comment cmnt(masm_, "[ function compiled by full code generator");
 
+#ifdef DEBUG
+  if (strlen(FLAG_stop_at) > 0 &&
+      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+    __ stop("stop-at");
+  }
+#endif
+
   int locals_count = scope()->num_stack_slots();
 
   __ Push(lr, fp, cp, r1);
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index d5a700c..7f83d14 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -969,7 +969,8 @@
 
 bool LoadIC::PatchInlinedContextualLoad(Address address,
                                         Object* map,
-                                        Object* cell) {
+                                        Object* cell,
+                                        bool is_dont_delete) {
   // TODO(<bug#>): implement this.
   return false;
 }
@@ -1584,8 +1585,9 @@
   // Check that the receiver isn't a smi.
   __ BranchOnSmi(r1, &slow);
 
-  // Check that the key is a smi.
-  __ BranchOnNotSmi(r0, &slow);
+  // Check that the key is an array index, that is Uint32.
+  __ tst(r0, Operand(kSmiTagMask | kSmiSignMask));
+  __ b(ne, &slow);
 
   // Get the map of the receiver.
   __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
diff --git a/src/arm/regexp-macro-assembler-arm.cc b/src/arm/regexp-macro-assembler-arm.cc
index 8f45886..37bb1f0 100644
--- a/src/arm/regexp-macro-assembler-arm.cc
+++ b/src/arm/regexp-macro-assembler-arm.cc
@@ -142,7 +142,6 @@
 
 void RegExpMacroAssemblerARM::AdvanceCurrentPosition(int by) {
   if (by != 0) {
-    Label inside_string;
     __ add(current_input_offset(),
            current_input_offset(), Operand(by * char_size()));
   }
@@ -927,6 +926,19 @@
 }
 
 
+void RegExpMacroAssemblerARM::SetCurrentPositionFromEnd(int by) {
+  Label after_position;
+  __ cmp(current_input_offset(), Operand(-by * char_size()));
+  __ b(ge, &after_position);
+  __ mov(current_input_offset(), Operand(-by * char_size()));
+  // On RegExp code entry (where this operation is used), the character before
+  // the current position is expected to be already loaded.
+  // We have advanced the position, so it's safe to read backwards.
+  LoadCurrentCharacterUnchecked(-1, 1);
+  __ bind(&after_position);
+}
+
+
 void RegExpMacroAssemblerARM::SetRegister(int register_index, int to) {
   ASSERT(register_index >= num_saved_registers_);  // Reserved for positions!
   __ mov(r0, Operand(to));
diff --git a/src/arm/regexp-macro-assembler-arm.h b/src/arm/regexp-macro-assembler-arm.h
index 93a74d7..4e09f67 100644
--- a/src/arm/regexp-macro-assembler-arm.h
+++ b/src/arm/regexp-macro-assembler-arm.h
@@ -100,6 +100,7 @@
                             StackCheckFlag check_stack_limit);
   virtual void ReadCurrentPositionFromRegister(int reg);
   virtual void ReadStackPointerFromRegister(int reg);
+  virtual void SetCurrentPositionFromEnd(int by);
   virtual void SetRegister(int register_index, int to);
   virtual void Succeed();
   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index 64262b2..84d9d01 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -37,7 +37,7 @@
 #include "arm/constants-arm.h"
 #include "arm/simulator-arm.h"
 
-#if !defined(__arm__)
+#if !defined(__arm__) || defined(USE_SIMULATOR)
 
 // Only build the simulator if not compiling for real ARM hardware.
 namespace assembler {
@@ -294,7 +294,7 @@
             } else if (GetVFPSingleValue(arg1, &svalue)) {
               PrintF("%s: %f \n", arg1, svalue);
             } else if (GetVFPDoubleValue(arg1, &dvalue)) {
-              PrintF("%s: %lf \n", arg1, dvalue);
+              PrintF("%s: %f \n", arg1, dvalue);
             } else {
               PrintF("%s unrecognized\n", arg1);
             }
@@ -349,7 +349,8 @@
         end = cur + words;
 
         while (cur < end) {
-          PrintF("  0x%08x:  0x%08x %10d\n", cur, *cur, *cur);
+          PrintF("  0x%08x:  0x%08x %10d\n",
+                 reinterpret_cast<intptr_t>(cur), *cur, *cur);
           cur++;
         }
       } else if (strcmp(cmd, "disasm") == 0) {
@@ -382,7 +383,8 @@
 
         while (cur < end) {
           dasm.InstructionDecode(buffer, cur);
-          PrintF("  0x%08x  %s\n", cur, buffer.start());
+          PrintF("  0x%08x  %s\n",
+                 reinterpret_cast<intptr_t>(cur), buffer.start());
           cur += Instr::kInstrSize;
         }
       } else if (strcmp(cmd, "gdb") == 0) {
@@ -1061,7 +1063,7 @@
 // Unsupported instructions use Format to print an error and stop execution.
 void Simulator::Format(Instr* instr, const char* format) {
   PrintF("Simulator found unsupported instruction:\n 0x%08x: %s\n",
-         instr, format);
+         reinterpret_cast<intptr_t>(instr), format);
   UNIMPLEMENTED();
 }
 
@@ -2650,7 +2652,7 @@
     v8::internal::EmbeddedVector<char, 256> buffer;
     dasm.InstructionDecode(buffer,
                            reinterpret_cast<byte*>(instr));
-    PrintF("  0x%08x  %s\n", instr, buffer.start());
+    PrintF("  0x%08x  %s\n", reinterpret_cast<intptr_t>(instr), buffer.start());
   }
   if (instr->ConditionField() == special_condition) {
     DecodeUnconditional(instr);
@@ -2838,6 +2840,6 @@
 
 } }  // namespace assembler::arm
 
-#endif  // __arm__
+#endif  // !__arm__ || USE_SIMULATOR
 
 #endif  // V8_TARGET_ARCH_ARM
diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h
index fee296e..d4c8250 100644
--- a/src/arm/simulator-arm.h
+++ b/src/arm/simulator-arm.h
@@ -38,7 +38,7 @@
 
 #include "allocation.h"
 
-#if defined(__arm__)
+#if defined(__arm__) && !defined(USE_SIMULATOR)
 
 // When running without a simulator we call the entry directly.
 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
@@ -70,7 +70,7 @@
   reinterpret_cast<TryCatch*>(try_catch_address)
 
 
-#else  // defined(__arm__)
+#else  // !defined(__arm__) || defined(USE_SIMULATOR)
 
 // When running with the simulator transition into simulated execution at this
 // point.
@@ -356,6 +356,6 @@
 };
 
 
-#endif  // defined(__arm__)
+#endif  // !defined(__arm__) || defined(USE_SIMULATOR)
 
 #endif  // V8_ARM_SIMULATOR_ARM_H_
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 659f29c..97f9495 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -1643,6 +1643,108 @@
 }
 
 
+Object* CallStubCompiler::CompileMathAbsCall(Object* object,
+                                             JSObject* holder,
+                                             JSGlobalPropertyCell* cell,
+                                             JSFunction* function,
+                                             String* name) {
+  // ----------- S t a t e -------------
+  //  -- r2                     : function name
+  //  -- lr                     : return address
+  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero-based)
+  //  -- ...
+  //  -- sp[argc * 4]           : receiver
+  // -----------------------------------
+
+  const int argc = arguments().immediate();
+
+  // If the object is not a JSObject or we got an unexpected number of
+  // arguments, bail out to the regular call.
+  if (!object->IsJSObject() || argc != 1) return Heap::undefined_value();
+
+  Label miss;
+  GenerateNameCheck(name, &miss);
+
+  if (cell == NULL) {
+    __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
+
+    STATIC_ASSERT(kSmiTag == 0);
+    __ tst(r1, Operand(kSmiTagMask));
+    __ b(eq, &miss);
+
+    CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
+                    &miss);
+  } else {
+    ASSERT(cell->value() == function);
+    GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
+    GenerateLoadFunctionFromCell(cell, function, &miss);
+  }
+
+  // Load the (only) argument into r0.
+  __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
+
+  // Check if the argument is a smi.
+  Label not_smi;
+  STATIC_ASSERT(kSmiTag == 0);
+  __ BranchOnNotSmi(r0, &not_smi);
+
+  // Do bitwise not or do nothing depending on the sign of the
+  // argument.
+  __ eor(r1, r0, Operand(r0, ASR, kBitsPerInt - 1));
+
+  // Add 1 or do nothing depending on the sign of the argument.
+  __ sub(r0, r1, Operand(r0, ASR, kBitsPerInt - 1), SetCC);
+
+  // If the result is still negative, go to the slow case.
+  // This only happens for the most negative smi.
+  Label slow;
+  __ b(mi, &slow);
+
+  // Smi case done.
+  __ Drop(argc + 1);
+  __ Ret();
+
+  // Check if the argument is a heap number and load its exponent and
+  // sign.
+  __ bind(&not_smi);
+  __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, true);
+  __ ldr(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset));
+
+  // Check the sign of the argument. If the argument is positive,
+  // just return it.
+  Label negative_sign;
+  __ tst(r1, Operand(HeapNumber::kSignMask));
+  __ b(ne, &negative_sign);
+  __ Drop(argc + 1);
+  __ Ret();
+
+  // If the argument is negative, clear the sign, and return a new
+  // number.
+  __ bind(&negative_sign);
+  __ eor(r1, r1, Operand(HeapNumber::kSignMask));
+  __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
+  __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
+  __ AllocateHeapNumber(r0, r4, r5, r6, &slow);
+  __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset));
+  __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
+  __ Drop(argc + 1);
+  __ Ret();
+
+  // Tail call the full function. We do not have to patch the receiver
+  // because the function makes no use of it.
+  __ bind(&slow);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+
+  __ bind(&miss);
+  // r2: function name.
+  Object* obj = GenerateMissBranch();
+  if (obj->IsFailure()) return obj;
+
+  // Return the generated code.
+  return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
+}
+
+
 Object* CallStubCompiler::CompileCallConstant(Object* object,
                                               JSObject* holder,
                                               JSFunction* function,
diff --git a/src/assembler.cc b/src/assembler.cc
index 6a46f61..b6efdb9 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -465,7 +465,7 @@
 void RelocInfo::Print() {
   PrintF("%p  %s", pc_, RelocModeName(rmode_));
   if (IsComment(rmode_)) {
-    PrintF("  (%s)", data_);
+    PrintF("  (%s)", reinterpret_cast<char*>(data_));
   } else if (rmode_ == EMBEDDED_OBJECT) {
     PrintF("  (");
     target_object()->ShortPrint();
@@ -479,7 +479,7 @@
     Code* code = Code::GetCodeFromTargetAddress(target_address());
     PrintF(" (%s)  (%p)", Code::Kind2String(code->kind()), target_address());
   } else if (IsPosition(rmode_)) {
-    PrintF("  (%d)", data());
+    PrintF("  (%" V8_PTR_PREFIX "d)", data());
   }
 
   PrintF("\n");
diff --git a/src/ast.cc b/src/ast.cc
index f47dffd..92f1496 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -398,39 +398,70 @@
 }
 
 
-bool RegExpAssertion::IsAnchored() {
+bool RegExpAssertion::IsAnchoredAtStart() {
   return type() == RegExpAssertion::START_OF_INPUT;
 }
 
 
-bool RegExpAlternative::IsAnchored() {
+bool RegExpAssertion::IsAnchoredAtEnd() {
+  return type() == RegExpAssertion::END_OF_INPUT;
+}
+
+
+bool RegExpAlternative::IsAnchoredAtStart() {
   ZoneList<RegExpTree*>* nodes = this->nodes();
   for (int i = 0; i < nodes->length(); i++) {
     RegExpTree* node = nodes->at(i);
-    if (node->IsAnchored()) { return true; }
+    if (node->IsAnchoredAtStart()) { return true; }
     if (node->max_match() > 0) { return false; }
   }
   return false;
 }
 
 
-bool RegExpDisjunction::IsAnchored() {
+bool RegExpAlternative::IsAnchoredAtEnd() {
+  ZoneList<RegExpTree*>* nodes = this->nodes();
+  for (int i = nodes->length() - 1; i >= 0; i--) {
+    RegExpTree* node = nodes->at(i);
+    if (node->IsAnchoredAtEnd()) { return true; }
+    if (node->max_match() > 0) { return false; }
+  }
+  return false;
+}
+
+
+bool RegExpDisjunction::IsAnchoredAtStart() {
   ZoneList<RegExpTree*>* alternatives = this->alternatives();
   for (int i = 0; i < alternatives->length(); i++) {
-    if (!alternatives->at(i)->IsAnchored())
+    if (!alternatives->at(i)->IsAnchoredAtStart())
       return false;
   }
   return true;
 }
 
 
-bool RegExpLookahead::IsAnchored() {
-  return is_positive() && body()->IsAnchored();
+bool RegExpDisjunction::IsAnchoredAtEnd() {
+  ZoneList<RegExpTree*>* alternatives = this->alternatives();
+  for (int i = 0; i < alternatives->length(); i++) {
+    if (!alternatives->at(i)->IsAnchoredAtEnd())
+      return false;
+  }
+  return true;
 }
 
 
-bool RegExpCapture::IsAnchored() {
-  return body()->IsAnchored();
+bool RegExpLookahead::IsAnchoredAtStart() {
+  return is_positive() && body()->IsAnchoredAtStart();
+}
+
+
+bool RegExpCapture::IsAnchoredAtStart() {
+  return body()->IsAnchoredAtStart();
+}
+
+
+bool RegExpCapture::IsAnchoredAtEnd() {
+  return body()->IsAnchoredAtEnd();
 }
 
 
diff --git a/src/ast.h b/src/ast.h
index eadb310..a01e48d 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -118,35 +118,38 @@
 typedef ZoneList<Handle<Object> > ZoneObjectList;
 
 
+#define DECLARE_NODE_TYPE(type)                                         \
+  virtual void Accept(AstVisitor* v);                                   \
+  virtual AstNode::Type node_type() const { return AstNode::k##type; }  \
+  virtual type* As##type() { return this; }
+
+
 class AstNode: public ZoneObject {
  public:
-  virtual ~AstNode() { }
-  virtual void Accept(AstVisitor* v) = 0;
+#define DECLARE_TYPE_ENUM(type) k##type,
+  enum Type {
+    AST_NODE_LIST(DECLARE_TYPE_ENUM)
+    kInvalid = -1
+  };
+#undef DECLARE_TYPE_ENUM
 
-  // Type testing & conversion.
+  virtual ~AstNode() { }
+
+  virtual void Accept(AstVisitor* v) = 0;
+  virtual Type node_type() const { return kInvalid; }
+
+  // Type testing & conversion functions overridden by concrete subclasses.
+#define DECLARE_NODE_FUNCTIONS(type)                  \
+  virtual type* As##type() { return NULL; }
+  AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
+#undef DECLARE_NODE_FUNCTIONS
+
   virtual Statement* AsStatement() { return NULL; }
-  virtual Block* AsBlock() { return NULL; }
-  virtual ExpressionStatement* AsExpressionStatement() { return NULL; }
-  virtual EmptyStatement* AsEmptyStatement() { return NULL; }
   virtual Expression* AsExpression() { return NULL; }
-  virtual Literal* AsLiteral() { return NULL; }
-  virtual Slot* AsSlot() { return NULL; }
-  virtual VariableProxy* AsVariableProxy() { return NULL; }
-  virtual Property* AsProperty() { return NULL; }
-  virtual Call* AsCall() { return NULL; }
   virtual TargetCollector* AsTargetCollector() { return NULL; }
   virtual BreakableStatement* AsBreakableStatement() { return NULL; }
   virtual IterationStatement* AsIterationStatement() { return NULL; }
-  virtual ForStatement* AsForStatement() { return NULL; }
-  virtual UnaryOperation* AsUnaryOperation() { return NULL; }
-  virtual CountOperation* AsCountOperation() { return NULL; }
-  virtual BinaryOperation* AsBinaryOperation() { return NULL; }
-  virtual Assignment* AsAssignment() { return NULL; }
-  virtual FunctionLiteral* AsFunctionLiteral() { return NULL; }
   virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
-  virtual ObjectLiteral* AsObjectLiteral() { return NULL; }
-  virtual ArrayLiteral* AsArrayLiteral() { return NULL; }
-  virtual CompareOperation* AsCompareOperation() { return NULL; }
 };
 
 
@@ -155,7 +158,6 @@
   Statement() : statement_pos_(RelocInfo::kNoPosition) {}
 
   virtual Statement* AsStatement()  { return this; }
-  virtual ReturnStatement* AsReturnStatement() { return NULL; }
 
   virtual Assignment* StatementAsSimpleAssignment() { return NULL; }
   virtual CountOperation* StatementAsCountOperation() { return NULL; }
@@ -313,9 +315,7 @@
  public:
   inline Block(ZoneStringList* labels, int capacity, bool is_initializer_block);
 
-  virtual void Accept(AstVisitor* v);
-
-  virtual Block* AsBlock() { return this; }
+  DECLARE_NODE_TYPE(Block)
 
   virtual Assignment* StatementAsSimpleAssignment() {
     if (statements_.length() != 1) return NULL;
@@ -349,7 +349,7 @@
     ASSERT(fun == NULL || mode == Variable::VAR);
   }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(Declaration)
 
   VariableProxy* proxy() const { return proxy_; }
   Variable::Mode mode() const { return mode_; }
@@ -390,13 +390,13 @@
  public:
   explicit inline DoWhileStatement(ZoneStringList* labels);
 
+  DECLARE_NODE_TYPE(DoWhileStatement)
+
   void Initialize(Expression* cond, Statement* body) {
     IterationStatement::Initialize(body);
     cond_ = cond;
   }
 
-  virtual void Accept(AstVisitor* v);
-
   Expression* cond() const { return cond_; }
 
   // Position where condition expression starts. We need it to make
@@ -414,13 +414,13 @@
  public:
   explicit WhileStatement(ZoneStringList* labels);
 
+  DECLARE_NODE_TYPE(WhileStatement)
+
   void Initialize(Expression* cond, Statement* body) {
     IterationStatement::Initialize(body);
     cond_ = cond;
   }
 
-  virtual void Accept(AstVisitor* v);
-
   Expression* cond() const { return cond_; }
   bool may_have_function_literal() const {
     return may_have_function_literal_;
@@ -440,7 +440,7 @@
  public:
   explicit inline ForStatement(ZoneStringList* labels);
 
-  virtual ForStatement* AsForStatement() { return this; }
+  DECLARE_NODE_TYPE(ForStatement)
 
   void Initialize(Statement* init,
                   Expression* cond,
@@ -452,8 +452,6 @@
     next_ = next;
   }
 
-  virtual void Accept(AstVisitor* v);
-
   Statement* init() const { return init_; }
   void set_init(Statement* stmt) { init_ = stmt; }
   Expression* cond() const { return cond_; }
@@ -486,14 +484,14 @@
  public:
   explicit inline ForInStatement(ZoneStringList* labels);
 
+  DECLARE_NODE_TYPE(ForInStatement)
+
   void Initialize(Expression* each, Expression* enumerable, Statement* body) {
     IterationStatement::Initialize(body);
     each_ = each;
     enumerable_ = enumerable;
   }
 
-  virtual void Accept(AstVisitor* v);
-
   Expression* each() const { return each_; }
   Expression* enumerable() const { return enumerable_; }
 
@@ -508,10 +506,7 @@
   explicit ExpressionStatement(Expression* expression)
       : expression_(expression) { }
 
-  virtual void Accept(AstVisitor* v);
-
-  // Type testing & conversion.
-  virtual ExpressionStatement* AsExpressionStatement() { return this; }
+  DECLARE_NODE_TYPE(ExpressionStatement)
 
   virtual Assignment* StatementAsSimpleAssignment();
   virtual CountOperation* StatementAsCountOperation();
@@ -529,7 +524,7 @@
   explicit ContinueStatement(IterationStatement* target)
       : target_(target) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(ContinueStatement)
 
   IterationStatement* target() const { return target_; }
 
@@ -543,7 +538,7 @@
   explicit BreakStatement(BreakableStatement* target)
       : target_(target) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(BreakStatement)
 
   BreakableStatement* target() const { return target_; }
 
@@ -557,10 +552,7 @@
   explicit ReturnStatement(Expression* expression)
       : expression_(expression) { }
 
-  virtual void Accept(AstVisitor* v);
-
-  // Type testing & conversion.
-  virtual ReturnStatement* AsReturnStatement() { return this; }
+  DECLARE_NODE_TYPE(ReturnStatement)
 
   Expression* expression() { return expression_; }
 
@@ -574,7 +566,7 @@
   explicit WithEnterStatement(Expression* expression, bool is_catch_block)
       : expression_(expression), is_catch_block_(is_catch_block) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(WithEnterStatement)
 
   Expression* expression() const { return expression_; }
 
@@ -590,7 +582,7 @@
  public:
   WithExitStatement() { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(WithExitStatement)
 };
 
 
@@ -617,13 +609,13 @@
  public:
   explicit inline SwitchStatement(ZoneStringList* labels);
 
+  DECLARE_NODE_TYPE(SwitchStatement)
+
   void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
     tag_ = tag;
     cases_ = cases;
   }
 
-  virtual void Accept(AstVisitor* v);
-
   Expression* tag() const { return tag_; }
   ZoneList<CaseClause*>* cases() const { return cases_; }
 
@@ -647,7 +639,7 @@
         then_statement_(then_statement),
         else_statement_(else_statement) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(IfStatement)
 
   bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
   bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
@@ -717,7 +709,7 @@
         catch_block_(catch_block) {
   }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(TryCatchStatement)
 
   VariableProxy* catch_var() const { return catch_var_; }
   Block* catch_block() const { return catch_block_; }
@@ -734,7 +726,7 @@
       : TryStatement(try_block),
         finally_block_(finally_block) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(TryFinallyStatement)
 
   Block* finally_block() const { return finally_block_; }
 
@@ -745,18 +737,13 @@
 
 class DebuggerStatement: public Statement {
  public:
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(DebuggerStatement)
 };
 
 
 class EmptyStatement: public Statement {
  public:
-  EmptyStatement() {}
-
-  virtual void Accept(AstVisitor* v);
-
-  // Type testing & conversion.
-  virtual EmptyStatement* AsEmptyStatement() { return this; }
+  DECLARE_NODE_TYPE(EmptyStatement)
 };
 
 
@@ -764,13 +751,11 @@
  public:
   explicit Literal(Handle<Object> handle) : handle_(handle) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(Literal)
+
   virtual bool IsTrivial() { return true; }
   virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
 
-  // Type testing & conversion.
-  virtual Literal* AsLiteral() { return this; }
-
   // Check if this literal is identical to the other literal.
   bool IsIdenticalTo(const Literal* other) const {
     return handle_.is_identical_to(other->handle_);
@@ -864,8 +849,7 @@
         properties_(properties),
         fast_elements_(fast_elements) {}
 
-  virtual ObjectLiteral* AsObjectLiteral() { return this; }
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(ObjectLiteral)
 
   Handle<FixedArray> constant_properties() const {
     return constant_properties_;
@@ -891,7 +875,7 @@
         pattern_(pattern),
         flags_(flags) {}
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(RegExpLiteral)
 
   Handle<String> pattern() const { return pattern_; }
   Handle<String> flags() const { return flags_; }
@@ -914,8 +898,7 @@
         constant_elements_(constant_elements),
         values_(values) {}
 
-  virtual void Accept(AstVisitor* v);
-  virtual ArrayLiteral* AsArrayLiteral() { return this; }
+  DECLARE_NODE_TYPE(ArrayLiteral)
 
   Handle<FixedArray> constant_elements() const { return constant_elements_; }
   ZoneList<Expression*>* values() const { return values_; }
@@ -935,7 +918,7 @@
       : key_(key), value_(value) {
   }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(CatchExtensionObject)
 
   Literal* key() const { return key_; }
   VariableProxy* value() const { return value_; }
@@ -950,17 +933,13 @@
  public:
   explicit VariableProxy(Variable* var);
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(VariableProxy)
 
   // Type testing & conversion
   virtual Property* AsProperty() {
     return var_ == NULL ? NULL : var_->AsProperty();
   }
 
-  virtual VariableProxy* AsVariableProxy() {
-    return this;
-  }
-
   Variable* AsVariable() {
     if (this == NULL || var_ == NULL) return NULL;
     Expression* rewrite = var_->rewrite();
@@ -1055,10 +1034,7 @@
     ASSERT(var != NULL);
   }
 
-  virtual void Accept(AstVisitor* v);
-
-  // Type testing & conversion
-  virtual Slot* AsSlot() { return this; }
+  DECLARE_NODE_TYPE(Slot)
 
   bool IsStackAllocated() { return type_ == PARAMETER || type_ == LOCAL; }
 
@@ -1085,10 +1061,7 @@
   Property(Expression* obj, Expression* key, int pos, Type type = NORMAL)
       : obj_(obj), key_(key), pos_(pos), type_(type) { }
 
-  virtual void Accept(AstVisitor* v);
-
-  // Type testing & conversion
-  virtual Property* AsProperty() { return this; }
+  DECLARE_NODE_TYPE(Property)
 
   virtual bool IsValidLeftHandSide() { return true; }
 
@@ -1117,10 +1090,7 @@
   Call(Expression* expression, ZoneList<Expression*>* arguments, int pos)
       : expression_(expression), arguments_(arguments), pos_(pos) { }
 
-  virtual void Accept(AstVisitor* v);
-
-  // Type testing and conversion.
-  virtual Call* AsCall() { return this; }
+  DECLARE_NODE_TYPE(Call)
 
   Expression* expression() const { return expression_; }
   ZoneList<Expression*>* arguments() const { return arguments_; }
@@ -1142,7 +1112,7 @@
   CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
       : expression_(expression), arguments_(arguments), pos_(pos) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(CallNew)
 
   Expression* expression() const { return expression_; }
   ZoneList<Expression*>* arguments() const { return arguments_; }
@@ -1166,7 +1136,7 @@
               ZoneList<Expression*>* arguments)
       : name_(name), function_(function), arguments_(arguments) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(CallRuntime)
 
   Handle<String> name() const { return name_; }
   Runtime::Function* function() const { return function_; }
@@ -1187,11 +1157,9 @@
     ASSERT(Token::IsUnaryOp(op));
   }
 
-  virtual void Accept(AstVisitor* v);
-  virtual bool ResultOverwriteAllowed();
+  DECLARE_NODE_TYPE(UnaryOperation)
 
-  // Type testing & conversion
-  virtual UnaryOperation* AsUnaryOperation() { return this; }
+  virtual bool ResultOverwriteAllowed();
 
   Token::Value op() const { return op_; }
   Expression* expression() const { return expression_; }
@@ -1215,11 +1183,9 @@
   // Create the binary operation corresponding to a compound assignment.
   explicit BinaryOperation(Assignment* assignment);
 
-  virtual void Accept(AstVisitor* v);
-  virtual bool ResultOverwriteAllowed();
+  DECLARE_NODE_TYPE(BinaryOperation)
 
-  // Type testing & conversion
-  virtual BinaryOperation* AsBinaryOperation() { return this; }
+  virtual bool ResultOverwriteAllowed();
 
   Token::Value op() const { return op_; }
   Expression* left() const { return left_; }
@@ -1241,12 +1207,12 @@
     ASSERT(Token::IsCountOp(op));
   }
 
+  DECLARE_NODE_TYPE(IncrementOperation)
+
   Token::Value op() const { return op_; }
   bool is_increment() { return op_ == Token::INC; }
   Expression* expression() const { return expression_; }
 
-  virtual void Accept(AstVisitor* v);
-
  private:
   Token::Value op_;
   Expression* expression_;
@@ -1259,9 +1225,7 @@
   CountOperation(bool is_prefix, IncrementOperation* increment, int pos)
       : is_prefix_(is_prefix), increment_(increment), pos_(pos) { }
 
-  virtual void Accept(AstVisitor* v);
-
-  virtual CountOperation* AsCountOperation() { return this; }
+  DECLARE_NODE_TYPE(CountOperation)
 
   bool is_prefix() const { return is_prefix_; }
   bool is_postfix() const { return !is_prefix_; }
@@ -1294,16 +1258,13 @@
     ASSERT(Token::IsCompareOp(op));
   }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(CompareOperation)
 
   Token::Value op() const { return op_; }
   Expression* left() const { return left_; }
   Expression* right() const { return right_; }
   int position() const { return pos_; }
 
-  // Type testing & conversion
-  virtual CompareOperation* AsCompareOperation() { return this; }
-
  private:
   Token::Value op_;
   Expression* left_;
@@ -1317,7 +1278,7 @@
   CompareToNull(bool is_strict, Expression* expression)
       : is_strict_(is_strict), expression_(expression) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(CompareToNull)
 
   bool is_strict() const { return is_strict_; }
   Token::Value op() const { return is_strict_ ? Token::EQ_STRICT : Token::EQ; }
@@ -1342,7 +1303,7 @@
         then_expression_position_(then_expression_position),
         else_expression_position_(else_expression_position) { }
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(Conditional)
 
   Expression* condition() const { return condition_; }
   Expression* then_expression() const { return then_expression_; }
@@ -1368,8 +1329,7 @@
     ASSERT(Token::IsAssignmentOp(op));
   }
 
-  virtual void Accept(AstVisitor* v);
-  virtual Assignment* AsAssignment() { return this; }
+  DECLARE_NODE_TYPE(Assignment)
 
   Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
 
@@ -1406,7 +1366,7 @@
   Throw(Expression* exception, int pos)
       : exception_(exception), pos_(pos) {}
 
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(Throw)
 
   Expression* exception() const { return exception_; }
   int position() const { return pos_; }
@@ -1452,10 +1412,7 @@
 #endif
   }
 
-  virtual void Accept(AstVisitor* v);
-
-  // Type testing & conversion
-  virtual FunctionLiteral* AsFunctionLiteral()  { return this; }
+  DECLARE_NODE_TYPE(FunctionLiteral)
 
   Handle<String> name() const { return name_; }
   Scope* scope() const { return scope_; }
@@ -1479,6 +1436,11 @@
 
   bool AllowsLazyCompilation();
 
+  Handle<String> debug_name() const {
+    if (name_->length() > 0) return name_;
+    return inferred_name();
+  }
+
   Handle<String> inferred_name() const { return inferred_name_; }
   void set_inferred_name(Handle<String> inferred_name) {
     inferred_name_ = inferred_name;
@@ -1522,12 +1484,12 @@
       Handle<SharedFunctionInfo> shared_function_info)
       : shared_function_info_(shared_function_info) { }
 
+  DECLARE_NODE_TYPE(SharedFunctionInfoLiteral)
+
   Handle<SharedFunctionInfo> shared_function_info() const {
     return shared_function_info_;
   }
 
-  virtual void Accept(AstVisitor* v);
-
  private:
   Handle<SharedFunctionInfo> shared_function_info_;
 };
@@ -1535,7 +1497,7 @@
 
 class ThisFunction: public Expression {
  public:
-  virtual void Accept(AstVisitor* v);
+  DECLARE_NODE_TYPE(ThisFunction)
 };
 
 
@@ -1561,7 +1523,8 @@
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) = 0;
   virtual bool IsTextElement() { return false; }
-  virtual bool IsAnchored() { return false; }
+  virtual bool IsAnchoredAtStart() { return false; }
+  virtual bool IsAnchoredAtEnd() { return false; }
   virtual int min_match() = 0;
   virtual int max_match() = 0;
   // Returns the interval of registers used for captures within this
@@ -1586,7 +1549,8 @@
   virtual RegExpDisjunction* AsDisjunction();
   virtual Interval CaptureRegisters();
   virtual bool IsDisjunction();
-  virtual bool IsAnchored();
+  virtual bool IsAnchoredAtStart();
+  virtual bool IsAnchoredAtEnd();
   virtual int min_match() { return min_match_; }
   virtual int max_match() { return max_match_; }
   ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
@@ -1606,7 +1570,8 @@
   virtual RegExpAlternative* AsAlternative();
   virtual Interval CaptureRegisters();
   virtual bool IsAlternative();
-  virtual bool IsAnchored();
+  virtual bool IsAnchoredAtStart();
+  virtual bool IsAnchoredAtEnd();
   virtual int min_match() { return min_match_; }
   virtual int max_match() { return max_match_; }
   ZoneList<RegExpTree*>* nodes() { return nodes_; }
@@ -1633,7 +1598,8 @@
                              RegExpNode* on_success);
   virtual RegExpAssertion* AsAssertion();
   virtual bool IsAssertion();
-  virtual bool IsAnchored();
+  virtual bool IsAnchoredAtStart();
+  virtual bool IsAnchoredAtEnd();
   virtual int min_match() { return 0; }
   virtual int max_match() { return 0; }
   Type type() { return type_; }
@@ -1806,7 +1772,8 @@
                             RegExpCompiler* compiler,
                             RegExpNode* on_success);
   virtual RegExpCapture* AsCapture();
-  virtual bool IsAnchored();
+  virtual bool IsAnchoredAtStart();
+  virtual bool IsAnchoredAtEnd();
   virtual Interval CaptureRegisters();
   virtual bool IsCapture();
   virtual int min_match() { return body_->min_match(); }
@@ -1838,7 +1805,7 @@
   virtual RegExpLookahead* AsLookahead();
   virtual Interval CaptureRegisters();
   virtual bool IsLookahead();
-  virtual bool IsAnchored();
+  virtual bool IsAnchoredAtStart();
   virtual int min_match() { return 0; }
   virtual int max_match() { return 0; }
   RegExpTree* body() { return body_; }
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index aa8d8e5..d7491e1 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1814,6 +1814,11 @@
     i::Counters::contexts_created_from_scratch.Increment();
   }
 
+  // Add this context to the weak list of global contexts.
+  (*global_context_)->set(Context::NEXT_CONTEXT_LINK,
+                          Heap::global_contexts_list());
+  Heap::set_global_contexts_list(*global_context_);
+
   result_ = global_context_;
 }
 
diff --git a/src/bytecodes-irregexp.h b/src/bytecodes-irregexp.h
index bcb34c8..93218ea 100644
--- a/src/bytecodes-irregexp.h
+++ b/src/bytecodes-irregexp.h
@@ -88,7 +88,8 @@
 V(CHECK_AT_START,    44, 8)   /* bc8 pad24 addr32                           */ \
 V(CHECK_NOT_AT_START, 45, 8)  /* bc8 pad24 addr32                           */ \
 V(CHECK_GREEDY,      46, 8)   /* bc8 pad24 addr32                           */ \
-V(ADVANCE_CP_AND_GOTO, 47, 8) /* bc8 offset24 addr32                        */
+V(ADVANCE_CP_AND_GOTO, 47, 8) /* bc8 offset24 addr32                        */ \
+V(SET_CURRENT_POSITION_FROM_END, 48, 4) /* bc8 idx24                        */
 
 #define DECLARE_BYTECODES(name, code, length) \
   static const int BC_##name = code;
diff --git a/src/cached-powers.cc b/src/cached-powers.cc
new file mode 100644
index 0000000..8f82286
--- /dev/null
+++ b/src/cached-powers.cc
@@ -0,0 +1,152 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdarg.h>
+#include <limits.h>
+
+#include "v8.h"
+
+#include "cached-powers.h"
+
+namespace v8 {
+namespace internal {
+
+struct CachedPower {
+  uint64_t significand;
+  int16_t binary_exponent;
+  int16_t decimal_exponent;
+};
+
+static const CachedPower kCachedPowers[] = {
+  {V8_2PART_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
+  {V8_2PART_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
+  {V8_2PART_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
+  {V8_2PART_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
+  {V8_2PART_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
+  {V8_2PART_UINT64_C(0xd3515c28, 31559a83), -954, -268},
+  {V8_2PART_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
+  {V8_2PART_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
+  {V8_2PART_UINT64_C(0xaecc4991, 4078536d), -874, -244},
+  {V8_2PART_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
+  {V8_2PART_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
+  {V8_2PART_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
+  {V8_2PART_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
+  {V8_2PART_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
+  {V8_2PART_UINT64_C(0xef340a98, 172aace5), -715, -196},
+  {V8_2PART_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
+  {V8_2PART_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
+  {V8_2PART_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
+  {V8_2PART_UINT64_C(0x936b9fce, bb25c996), -608, -164},
+  {V8_2PART_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
+  {V8_2PART_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
+  {V8_2PART_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
+  {V8_2PART_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
+  {V8_2PART_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
+  {V8_2PART_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
+  {V8_2PART_UINT64_C(0x964e858c, 91ba2655), -422, -108},
+  {V8_2PART_UINT64_C(0xdff97724, 70297ebd), -396, -100},
+  {V8_2PART_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
+  {V8_2PART_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
+  {V8_2PART_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
+  {V8_2PART_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
+  {V8_2PART_UINT64_C(0xcdb02555, 653131b6), -263, -60},
+  {V8_2PART_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
+  {V8_2PART_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
+  {V8_2PART_UINT64_C(0xaa242499, 697392d3), -183, -36},
+  {V8_2PART_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
+  {V8_2PART_UINT64_C(0xbce50864, 92111aeb), -130, -20},
+  {V8_2PART_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
+  {V8_2PART_UINT64_C(0xd1b71758, e219652c), -77, -4},
+  {V8_2PART_UINT64_C(0x9c400000, 00000000), -50, 4},
+  {V8_2PART_UINT64_C(0xe8d4a510, 00000000), -24, 12},
+  {V8_2PART_UINT64_C(0xad78ebc5, ac620000), 3, 20},
+  {V8_2PART_UINT64_C(0x813f3978, f8940984), 30, 28},
+  {V8_2PART_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
+  {V8_2PART_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
+  {V8_2PART_UINT64_C(0xd5d238a4, abe98068), 109, 52},
+  {V8_2PART_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
+  {V8_2PART_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
+  {V8_2PART_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
+  {V8_2PART_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
+  {V8_2PART_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
+  {V8_2PART_UINT64_C(0x924d692c, a61be758), 269, 100},
+  {V8_2PART_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
+  {V8_2PART_UINT64_C(0xa26da399, 9aef774a), 322, 116},
+  {V8_2PART_UINT64_C(0xf209787b, b47d6b85), 348, 124},
+  {V8_2PART_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
+  {V8_2PART_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
+  {V8_2PART_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
+  {V8_2PART_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
+  {V8_2PART_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
+  {V8_2PART_UINT64_C(0xa59bc234, db398c25), 508, 172},
+  {V8_2PART_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
+  {V8_2PART_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
+  {V8_2PART_UINT64_C(0x88fcf317, f22241e2), 588, 196},
+  {V8_2PART_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
+  {V8_2PART_UINT64_C(0x98165af3, 7b2153df), 641, 212},
+  {V8_2PART_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
+  {V8_2PART_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
+  {V8_2PART_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
+  {V8_2PART_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
+  {V8_2PART_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
+  {V8_2PART_UINT64_C(0xd01fef10, a657842c), 800, 260},
+  {V8_2PART_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
+  {V8_2PART_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
+  {V8_2PART_UINT64_C(0xac2820d9, 623bf429), 880, 284},
+  {V8_2PART_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
+  {V8_2PART_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
+  {V8_2PART_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
+  {V8_2PART_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
+  {V8_2PART_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
+  {V8_2PART_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
+  {V8_2PART_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
+};
+
+static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
+static const int kCachedPowersOffset = -kCachedPowers[0].decimal_exponent;
+static const double kD_1_LOG2_10 = 0.30102999566398114;  //  1 / lg(10)
+static const int kCachedPowersDecimalDistance =
+    kCachedPowers[1].decimal_exponent - kCachedPowers[0].decimal_exponent;
+
+void GetCachedPowerForBinaryExponentRange(int min_exponent,
+                                          int max_exponent,
+                                          DiyFp* power,
+                                          int* decimal_exponent) {
+    int kQ = DiyFp::kSignificandSize;
+    double k = ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10);
+    int foo = kCachedPowersOffset;
+    int index =
+        (foo + static_cast<int>(k) - 1) / kCachedPowersDecimalDistance + 1;
+    ASSERT(0 <= index && index < kCachedPowersLength);
+    CachedPower cached_power = kCachedPowers[index];
+    ASSERT(min_exponent <= cached_power.binary_exponent);
+    ASSERT(cached_power.binary_exponent <= max_exponent);
+    *decimal_exponent = cached_power.decimal_exponent;
+    *power = DiyFp(cached_power.significand, cached_power.binary_exponent);
+}
+
+} }  // namespace v8::internal
diff --git a/src/cached-powers.h b/src/cached-powers.h
index 314ccca..0c78343 100644
--- a/src/cached-powers.h
+++ b/src/cached-powers.h
@@ -33,86 +33,10 @@
 namespace v8 {
 namespace internal {
 
-struct CachedPower {
-  uint64_t significand;
-  int16_t binary_exponent;
-  int16_t decimal_exponent;
-};
-
-// The following defines implement the interface between this file and the
-// generated 'powers_ten.h'.
-// GRISU_CACHE_NAME(1) contains all possible cached powers.
-// GRISU_CACHE_NAME(i) contains GRISU_CACHE_NAME(1) where only every 'i'th
-// element is kept. More formally GRISU_CACHE_NAME(i) contains the elements j*i
-// with 0 <= j < k with k such that j*k < the size of GRISU_CACHE_NAME(1).
-// The higher 'i' is the fewer elements we use.
-// Given that there are less elements, the exponent-distance between two
-// elements in the cache grows. The variable GRISU_CACHE_MAX_DISTANCE(i) stores
-// the maximum distance between two elements.
-#define GRISU_CACHE_STRUCT CachedPower
-#define GRISU_CACHE_NAME(i) kCachedPowers##i
-#define GRISU_CACHE_MAX_DISTANCE(i) kCachedPowersMaxDistance##i
-#define GRISU_CACHE_OFFSET kCachedPowerOffset
-#define GRISU_UINT64_C V8_2PART_UINT64_C
-// The following include imports the precompiled cached powers.
-#include "powers-ten.h"  // NOLINT
-
-static const double kD_1_LOG2_10 = 0.30102999566398114;  //  1 / lg(10)
-
-// We can't use a function since we reference variables depending on the 'i'.
-// This way the compiler is able to see at compile time that only one
-// cache-array variable is used and thus can remove all the others.
-#define COMPUTE_FOR_CACHE(i) \
-  if (!found && (gamma - alpha + 1 >= GRISU_CACHE_MAX_DISTANCE(i))) {   \
-    int kQ = DiyFp::kSignificandSize;                                   \
-    double k = ceiling((alpha - e + kQ - 1) * kD_1_LOG2_10);            \
-    int index = (GRISU_CACHE_OFFSET + static_cast<int>(k) - 1) / i + 1; \
-    cached_power = GRISU_CACHE_NAME(i)[index];                          \
-    found = true;                                                       \
-  }                                                                     \
-
-static void GetCachedPower(int e, int alpha, int gamma, int* mk, DiyFp* c_mk) {
-  // The following if statement should be optimized by the compiler so that only
-  // one array is referenced and the others are not included in the object file.
-  bool found = false;
-  CachedPower cached_power;
-  COMPUTE_FOR_CACHE(20);
-  COMPUTE_FOR_CACHE(19);
-  COMPUTE_FOR_CACHE(18);
-  COMPUTE_FOR_CACHE(17);
-  COMPUTE_FOR_CACHE(16);
-  COMPUTE_FOR_CACHE(15);
-  COMPUTE_FOR_CACHE(14);
-  COMPUTE_FOR_CACHE(13);
-  COMPUTE_FOR_CACHE(12);
-  COMPUTE_FOR_CACHE(11);
-  COMPUTE_FOR_CACHE(10);
-  COMPUTE_FOR_CACHE(9);
-  COMPUTE_FOR_CACHE(8);
-  COMPUTE_FOR_CACHE(7);
-  COMPUTE_FOR_CACHE(6);
-  COMPUTE_FOR_CACHE(5);
-  COMPUTE_FOR_CACHE(4);
-  COMPUTE_FOR_CACHE(3);
-  COMPUTE_FOR_CACHE(2);
-  COMPUTE_FOR_CACHE(1);
-  if (!found) {
-    UNIMPLEMENTED();
-    // Silence compiler warnings.
-    cached_power.significand = 0;
-    cached_power.binary_exponent = 0;
-    cached_power.decimal_exponent = 0;
-  }
-  *c_mk = DiyFp(cached_power.significand, cached_power.binary_exponent);
-  *mk = cached_power.decimal_exponent;
-  ASSERT((alpha <= c_mk->e() + e) && (c_mk->e() + e <= gamma));
-}
-#undef GRISU_REDUCTION
-#undef GRISU_CACHE_STRUCT
-#undef GRISU_CACHE_NAME
-#undef GRISU_CACHE_MAX_DISTANCE
-#undef GRISU_CACHE_OFFSET
-#undef GRISU_UINT64_C
+void GetCachedPowerForBinaryExponentRange(int min_exponent,
+                                          int max_exponent,
+                                          DiyFp* power,
+                                          int* decimal_exponent);
 
 } }  // namespace v8::internal
 
diff --git a/src/codegen.cc b/src/codegen.cc
index 92241d1..bda697a 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -206,10 +206,9 @@
 }
 
 
-// Generate the code. Takes a function literal, generates code for it, assemble
-// all the pieces into a Code object. This function is only to be called by
-// the compiler.cc code.
-Handle<Code> CodeGenerator::MakeCode(CompilationInfo* info) {
+// Generate the code.  Compile the AST and assemble all the pieces into a
+// Code object.
+bool CodeGenerator::MakeCode(CompilationInfo* info) {
   Handle<Script> script = info->script();
   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
     int len = String::cast(script->source())->length();
@@ -224,12 +223,14 @@
   cgen.Generate(info);
   if (cgen.HasStackOverflow()) {
     ASSERT(!Top::has_pending_exception());
-    return Handle<Code>::null();
+    return false;
   }
 
-  InLoopFlag in_loop = (cgen.loop_nesting() != 0) ? IN_LOOP : NOT_IN_LOOP;
+  InLoopFlag in_loop = info->is_in_loop() ? IN_LOOP : NOT_IN_LOOP;
   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
-  return MakeCodeEpilogue(cgen.masm(), flags, info);
+  Handle<Code> code = MakeCodeEpilogue(cgen.masm(), flags, info);
+  info->SetCode(code);  // May be an empty handle.
+  return !code.is_null();
 }
 
 
@@ -325,9 +326,12 @@
         }
       } else {
         Handle<SharedFunctionInfo> function =
-            Compiler::BuildFunctionInfo(node->fun(), script(), this);
+            Compiler::BuildFunctionInfo(node->fun(), script());
         // Check for stack-overflow exception.
-        if (HasStackOverflow()) return;
+        if (function.is_null()) {
+          SetStackOverflow();
+          return;
+        }
         array->set(j++, *function);
       }
     }
@@ -357,24 +361,19 @@
 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
 
 
-CodeGenerator::InlineFunctionGenerator
-  CodeGenerator::FindInlineFunctionGenerator(Runtime::FunctionId id) {
-    return kInlineFunctionGenerators[
-      static_cast<int>(id) - static_cast<int>(Runtime::kFirstInlineFunction)];
-}
-
-
 bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
   ZoneList<Expression*>* args = node->arguments();
   Handle<String> name = node->name();
   Runtime::Function* function = node->function();
   if (function != NULL && function->intrinsic_type == Runtime::INLINE) {
-    InlineFunctionGenerator generator =
-        FindInlineFunctionGenerator(function->function_id);
-    if (generator != NULL) {
-      ((*this).*(generator))(args);
-      return true;
-    }
+    int lookup_index = static_cast<int>(function->function_id) -
+        static_cast<int>(Runtime::kFirstInlineFunction);
+    ASSERT(lookup_index >= 0);
+    ASSERT(static_cast<size_t>(lookup_index) <
+           ARRAY_SIZE(kInlineFunctionGenerators));
+    InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
+    (this->*generator)(args);
+    return true;
   }
   return false;
 }
diff --git a/src/codegen.h b/src/codegen.h
index 2a4d9d4..8f923dd 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -62,7 +62,6 @@
 //   ComputeCallInitializeInLoop
 //   ProcessDeclarations
 //   DeclareGlobals
-//   FindInlineRuntimeLUT
 //   CheckForInlineRuntimeCall
 //   AnalyzeCondition
 //   CodeForFunctionPosition
diff --git a/src/compiler.cc b/src/compiler.cc
index 825198e..6cc0971 100755
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -27,22 +27,58 @@
 
 #include "v8.h"
 
+#include "compiler.h"
+
 #include "bootstrapper.h"
 #include "codegen-inl.h"
 #include "compilation-cache.h"
-#include "compiler.h"
 #include "data-flow.h"
 #include "debug.h"
 #include "full-codegen.h"
 #include "liveedit.h"
 #include "oprofile-agent.h"
+#include "parser.h"
 #include "rewriter.h"
-#include "scopes.h"
 #include "scopeinfo.h"
+#include "scopes.h"
 
 namespace v8 {
 namespace internal {
 
+
+CompilationInfo::CompilationInfo(Handle<Script> script)
+    : flags_(0),
+      function_(NULL),
+      scope_(NULL),
+      script_(script),
+      extension_(NULL),
+      pre_parse_data_(NULL) {
+}
+
+
+CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info)
+    : flags_(IsLazy::encode(true)),
+      function_(NULL),
+      scope_(NULL),
+      shared_info_(shared_info),
+      script_(Handle<Script>(Script::cast(shared_info->script()))),
+      extension_(NULL),
+      pre_parse_data_(NULL) {
+}
+
+
+CompilationInfo::CompilationInfo(Handle<JSFunction> closure)
+    : flags_(IsLazy::encode(true)),
+      function_(NULL),
+      scope_(NULL),
+      closure_(closure),
+      shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
+      script_(Handle<Script>(Script::cast(shared_info_->script()))),
+      extension_(NULL),
+      pre_parse_data_(NULL) {
+}
+
+
 // For normal operation the syntax checker is used to determine whether to
 // use the full compiler for top level code or not. However if the flag
 // --always-full-compiler is specified or debugging is active the full
@@ -56,102 +92,74 @@
 }
 
 
-static Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
-  FunctionLiteral* function = info->function();
-  ASSERT(function != NULL);
-  // Rewrite the AST by introducing .result assignments where needed.
-  if (!Rewriter::Process(function)) {
-    // Signal a stack overflow by returning a null handle.  The stack
-    // overflow exception will be thrown by the caller.
-    return Handle<Code>::null();
+static bool MakeCode(CompilationInfo* info) {
+  // Precondition: code has been parsed.  Postcondition: the code field in
+  // the compilation info is set if compilation succeeded.
+  ASSERT(info->function() != NULL);
+
+  if (Rewriter::Rewrite(info) &&
+      Scope::Analyze(info) &&
+      Rewriter::Analyze(info)) {
+    // Generate code and return it.  Code generator selection is governed by
+    // which backends are enabled and whether the function is considered
+    // run-once code or not.
+    //
+    // --full-compiler enables the dedicated backend for code we expect to
+    // be run once
+    //
+    // The normal choice of backend can be overridden with the flags
+    // --always-full-compiler.
+    Handle<SharedFunctionInfo> shared = info->shared_info();
+    bool is_run_once = (shared.is_null())
+        ? info->scope()->is_global_scope()
+        : (shared->is_toplevel() || shared->try_full_codegen());
+    bool can_use_full =
+        FLAG_full_compiler && !info->function()->contains_loops();
+    if (AlwaysFullCompiler() || (is_run_once && can_use_full)) {
+      return FullCodeGenerator::MakeCode(info);
+    } else {
+      AssignedVariablesAnalyzer ava;
+      return ava.Analyze(info) && CodeGenerator::MakeCode(info);
+    }
   }
 
-  {
-    // Compute top scope and allocate variables. For lazy compilation
-    // the top scope only contains the single lazily compiled function,
-    // so this doesn't re-allocate variables repeatedly.
-    HistogramTimerScope timer(&Counters::variable_allocation);
-    Scope* top = info->scope();
-    while (top->outer_scope() != NULL) top = top->outer_scope();
-    top->AllocateVariables(context);
-  }
-
-#ifdef DEBUG
-  if (Bootstrapper::IsActive() ?
-      FLAG_print_builtin_scopes :
-      FLAG_print_scopes) {
-    info->scope()->Print();
-  }
-#endif
-
-  // Optimize the AST.
-  if (!Rewriter::Optimize(function)) {
-    // Signal a stack overflow by returning a null handle.  The stack
-    // overflow exception will be thrown by the caller.
-    return Handle<Code>::null();
-  }
-
-  // Generate code and return it.  Code generator selection is governed by
-  // which backends are enabled and whether the function is considered
-  // run-once code or not:
-  //
-  //  --full-compiler enables the dedicated backend for code we expect to be
-  //    run once
-  //
-  // The normal choice of backend can be overridden with the flags
-  // --always-full-compiler.
-  Handle<SharedFunctionInfo> shared = info->shared_info();
-  bool is_run_once = (shared.is_null())
-      ? info->scope()->is_global_scope()
-      : (shared->is_toplevel() || shared->try_full_codegen());
-  bool use_full = FLAG_full_compiler && !function->contains_loops();
-  if (AlwaysFullCompiler() || (use_full && is_run_once)) {
-    return FullCodeGenerator::MakeCode(info);
-  }
-
-  AssignedVariablesAnalyzer ava(function);
-  if (!ava.Analyze()) return Handle<Code>::null();
-  return CodeGenerator::MakeCode(info);
+  return false;
 }
 
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
-Handle<Code> MakeCodeForLiveEdit(CompilationInfo* info) {
-  Handle<Context> context = Handle<Context>::null();
-  Handle<Code> code = MakeCode(context, info);
+bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) {
+  // Precondition: code has been parsed.  Postcondition: the code field in
+  // the compilation info is set if compilation succeeded.
+  bool succeeded = MakeCode(info);
   if (!info->shared_info().is_null()) {
     Handle<SerializedScopeInfo> scope_info =
         SerializedScopeInfo::Create(info->scope());
     info->shared_info()->set_scope_info(*scope_info);
   }
-  return code;
+  return succeeded;
 }
 #endif
 
 
-static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
-    bool is_eval,
-    Compiler::ValidationState validate,
-    Handle<Script> script,
-    Handle<Context> context,
-    v8::Extension* extension,
-    ScriptDataImpl* pre_data) {
+static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
   CompilationZoneScope zone_scope(DELETE_ON_EXIT);
 
   PostponeInterruptsScope postpone;
 
   ASSERT(!i::Top::global_context().is_null());
+  Handle<Script> script = info->script();
   script->set_context_data((*i::Top::global_context())->data());
 
-  bool is_json = (validate == Compiler::VALIDATE_JSON);
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  if (is_eval || is_json) {
-    script->set_compilation_type(
-        is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
-                               Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
+  if (info->is_eval() || info->is_json()) {
+    Script::CompilationType compilation_type = info->is_json()
+        ? Script::COMPILATION_TYPE_JSON
+        : 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.
-    if (is_eval) {
+    if (info->is_eval()) {
       StackTraceFrameIterator it;
       if (!it.done()) {
         script->set_eval_from_shared(
@@ -168,54 +176,47 @@
 #endif
 
   // Only allow non-global compiles for eval.
-  ASSERT(is_eval || is_global);
+  ASSERT(info->is_eval() || info->is_global());
 
-  // Build AST.
-  FunctionLiteral* lit =
-      MakeAST(is_global, script, extension, pre_data, is_json);
-
-  LiveEditFunctionTracker live_edit_tracker(lit);
-
-  // Check for parse errors.
-  if (lit == NULL) {
-    ASSERT(Top::has_pending_exception());
-    return Handle<SharedFunctionInfo>::null();
-  }
+  if (!Parser::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
   // parsing statistics.
-  HistogramTimer* rate = is_eval
+  HistogramTimer* rate = info->is_eval()
       ? &Counters::compile_eval
       : &Counters::compile;
   HistogramTimerScope timer(rate);
 
   // Compile the code.
-  CompilationInfo info(lit, script, is_eval);
-  Handle<Code> code = MakeCode(context, &info);
-
-  // Check for stack-overflow exceptions.
-  if (code.is_null()) {
+  FunctionLiteral* lit = info->function();
+  LiveEditFunctionTracker live_edit_tracker(lit);
+  if (!MakeCode(info)) {
     Top::StackOverflow();
     return Handle<SharedFunctionInfo>::null();
   }
 
+  ASSERT(!info->code().is_null());
   if (script->name()->IsString()) {
     PROFILE(CodeCreateEvent(
-        is_eval ? Logger::EVAL_TAG :
-            Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
-        *code, String::cast(script->name())));
+        info->is_eval()
+            ? Logger::EVAL_TAG
+            : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
+        *info->code(),
+        String::cast(script->name())));
     OPROFILE(CreateNativeCodeRegion(String::cast(script->name()),
-                                    code->instruction_start(),
-                                    code->instruction_size()));
+                                    info->code()->instruction_start(),
+                                    info->code()->instruction_size()));
   } else {
     PROFILE(CodeCreateEvent(
-        is_eval ? Logger::EVAL_TAG :
-            Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
-        *code, ""));
-    OPROFILE(CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
-                                    code->instruction_start(),
-                                    code->instruction_size()));
+        info->is_eval()
+            ? Logger::EVAL_TAG
+            : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
+        *info->code(),
+        ""));
+    OPROFILE(CreateNativeCodeRegion(info->is_eval() ? "Eval" : "Script",
+                                    info->code()->instruction_start(),
+                                    info->code()->instruction_size()));
   }
 
   // Allocate function.
@@ -223,8 +224,8 @@
       Factory::NewSharedFunctionInfo(
           lit->name(),
           lit->materialized_literal_count(),
-          code,
-          SerializedScopeInfo::Create(info.scope()));
+          info->code(),
+          SerializedScopeInfo::Create(info->scope()));
 
   ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
   Compiler::SetFunctionInfo(result, lit, true, script);
@@ -282,7 +283,7 @@
     if (pre_data == NULL
         && FLAG_lazy
         && source_length >= FLAG_min_preparse_length) {
-      pre_data = PartialPreParse(source, NULL, extension);
+      pre_data = Parser::PartialPreParse(source, NULL, extension);
     }
 
     // Create a script object describing the script to be compiled.
@@ -300,13 +301,11 @@
                                            : *script_data);
 
     // Compile the function and add it to the cache.
-    result = MakeFunctionInfo(true,
-                              false,
-                              DONT_VALIDATE_JSON,
-                              script,
-                              Handle<Context>::null(),
-                              extension,
-                              pre_data);
+    CompilationInfo info(script);
+    info.MarkAsGlobal();
+    info.SetExtension(extension);
+    info.SetPreParseData(pre_data);
+    result = MakeFunctionInfo(&info);
     if (extension == NULL && !result.is_null()) {
       CompilationCache::PutScript(source, result);
     }
@@ -326,9 +325,10 @@
                                                  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.
+  // 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);
 
   int source_length = source->length();
   Counters::total_eval_size.Increment(source_length);
@@ -337,27 +337,27 @@
   // The VM is in the COMPILER state until exiting this function.
   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.
+  // 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.
   Handle<SharedFunctionInfo> result;
-  if (validate == DONT_VALIDATE_JSON)
+  if (!is_json) {
     result = CompilationCache::LookupEval(source, context, is_global);
+  }
 
   if (result.is_null()) {
     // Create a script object describing the script to be compiled.
     Handle<Script> script = Factory::NewScript(source);
-    result = MakeFunctionInfo(is_global,
-                              true,
-                              validate,
-                              script,
-                              context,
-                              NULL,
-                              NULL);
-    if (!result.is_null() && validate != VALIDATE_JSON) {
-      // For json it's unlikely that we'll ever see exactly the same
-      // string again so we don't use the compilation cache.
+    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.
       CompilationCache::PutEval(source, context, is_global, result);
     }
   }
@@ -374,140 +374,122 @@
 
   PostponeInterruptsScope postpone;
 
-  // Compute name, source code and script data.
   Handle<SharedFunctionInfo> shared = info->shared_info();
-  Handle<String> name(String::cast(shared->name()));
+  int compiled_size = shared->end_position() - shared->start_position();
+  Counters::total_compile_size.Increment(compiled_size);
 
-  int start_position = shared->start_position();
-  int end_position = shared->end_position();
-  bool is_expression = shared->is_expression();
-  Counters::total_compile_size.Increment(end_position - start_position);
+  // Generate the AST for the lazily compiled function.
+  if (Parser::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.
+    HistogramTimerScope timer(&Counters::compile_lazy);
 
-  // Generate the AST for the lazily compiled function. The AST may be
-  // NULL in case of parser stack overflow.
-  FunctionLiteral* lit = MakeLazyAST(info->script(),
-                                     name,
-                                     start_position,
-                                     end_position,
-                                     is_expression);
+    // Compile the code.
+    if (!MakeCode(info)) {
+      Top::StackOverflow();
+    } else {
+      ASSERT(!info->code().is_null());
+      RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
+                                Handle<String>(shared->DebugName()),
+                                shared->start_position(),
+                                info);
 
-  // Check for parse errors.
-  if (lit == NULL) {
-    ASSERT(Top::has_pending_exception());
-    return false;
-  }
-  info->set_function(lit);
+      // Update the shared function info with the compiled code and the
+      // scope info.  Please note, that the order of the sharedfunction
+      // initialization is important since SerializedScopeInfo::Create might
+      // trigger a GC, causing the ASSERT below to be invalid if the code
+      // was flushed. By setting the code object last we avoid this.
+      Handle<SerializedScopeInfo> scope_info =
+          SerializedScopeInfo::Create(info->scope());
+      shared->set_scope_info(*scope_info);
+      shared->set_code(*info->code());
+      if (!info->closure().is_null()) {
+        info->closure()->set_code(*info->code());
+      }
 
-  // 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.
-  HistogramTimerScope timer(&Counters::compile_lazy);
+      // Set the expected number of properties for instances.
+      FunctionLiteral* lit = info->function();
+      SetExpectedNofPropertiesFromEstimate(shared,
+                                           lit->expected_property_count());
 
-  // Compile the code.
-  Handle<Code> code = MakeCode(Handle<Context>::null(), info);
+      // Set the optimization hints after performing lazy compilation, as
+      // these are not set when the function is set up as a lazily compiled
+      // function.
+      shared->SetThisPropertyAssignmentsInfo(
+          lit->has_only_simple_this_property_assignments(),
+          *lit->this_property_assignments());
 
-  // Check for stack-overflow exception.
-  if (code.is_null()) {
-    Top::StackOverflow();
-    return false;
+      // Check the function has compiled code.
+      ASSERT(shared->is_compiled());
+      shared->set_code_age(0);
+      ASSERT(!info->code().is_null());
+      return true;
+    }
   }
 
-  RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
-                            name,
-                            Handle<String>(shared->inferred_name()),
-                            start_position,
-                            info->script(),
-                            code);
-
-  // Update the shared function info with the compiled code and the scope info.
-  // Please note, that the order of the sharedfunction initialization is
-  // important since SerializedScopeInfo::Create might trigger a GC, causing
-  // the ASSERT below to be invalid if the code was flushed. By setting the code
-  // object last we avoid this.
-  Handle<SerializedScopeInfo> scope_info =
-      SerializedScopeInfo::Create(info->scope());
-  shared->set_scope_info(*scope_info);
-  shared->set_code(*code);
-  if (!info->closure().is_null()) {
-    info->closure()->set_code(*code);
-  }
-
-  // Set the expected number of properties for instances.
-  SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
-
-  // Set the optimication hints after performing lazy compilation, as these are
-  // not set when the function is set up as a lazily compiled function.
-  shared->SetThisPropertyAssignmentsInfo(
-      lit->has_only_simple_this_property_assignments(),
-      *lit->this_property_assignments());
-
-  // Check the function has compiled code.
-  ASSERT(shared->is_compiled());
-  shared->set_code_age(0);
-  return true;
+  ASSERT(info->code().is_null());
+  return false;
 }
 
 
 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
-                                                       Handle<Script> script,
-                                                       AstVisitor* caller) {
-  LiveEditFunctionTracker live_edit_tracker(literal);
+                                                       Handle<Script> script) {
 #ifdef DEBUG
   // We should not try to compile the same function literal more than
   // once.
   literal->mark_as_compiled();
 #endif
 
-  // Determine if the function can be lazily compiled. This is
-  // necessary to allow some of our builtin JS files to be lazily
-  // compiled. These builtins cannot be handled lazily by the parser,
-  // since we have to know if a function uses the special natives
-  // syntax, which is something the parser records.
+  // Precondition: code has been parsed and scopes have been analyzed.
+  CompilationInfo info(script);
+  info.SetFunction(literal);
+  info.SetScope(literal->scope());
+
+  LiveEditFunctionTracker live_edit_tracker(literal);
+  // Determine if the function can be lazily compiled. This is necessary to
+  // allow some of our builtin JS files to be lazily compiled. These
+  // builtins cannot be handled lazily by the parser, since we have to know
+  // if a function uses the special natives syntax, which is something the
+  // parser records.
   bool allow_lazy = literal->AllowsLazyCompilation() &&
       !LiveEditFunctionTracker::IsActive();
 
   Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty());
 
   // Generate code
-  Handle<Code> code;
   if (FLAG_lazy && allow_lazy) {
-    code = Handle<Code>(Builtins::builtin(Builtins::LazyCompile));
+    Handle<Code> code(Builtins::builtin(Builtins::LazyCompile));
+    info.SetCode(code);
   } else {
-    // The bodies of function literals have not yet been visited by
-    // the AST optimizer/analyzer.
-    if (!Rewriter::Optimize(literal)) {
-      return Handle<SharedFunctionInfo>::null();
-    }
-
     // Generate code and return it.  The way that the compilation mode
     // is controlled by the command-line flags is described in
     // the static helper function MakeCode.
-    CompilationInfo info(literal, script, false);
+    //
+    // The bodies of function literals have not yet been visited by
+    // the AST analyzer.
+    if (!Rewriter::Analyze(&info)) return Handle<SharedFunctionInfo>::null();
 
     bool is_run_once = literal->try_full_codegen();
     bool use_full = FLAG_full_compiler && !literal->contains_loops();
     if (AlwaysFullCompiler() || (use_full && is_run_once)) {
-      code = FullCodeGenerator::MakeCode(&info);
+      if (!FullCodeGenerator::MakeCode(&info)) {
+        return Handle<SharedFunctionInfo>::null();
+      }
     } else {
       // We fall back to the classic V8 code generator.
-      AssignedVariablesAnalyzer ava(literal);
-      if (!ava.Analyze()) return Handle<SharedFunctionInfo>::null();
-      code = CodeGenerator::MakeCode(&info);
-    }
-
-    // Check for stack-overflow exception.
-    if (code.is_null()) {
-      caller->SetStackOverflow();
-      return Handle<SharedFunctionInfo>::null();
+      AssignedVariablesAnalyzer ava;
+      if (!ava.Analyze(&info)) return Handle<SharedFunctionInfo>::null();
+      if (!CodeGenerator::MakeCode(&info)) {
+        return Handle<SharedFunctionInfo>::null();
+      }
     }
 
     // Function compilation complete.
     RecordFunctionCompilation(Logger::FUNCTION_TAG,
-                              literal->name(),
-                              literal->inferred_name(),
+                              literal->debug_name(),
                               literal->start_position(),
-                              script,
-                              code);
+                              &info);
     scope_info = SerializedScopeInfo::Create(info.scope());
   }
 
@@ -515,7 +497,7 @@
   Handle<SharedFunctionInfo> result =
       Factory::NewSharedFunctionInfo(literal->name(),
                                      literal->materialized_literal_count(),
-                                     code,
+                                     info.code(),
                                      scope_info);
   SetFunctionInfo(result, literal, false, script);
 
@@ -555,32 +537,34 @@
 
 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
                                          Handle<String> name,
-                                         Handle<String> inferred_name,
                                          int start_position,
-                                         Handle<Script> script,
-                                         Handle<Code> code) {
-  // Log the code generation. If source information is available
-  // include script name and line number. Check explicitly whether
-  // logging is enabled as finding the line number is not free.
-  if (Logger::is_logging()
-      || OProfileAgent::is_enabled()
-      || CpuProfiler::is_profiling()) {
-    Handle<String> func_name(name->length() > 0 ? *name : *inferred_name);
+                                         CompilationInfo* info) {
+  // Log the code generation. If source information is available include
+  // script name and line number. Check explicitly whether logging is
+  // enabled as finding the line number is not free.
+  if (Logger::is_logging() ||
+      OProfileAgent::is_enabled() ||
+      CpuProfiler::is_profiling()) {
+    Handle<Script> script = info->script();
+    Handle<Code> code = info->code();
     if (script->name()->IsString()) {
       int line_num = GetScriptLineNumber(script, start_position) + 1;
       USE(line_num);
       PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
-                              *code, *func_name,
-                              String::cast(script->name()), line_num));
-      OPROFILE(CreateNativeCodeRegion(*func_name,
+                              *code,
+                              *name,
+                              String::cast(script->name()),
+                              line_num));
+      OPROFILE(CreateNativeCodeRegion(*name,
                                       String::cast(script->name()),
                                       line_num,
                                       code->instruction_start(),
                                       code->instruction_size()));
     } else {
       PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
-                              *code, *func_name));
-      OPROFILE(CreateNativeCodeRegion(*func_name,
+                              *code,
+                              *name));
+      OPROFILE(CreateNativeCodeRegion(*name,
                                       code->instruction_start(),
                                       code->instruction_size()));
     }
diff --git a/src/compiler.h b/src/compiler.h
index ed26603..d6f4e69 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -30,127 +30,111 @@
 
 #include "ast.h"
 #include "frame-element.h"
-#include "parser.h"
 #include "register-allocator.h"
 #include "zone.h"
 
 namespace v8 {
 namespace internal {
 
+class ScriptDataImpl;
+
 // CompilationInfo encapsulates some information known at compile time.  It
 // is constructed based on the resources available at compile-time.
 class CompilationInfo BASE_EMBEDDED {
  public:
-  // Lazy compilation of a JSFunction.
-  CompilationInfo(Handle<JSFunction> closure,
-                  int loop_nesting,
-                  Handle<Object> receiver)
-      : closure_(closure),
-        function_(NULL),
-        is_eval_(false),
-        loop_nesting_(loop_nesting),
-        receiver_(receiver) {
-    Initialize();
-    ASSERT(!closure_.is_null() &&
-           shared_info_.is_null() &&
-           script_.is_null());
+  explicit CompilationInfo(Handle<Script> script);
+  explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info);
+  explicit CompilationInfo(Handle<JSFunction> closure);
+
+  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_; }
+  Handle<Code> code() const { return code_; }
+  Handle<JSFunction> closure() const { return closure_; }
+  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
+  Handle<Script> script() const { return script_; }
+  v8::Extension* extension() const { return extension_; }
+  ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
+  Handle<Context> calling_context() const { return calling_context_; }
+
+  void MarkAsEval() {
+    ASSERT(!is_lazy());
+    flags_ |= IsEval::encode(true);
   }
-
-  // Lazy compilation based on SharedFunctionInfo.
-  explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info)
-      : shared_info_(shared_info),
-        function_(NULL),
-        is_eval_(false),
-        loop_nesting_(0) {
-    Initialize();
-    ASSERT(closure_.is_null() &&
-           !shared_info_.is_null() &&
-           script_.is_null());
+  void MarkAsGlobal() {
+    ASSERT(!is_lazy());
+    flags_ |= IsGlobal::encode(true);
   }
-
-  // Eager compilation.
-  CompilationInfo(FunctionLiteral* literal, Handle<Script> script, bool is_eval)
-      : script_(script),
-        function_(literal),
-        is_eval_(is_eval),
-        loop_nesting_(0) {
-    Initialize();
-    ASSERT(closure_.is_null() &&
-           shared_info_.is_null() &&
-           !script_.is_null());
+  void MarkAsJson() {
+    ASSERT(!is_lazy());
+    flags_ |= IsJson::encode(true);
   }
-
-  // We can only get a JSFunction if we actually have one.
-  Handle<JSFunction> closure() { return closure_; }
-
-  // We can get a SharedFunctionInfo from a JSFunction or if we actually
-  // have one.
-  Handle<SharedFunctionInfo> shared_info() {
-    if (!closure().is_null()) {
-      return Handle<SharedFunctionInfo>(closure()->shared());
-    } else {
-      return shared_info_;
-    }
+  void MarkAsInLoop() {
+    ASSERT(is_lazy());
+    flags_ |= IsInLoop::encode(true);
   }
-
-  // We can always get a script.  Either we have one or we can get a shared
-  // function info.
-  Handle<Script> script() {
-    if (!script_.is_null()) {
-      return script_;
-    } else {
-      ASSERT(shared_info()->script()->IsScript());
-      return Handle<Script>(Script::cast(shared_info()->script()));
-    }
+  void SetFunction(FunctionLiteral* literal) {
+    ASSERT(function_ == NULL);
+    function_ = literal;
   }
-
-  // There should always be a function literal, but it may be set after
-  // construction (for lazy compilation).
-  FunctionLiteral* function() { return function_; }
-  void set_function(FunctionLiteral* literal) { function_ = literal; }
-
-  // Simple accessors.
-  bool is_eval() { return is_eval_; }
-  int loop_nesting() { return loop_nesting_; }
-  bool has_receiver() { return !receiver_.is_null(); }
-  Handle<Object> receiver() { return receiver_; }
-
-  bool has_this_properties() { return has_this_properties_; }
-  void set_has_this_properties(bool flag) { has_this_properties_ = flag; }
-
-  bool has_global_object() {
-    return !closure().is_null() && (closure()->context()->global() != NULL);
+  void SetScope(Scope* scope) {
+    ASSERT(scope_ == NULL);
+    scope_ = scope;
   }
-
-  GlobalObject* global_object() {
-    return has_global_object() ? closure()->context()->global() : NULL;
+  void SetCode(Handle<Code> code) { code_ = code; }
+  void SetExtension(v8::Extension* extension) {
+    ASSERT(!is_lazy());
+    extension_ = extension;
   }
-
-  bool has_globals() { return has_globals_; }
-  void set_has_globals(bool flag) { has_globals_ = flag; }
-
-  // Derived accessors.
-  Scope* scope() { return function()->scope(); }
+  void SetPreParseData(ScriptDataImpl* pre_parse_data) {
+    ASSERT(!is_lazy());
+    pre_parse_data_ = pre_parse_data;
+  }
+  void SetCallingContext(Handle<Context> context) {
+    ASSERT(is_eval());
+    calling_context_ = context;
+  }
 
  private:
-  void Initialize() {
-    has_this_properties_ = false;
-    has_globals_ = false;
-  }
+  // Flags using template class BitField<type, start, length>.  All are
+  // false by default.
+  //
+  // Compilation is either eager or lazy.
+  class IsLazy:   public BitField<bool, 0, 1> {};
+  // 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> {};
 
+  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
+  // that scopes have been analyzed.
+  Scope* scope_;
+  // The compiled code.
+  Handle<Code> code_;
+
+  // Possible initial inputs to the compilation process.
   Handle<JSFunction> closure_;
   Handle<SharedFunctionInfo> shared_info_;
   Handle<Script> script_;
 
-  FunctionLiteral* function_;
+  // Fields possibly needed for eager compilation, NULL by default.
+  v8::Extension* extension_;
+  ScriptDataImpl* pre_parse_data_;
 
-  bool is_eval_;
-  int loop_nesting_;
-
-  Handle<Object> receiver_;
-
-  bool has_this_properties_;
-  bool has_globals_;
+  // The context of the caller is needed for eval code, and will be a null
+  // handle otherwise.
+  Handle<Context> calling_context_;
 
   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
 };
@@ -163,13 +147,13 @@
 // functions, they will be compiled and allocated as part of the compilation
 // of the source code.
 
-// Please note this interface returns shared function infos.
-// This means you need to call Factory::NewFunctionFromSharedFunctionInfo
-// before you have a real function with a context.
+// Please note this interface returns shared function infos.  This means you
+// need to call Factory::NewFunctionFromSharedFunctionInfo before you have a
+// real function with a context.
 
 class Compiler : public AllStatic {
  public:
-  enum ValidationState { VALIDATE_JSON, DONT_VALIDATE_JSON };
+  enum ValidationState { DONT_VALIDATE_JSON, VALIDATE_JSON };
 
   // All routines return a JSFunction.
   // If an error occurs an exception is raised and
@@ -191,17 +175,14 @@
                                                 bool is_global,
                                                 ValidationState validation);
 
-  // Compile from function info (used for lazy compilation). Returns
-  // true on success and false if the compilation resulted in a stack
-  // overflow.
+  // Compile from function info (used for lazy compilation). Returns true on
+  // success and false if the compilation resulted in a stack overflow.
   static bool CompileLazy(CompilationInfo* info);
 
-  // Compile a shared function info object (the function is possibly
-  // lazily compiled). Called recursively from a backend code
-  // generator 'caller' to build the shared function info.
+  // Compile a shared function info object (the function is possibly lazily
+  // compiled).
   static Handle<SharedFunctionInfo> BuildFunctionInfo(FunctionLiteral* node,
-                                                      Handle<Script> script,
-                                                      AstVisitor* caller);
+                                                      Handle<Script> script);
 
   // Set the function info for a newly compiled function.
   static void SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
@@ -209,23 +190,18 @@
                               bool is_toplevel,
                               Handle<Script> script);
 
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  static bool MakeCodeForLiveEdit(CompilationInfo* info);
+#endif
+
  private:
   static void RecordFunctionCompilation(Logger::LogEventsAndTags tag,
                                         Handle<String> name,
-                                        Handle<String> inferred_name,
                                         int start_position,
-                                        Handle<Script> script,
-                                        Handle<Code> code);
+                                        CompilationInfo* info);
 };
 
 
-#ifdef ENABLE_DEBUGGER_SUPPORT
-
-Handle<Code> MakeCodeForLiveEdit(CompilationInfo* info);
-
-#endif
-
-
 // During compilation we need a global list of handles to constants
 // for frame elements.  When the zone gets deleted, we make sure to
 // clear this list of handles as well.
diff --git a/src/contexts.cc b/src/contexts.cc
index 723354f..1ce5007 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -90,7 +90,7 @@
 
   do {
     if (FLAG_trace_contexts) {
-      PrintF(" - looking in context %p", *context);
+      PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
       if (context->IsGlobalContext()) PrintF(" (global context)");
       PrintF("\n");
     }
@@ -110,7 +110,8 @@
       if (*attributes != ABSENT) {
         // property found
         if (FLAG_trace_contexts) {
-          PrintF("=> found property in context object %p\n", *extension);
+          PrintF("=> found property in context object %p\n",
+                 reinterpret_cast<void*>(*extension));
         }
         return extension;
       }
diff --git a/src/contexts.h b/src/contexts.h
index 78dda6a..9722a93 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -225,7 +225,15 @@
     OUT_OF_MEMORY_INDEX,
     MAP_CACHE_INDEX,
     CONTEXT_DATA_INDEX,
-    GLOBAL_CONTEXT_SLOTS
+
+    // Properties from here are treated as weak references by the full GC.
+    // Scavenge treats them as strong references.
+    NEXT_CONTEXT_LINK,
+
+    // Total number of slots.
+    GLOBAL_CONTEXT_SLOTS,
+
+    FIRST_WEAK_SLOT = NEXT_CONTEXT_LINK
   };
 
   // Direct slot access.
@@ -333,6 +341,17 @@
     return kHeaderSize + index * kPointerSize - kHeapObjectTag;
   }
 
+  static const int kSize = kHeaderSize + GLOBAL_CONTEXT_SLOTS * kPointerSize;
+
+  // GC support.
+  typedef FixedBodyDescriptor<
+      kHeaderSize, kSize, kSize> ScavengeBodyDescriptor;
+
+  typedef FixedBodyDescriptor<
+      kHeaderSize,
+      kHeaderSize + FIRST_WEAK_SLOT * kPointerSize,
+      kSize> MarkCompactBodyDescriptor;
+
  private:
   // Unchecked access to the slots.
   Object* unchecked_previous() { return get(PREVIOUS_INDEX); }
diff --git a/src/conversions.cc b/src/conversions.cc
index f15a804..790e807 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -34,6 +34,7 @@
 #include "dtoa.h"
 #include "factory.h"
 #include "scanner.h"
+#include "strtod.h"
 
 namespace v8 {
 namespace internal {
@@ -103,8 +104,6 @@
 }
 
 
-extern "C" double gay_strtod(const char* s00, const char** se);
-
 // Maximum number of significant digits in decimal representation.
 // The longest possible double in decimal representation is
 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
@@ -353,8 +352,9 @@
     }
 
     ASSERT(buffer_pos < kBufferSize);
-    buffer[buffer_pos++] = '\0';
-    return sign ? -gay_strtod(buffer, NULL) : gay_strtod(buffer, NULL);
+    buffer[buffer_pos] = '\0';
+    Vector<const char> buffer_vector(buffer, buffer_pos);
+    return sign ? -Strtod(buffer_vector, 0) : Strtod(buffer_vector, 0);
   }
 
   // The following code causes accumulating rounding error for numbers greater
@@ -462,7 +462,6 @@
     ++current;
     if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
   } else if (*current == '-') {
-    buffer[buffer_pos++] = '-';
     ++current;
     if (!AdvanceToNonspace(&current, end)) return JUNK_STRING_VALUE;
     sign = true;
@@ -478,8 +477,8 @@
       return JUNK_STRING_VALUE;
     }
 
-    ASSERT(buffer_pos == 0 || buffer[0] == '-');
-    return buffer_pos > 0 ? -V8_INFINITY : V8_INFINITY;
+    ASSERT(buffer_pos == 0);
+    return sign ? -V8_INFINITY : V8_INFINITY;
   }
 
   bool leading_zero = false;
@@ -496,7 +495,6 @@
         return JUNK_STRING_VALUE;  // "0x".
       }
 
-      bool sign = (buffer_pos > 0 && buffer[0] == '-');
       return InternalStringToIntDouble<4>(current,
                                           end,
                                           sign,
@@ -533,6 +531,9 @@
   }
 
   if (*current == '.') {
+    if (octal && !allow_trailing_junk) return JUNK_STRING_VALUE;
+    if (octal) goto parsing_done;
+
     ++current;
     if (current == end) {
       if (significant_digits == 0 && !leading_zero) {
@@ -553,16 +554,16 @@
       }
     }
 
-    ASSERT(buffer_pos < kBufferSize);
-    buffer[buffer_pos++] = '.';
+    // We don't emit a '.', but adjust the exponent instead.
     fractional_part = true;
 
-    // There is the fractional part.
+    // There is a fractional part.
     while (*current >= '0' && *current <= '9') {
       if (significant_digits < kMaxSignificantDigits) {
         ASSERT(buffer_pos < kBufferSize);
         buffer[buffer_pos++] = static_cast<char>(*current);
         significant_digits++;
+        exponent--;
       } else {
         // Ignore insignificant digits in the fractional part.
         nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
@@ -638,60 +639,25 @@
   exponent += insignificant_digits;
 
   if (octal) {
-    bool sign = buffer[0] == '-';
-    int start_pos = (sign ? 1 : 0);
-
-    return InternalStringToIntDouble<3>(buffer + start_pos,
+    return InternalStringToIntDouble<3>(buffer,
                                         buffer + buffer_pos,
                                         sign,
                                         allow_trailing_junk);
   }
 
   if (nonzero_digit_dropped) {
-    if (insignificant_digits) buffer[buffer_pos++] = '.';
     buffer[buffer_pos++] = '1';
-  }
-
-  // If the number has no more than kMaxDigitsInInt digits and doesn't have
-  // fractional part it could be parsed faster (without checks for
-  // spaces, overflow, etc.).
-  const int kMaxDigitsInInt = 9 * sizeof(int) / 4;  // NOLINT
-
-  if (exponent != 0) {
-    ASSERT(buffer_pos < kBufferSize);
-    buffer[buffer_pos++] = 'e';
-    if (exponent < 0) {
-      ASSERT(buffer_pos < kBufferSize);
-      buffer[buffer_pos++] = '-';
-      exponent = -exponent;
-    }
-    if (exponent > 999) exponent = 999;  // Result will be Infinity or 0 or -0.
-
-    const int exp_digits = 3;
-    for (int i = 0; i < exp_digits; i++) {
-      buffer[buffer_pos + exp_digits - 1 - i] = '0' + exponent % 10;
-      exponent /= 10;
-    }
-    ASSERT(exponent == 0);
-    buffer_pos += exp_digits;
-  } else if (!fractional_part && significant_digits <= kMaxDigitsInInt) {
-    if (significant_digits == 0) return SignedZero(sign);
-    ASSERT(buffer_pos > 0);
-    int num = 0;
-    int start_pos = (buffer[0] == '-' ? 1 : 0);
-    for (int i = start_pos; i < buffer_pos; i++) {
-      ASSERT(buffer[i] >= '0' && buffer[i] <= '9');
-      num = 10 * num + (buffer[i] - '0');
-    }
-    return static_cast<double>(start_pos == 0 ? num : -num);
+    exponent--;
   }
 
   ASSERT(buffer_pos < kBufferSize);
   buffer[buffer_pos] = '\0';
 
-  return gay_strtod(buffer, NULL);
+  double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
+  return sign? -converted: converted;
 }
 
+
 double StringToDouble(String* str, int flags, double empty_string_val) {
   StringShape shape(str);
   if (shape.IsSequentialAscii()) {
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index acf3349..da19a45 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -188,6 +188,20 @@
 }
 
 
+void ProfilerEventsProcessor::ProcessMovedFunctions() {
+  for (int i = 0; i < moved_functions_.length(); ++i) {
+    JSFunction* function = moved_functions_[i];
+    CpuProfiler::FunctionCreateEvent(function);
+  }
+  moved_functions_.Clear();
+}
+
+
+void ProfilerEventsProcessor::RememberMovedFunction(JSFunction* function) {
+  moved_functions_.Add(function);
+}
+
+
 void ProfilerEventsProcessor::RegExpCodeCreateEvent(
     Logger::LogEventsAndTags tag,
     const char* prefix,
@@ -426,8 +440,12 @@
 }
 
 
-void CpuProfiler::FunctionCreateEventFromMove(JSFunction* function,
-                                              HeapObject* source) {
+void CpuProfiler::ProcessMovedFunctions() {
+  singleton_->processor_->ProcessMovedFunctions();
+}
+
+
+void CpuProfiler::FunctionCreateEventFromMove(JSFunction* function) {
   // This function is called from GC iterators (during Scavenge,
   // MC, and MS), so marking bits can be set on objects. That's
   // why unchecked accessors are used here.
@@ -436,27 +454,7 @@
   if (function->unchecked_code() == Builtins::builtin(Builtins::LazyCompile)
       || singleton_->processor_->IsKnownFunction(function->address())) return;
 
-  int security_token_id = TokenEnumerator::kNoSecurityToken;
-  // In debug mode, assertions may fail for contexts,
-  // and we can live without security tokens in debug mode.
-#ifndef DEBUG
-  if (function->unchecked_context()->IsContext()) {
-    security_token_id = singleton_->token_enumerator_->GetTokenId(
-        function->context()->global_context()->security_token());
-  }
-  // Security token may not be moved yet.
-  if (security_token_id == TokenEnumerator::kNoSecurityToken) {
-    JSFunction* old_function = reinterpret_cast<JSFunction*>(source);
-    if (old_function->unchecked_context()->IsContext()) {
-      security_token_id = singleton_->token_enumerator_->GetTokenId(
-          old_function->context()->global_context()->security_token());
-    }
-  }
-#endif
-  singleton_->processor_->FunctionCreateEvent(
-      function->address(),
-      function->unchecked_code()->address(),
-      security_token_id);
+  singleton_->processor_->RememberMovedFunction(function);
 }
 
 
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index 86f9f67..d3158d7 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -165,6 +165,8 @@
   // Puts current stack into tick sample events buffer.
   void AddCurrentStack();
   bool IsKnownFunction(Address start);
+  void ProcessMovedFunctions();
+  void RememberMovedFunction(JSFunction* function);
 
   // Tick sample events are filled directly in the buffer of the circular
   // queue (because the structure is of fixed width, but usually not all
@@ -202,6 +204,7 @@
 
   // Used from the VM thread.
   HashMap* known_functions_;
+  List<JSFunction*> moved_functions_;
 };
 
 } }  // namespace v8::internal
@@ -251,17 +254,18 @@
                               String* source, int line);
   static void CodeCreateEvent(Logger::LogEventsAndTags tag,
                               Code* code, int args_count);
+  static void CodeMovingGCEvent() {}
   static void CodeMoveEvent(Address from, Address to);
   static void CodeDeleteEvent(Address from);
   static void FunctionCreateEvent(JSFunction* function);
   // Reports function creation in case we had missed it (e.g.
   // if it was created from compiled code).
-  static void FunctionCreateEventFromMove(JSFunction* function,
-                                          HeapObject* source);
+  static void FunctionCreateEventFromMove(JSFunction* function);
   static void FunctionMoveEvent(Address from, Address to);
   static void FunctionDeleteEvent(Address from);
   static void GetterCallbackEvent(String* name, Address entry_point);
   static void RegExpCodeCreateEvent(Code* code, String* source);
+  static void ProcessMovedFunctions();
   static void SetterCallbackEvent(String* name, Address entry_point);
 
   static INLINE(bool is_profiling()) {
diff --git a/src/d8.js b/src/d8.js
index 5c3da13..a758e09 100644
--- a/src/d8.js
+++ b/src/d8.js
@@ -949,7 +949,7 @@
       case 'suspend':
         details.text = 'stopped';
         break;
-        
+
       case 'setbreakpoint':
         result = 'set breakpoint #';
         result += body.breakpoint;
@@ -961,7 +961,7 @@
         result += body.breakpoint;
         details.text = result;
         break;
-        
+
       case 'listbreakpoints':
         result = 'breakpoints: (' + body.breakpoints.length + ')';
         for (var i = 0; i < body.breakpoints.length; i++) {
diff --git a/src/data-flow.cc b/src/data-flow.cc
index 44a1050..be82446 100644
--- a/src/data-flow.cc
+++ b/src/data-flow.cc
@@ -42,7 +42,7 @@
     if (Contains(i)) {
       if (!first) PrintF(",");
       first = false;
-      PrintF("%d");
+      PrintF("%d", i);
     }
   }
   PrintF("}");
@@ -50,12 +50,13 @@
 #endif
 
 
-bool AssignedVariablesAnalyzer::Analyze() {
-  Scope* scope = fun_->scope();
+bool AssignedVariablesAnalyzer::Analyze(CompilationInfo* info) {
+  info_ = info;
+  Scope* scope = info->scope();
   int variables = scope->num_parameters() + scope->num_stack_slots();
   if (variables == 0) return true;
   av_.ExpandTo(variables);
-  VisitStatements(fun_->body());
+  VisitStatements(info->function()->body());
   return !HasStackOverflow();
 }
 
@@ -129,7 +130,7 @@
   if (slot->type() == Slot::PARAMETER) {
     return slot->index();
   } else {
-    return fun_->scope()->num_parameters() + slot->index();
+    return info_->scope()->num_parameters() + slot->index();
   }
 }
 
diff --git a/src/data-flow.h b/src/data-flow.h
index 540db16..efce1ea 100644
--- a/src/data-flow.h
+++ b/src/data-flow.h
@@ -198,8 +198,8 @@
 // is guaranteed to be a smi.
 class AssignedVariablesAnalyzer : public AstVisitor {
  public:
-  explicit AssignedVariablesAnalyzer(FunctionLiteral* fun) : fun_(fun) { }
-  bool Analyze();
+  explicit AssignedVariablesAnalyzer() : info_(NULL) { }
+  bool Analyze(CompilationInfo* info);
 
  private:
   Variable* FindSmiLoopVariable(ForStatement* stmt);
@@ -219,7 +219,7 @@
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
-  FunctionLiteral* fun_;
+  CompilationInfo* info_;
 
   // Accumulator for assigned variables set.
   BitVector av_;
diff --git a/src/date.js b/src/date.js
index b101ea6..9601470 100644
--- a/src/date.js
+++ b/src/date.js
@@ -246,7 +246,7 @@
 
 
 var ltcache = {
-  key: null, 
+  key: null,
   val: null
 };
 
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index 34eb0f0..a0c6808 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -2118,7 +2118,7 @@
   }
   var script_id = request.arguments.script_id;
   var preview_only = !!request.arguments.preview_only;
-  
+
   var scripts = %DebugGetLoadedScripts();
 
   var the_script = null;
@@ -2139,11 +2139,11 @@
   }
 
   var new_source = request.arguments.new_source;
-  
+
   var result_description = Debug.LiveEdit.SetScriptSource(the_script,
       new_source, preview_only, change_log);
   response.body = {change_log: change_log, result: result_description};
-  
+
   if (!preview_only && !this.running_ && result_description.stack_modified) {
     response.body.stepin_recommended = true;
   }
diff --git a/src/disassembler.cc b/src/disassembler.cc
index e79421f..2a4ea74 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -44,7 +44,10 @@
 void Disassembler::Dump(FILE* f, byte* begin, byte* end) {
   for (byte* pc = begin; pc < end; pc++) {
     if (f == NULL) {
-      PrintF("%" V8PRIxPTR "  %4" V8PRIdPTR "  %02x\n", pc, pc - begin, *pc);
+      PrintF("%" V8PRIxPTR "  %4" V8PRIdPTR "  %02x\n",
+             reinterpret_cast<intptr_t>(pc),
+             pc - begin,
+             *pc);
     } else {
       fprintf(f, "%" V8PRIxPTR "  %4" V8PRIdPTR "  %02x\n",
               reinterpret_cast<uintptr_t>(pc), pc - begin, *pc);
diff --git a/src/execution.cc b/src/execution.cc
index 5421678..6862324 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -473,6 +473,19 @@
 #undef RETURN_NATIVE_CALL
 
 
+Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
+                                        Handle<String> flags,
+                                        bool* exc) {
+  Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
+      Handle<JSFunction>(Top::global_context()->regexp_function()),
+      pattern,
+      flags,
+      exc);
+  if (*exc) return Handle<JSRegExp>();
+  return Handle<JSRegExp>::cast(re_obj);
+}
+
+
 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
   int int_index = static_cast<int>(index);
   if (int_index < 0 || int_index >= string->length()) {
diff --git a/src/execution.h b/src/execution.h
index 2823503..15d85ef 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -105,6 +105,11 @@
   // Create a new date object from 'time'.
   static Handle<Object> NewDate(double time, bool* exc);
 
+  // Create a new regular expression object from 'pattern' and 'flags'.
+  static Handle<JSRegExp> NewJSRegExp(Handle<String> pattern,
+                                      Handle<String> flags,
+                                      bool* exc);
+
   // Used to implement [] notation on strings (calls JS code)
   static Handle<Object> CharAt(Handle<String> str, uint32_t index);
 
diff --git a/src/fast-dtoa.cc b/src/fast-dtoa.cc
index d2a00cc..ce825f9 100644
--- a/src/fast-dtoa.cc
+++ b/src/fast-dtoa.cc
@@ -609,8 +609,13 @@
   ASSERT(boundary_plus.e() == w.e());
   DiyFp ten_mk;  // Cached power of ten: 10^-k
   int mk;        // -k
-  GetCachedPower(w.e() + DiyFp::kSignificandSize, kMinimalTargetExponent,
-                 kMaximalTargetExponent, &mk, &ten_mk);
+  int ten_mk_minimal_binary_exponent =
+     kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  int ten_mk_maximal_binary_exponent =
+     kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  GetCachedPowerForBinaryExponentRange(ten_mk_minimal_binary_exponent,
+                                       ten_mk_maximal_binary_exponent,
+                                       &ten_mk, &mk);
   ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
           DiyFp::kSignificandSize) &&
          (kMaximalTargetExponent >= w.e() + ten_mk.e() +
@@ -662,8 +667,13 @@
   DiyFp w = Double(v).AsNormalizedDiyFp();
   DiyFp ten_mk;  // Cached power of ten: 10^-k
   int mk;        // -k
-  GetCachedPower(w.e() + DiyFp::kSignificandSize, kMinimalTargetExponent,
-                 kMaximalTargetExponent, &mk, &ten_mk);
+  int ten_mk_minimal_binary_exponent =
+     kMinimalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  int ten_mk_maximal_binary_exponent =
+     kMaximalTargetExponent - (w.e() + DiyFp::kSignificandSize);
+  GetCachedPowerForBinaryExponentRange(ten_mk_minimal_binary_exponent,
+                                       ten_mk_maximal_binary_exponent,
+                                       &ten_mk, &mk);
   ASSERT((kMinimalTargetExponent <= w.e() + ten_mk.e() +
           DiyFp::kSignificandSize) &&
          (kMaximalTargetExponent >= w.e() + ten_mk.e() +
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 263a2a4..2474c62 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -108,6 +108,8 @@
             "enable use of SSE2 instructions if available")
 DEFINE_bool(enable_sse3, true,
             "enable use of SSE3 instructions if available")
+DEFINE_bool(enable_sse4_1, true,
+            "enable use of SSE4.1 instructions if available")
 DEFINE_bool(enable_cmov, true,
             "enable use of CMOV instruction if available")
 DEFINE_bool(enable_rdtsc, true,
@@ -179,8 +181,8 @@
             "always inline smi code in non-opt code")
 
 // heap.cc
-DEFINE_int(max_new_space_size, 0, "max size of the new generation")
-DEFINE_int(max_old_space_size, 0, "max size of the old generation")
+DEFINE_int(max_new_space_size, 0, "max size of the new generation (in kBytes)")
+DEFINE_int(max_old_space_size, 0, "max size of the old generation (in Mbytes)")
 DEFINE_bool(gc_global, false, "always perform global GCs")
 DEFINE_int(gc_interval, -1, "garbage collect after <n> allocations")
 DEFINE_bool(trace_gc, false,
@@ -410,6 +412,7 @@
             "Update sliding state window counters.")
 DEFINE_string(logfile, "v8.log", "Specify the name of the log file.")
 DEFINE_bool(oprofile, false, "Enable JIT agent for OProfile.")
+DEFINE_bool(ll_prof, false, "Enable low-level linux profiler.")
 
 //
 // Heap protection flags
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index fa835cb..97987c2 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -277,7 +277,7 @@
 
 #define __ ACCESS_MASM(masm())
 
-Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
+bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
   Handle<Script> script = info->script();
   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
     int len = String::cast(script->source())->length();
@@ -291,10 +291,13 @@
   cgen.Generate(info);
   if (cgen.HasStackOverflow()) {
     ASSERT(!Top::has_pending_exception());
-    return Handle<Code>::null();
+    return false;
   }
+
   Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP);
-  return CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
+  Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
+  info->SetCode(code);  // may be an empty handle.
+  return !code.is_null();
 }
 
 
@@ -462,9 +465,12 @@
           }
         } else {
           Handle<SharedFunctionInfo> function =
-              Compiler::BuildFunctionInfo(decl->fun(), script(), this);
+              Compiler::BuildFunctionInfo(decl->fun(), script());
           // Check for stack-overflow exception.
-          if (HasStackOverflow()) return;
+          if (function.is_null()) {
+            SetStackOverflow();
+            return;
+          }
           array->set(j++, *function);
         }
       }
@@ -1122,9 +1128,14 @@
   __ bind(&true_case);
   SetExpressionPosition(expr->then_expression(),
                         expr->then_expression_position());
-  Visit(expr->then_expression());
-  // If control flow falls through Visit, jump to done.
-  if (!context()->IsTest()) {
+  if (context()->IsTest()) {
+    const TestContext* for_test = TestContext::cast(context());
+    VisitForControl(expr->then_expression(),
+                    for_test->true_label(),
+                    for_test->false_label(),
+                    NULL);
+  } else {
+    Visit(expr->then_expression());
     __ jmp(&done);
   }
 
@@ -1156,8 +1167,11 @@
 
   // Build the function boilerplate and instantiate it.
   Handle<SharedFunctionInfo> function_info =
-      Compiler::BuildFunctionInfo(expr, script(), this);
-  if (HasStackOverflow()) return;
+      Compiler::BuildFunctionInfo(expr, script());
+  if (function_info.is_null()) {
+    SetStackOverflow();
+    return;
+  }
   EmitNewClosure(function_info);
 }
 
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 03024e1..201507b 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -74,7 +74,7 @@
         context_(NULL) {
   }
 
-  static Handle<Code> MakeCode(CompilationInfo* info);
+  static bool MakeCode(CompilationInfo* info);
 
   void Generate(CompilationInfo* info);
 
@@ -604,6 +604,15 @@
           false_label_(false_label),
           fall_through_(fall_through) { }
 
+    static const TestContext* cast(const ExpressionContext* context) {
+      ASSERT(context->IsTest());
+      return reinterpret_cast<const TestContext*>(context);
+    }
+
+    Label* true_label() const { return true_label_; }
+    Label* false_label() const { return false_label_; }
+    Label* fall_through() const { return fall_through_; }
+
     virtual void Plug(bool flag) const;
     virtual void Plug(Register reg) const;
     virtual void Plug(Label* materialize_true, Label* materialize_false) const;
diff --git a/src/global-handles.cc b/src/global-handles.cc
index a909caf..0207322 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -486,7 +486,7 @@
   }
 
   PrintF("Global Handle Statistics:\n");
-  PrintF("  allocated memory = %dB\n", sizeof(Node) * total);
+  PrintF("  allocated memory = %" V8_PTR_PREFIX "dB\n", sizeof(Node) * total);
   PrintF("  # weak       = %d\n", weak);
   PrintF("  # pending    = %d\n", pending);
   PrintF("  # near_death = %d\n", near_death);
@@ -497,8 +497,10 @@
 void GlobalHandles::Print() {
   PrintF("Global handles:\n");
   for (Node* current = head_; current != NULL; current = current->next()) {
-    PrintF("  handle %p to %p (weak=%d)\n", current->handle().location(),
-           *current->handle(), current->state_ == Node::WEAK);
+    PrintF("  handle %p to %p (weak=%d)\n",
+           reinterpret_cast<void*>(current->handle().location()),
+           reinterpret_cast<void*>(*current->handle()),
+           current->state_ == Node::WEAK);
   }
 }
 
diff --git a/src/handles.cc b/src/handles.cc
index 78a7fcf..8fe29bb 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -175,7 +175,7 @@
 
   // Inobject slack tracking will reclaim redundant inobject space later,
   // so we can afford to adjust the estimate generously.
-  return estimate + 6;
+  return estimate + 8;
 }
 
 
@@ -635,8 +635,19 @@
 }
 
 
+static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
+  int len = array->length();
+  for (int i = 0; i < len; i++) {
+    Object* e = array->get(i);
+    if (!(e->IsString() || e->IsNumber())) return false;
+  }
+  return true;
+}
+
+
 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object,
                                           KeyCollectionType type) {
+  USE(ContainsOnlyValidKeys);
   Handle<FixedArray> content = Factory::empty_fixed_array();
   Handle<JSObject> arguments_boilerplate =
       Handle<JSObject>(
@@ -664,6 +675,7 @@
         Factory::NewFixedArray(current->NumberOfEnumElements());
     current->GetEnumElementKeys(*element_keys);
     content = UnionOfKeys(content, element_keys);
+    ASSERT(ContainsOnlyValidKeys(content));
 
     // Add the element keys from the interceptor.
     if (current->HasIndexedInterceptor()) {
@@ -671,6 +683,7 @@
           GetKeysForIndexedInterceptor(object, current);
       if (!result.IsEmpty())
         content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
+      ASSERT(ContainsOnlyValidKeys(content));
     }
 
     // We can cache the computed property keys if access checks are
@@ -692,6 +705,7 @@
     // Compute the property keys and cache them if possible.
     content =
         UnionOfKeys(content, GetEnumPropertyKeys(current, cache_enum_keys));
+    ASSERT(ContainsOnlyValidKeys(content));
 
     // Add the property keys from the interceptor.
     if (current->HasNamedInterceptor()) {
@@ -699,6 +713,7 @@
           GetKeysForNamedInterceptor(object, current);
       if (!result.IsEmpty())
         content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
+      ASSERT(ContainsOnlyValidKeys(content));
     }
 
     // If we only want local properties we bail out after the first
@@ -785,15 +800,16 @@
 
 
 bool CompileLazy(Handle<JSFunction> function,
-                 Handle<Object> receiver,
                  ClearExceptionFlag flag) {
   if (function->shared()->is_compiled()) {
     function->set_code(function->shared()->code());
+    PROFILE(FunctionCreateEvent(*function));
     function->shared()->set_code_age(0);
     return true;
   } else {
-    CompilationInfo info(function, 0, receiver);
+    CompilationInfo info(function);
     bool result = CompileLazyHelper(&info, flag);
+    ASSERT(!result || function->is_compiled());
     PROFILE(FunctionCreateEvent(*function));
     return result;
   }
@@ -801,15 +817,17 @@
 
 
 bool CompileLazyInLoop(Handle<JSFunction> function,
-                       Handle<Object> receiver,
                        ClearExceptionFlag flag) {
   if (function->shared()->is_compiled()) {
     function->set_code(function->shared()->code());
+    PROFILE(FunctionCreateEvent(*function));
     function->shared()->set_code_age(0);
     return true;
   } else {
-    CompilationInfo info(function, 1, receiver);
+    CompilationInfo info(function);
+    info.MarkAsInLoop();
     bool result = CompileLazyHelper(&info, flag);
+    ASSERT(!result || function->is_compiled());
     PROFILE(FunctionCreateEvent(*function));
     return result;
   }
diff --git a/src/handles.h b/src/handles.h
index 135dbfb..69170ff 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -345,13 +345,9 @@
 bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
                        ClearExceptionFlag flag);
 
-bool CompileLazy(Handle<JSFunction> function,
-                 Handle<Object> receiver,
-                 ClearExceptionFlag flag);
+bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag);
 
-bool CompileLazyInLoop(Handle<JSFunction> function,
-                       Handle<Object> receiver,
-                       ClearExceptionFlag flag);
+bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag flag);
 
 class NoHandleAllocation BASE_EMBEDDED {
  public:
diff --git a/src/heap-inl.h b/src/heap-inl.h
index b68f5c1..104292d 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -36,7 +36,7 @@
 namespace internal {
 
 void Heap::UpdateOldSpaceLimits() {
-  int old_gen_size = PromotedSpaceSize();
+  intptr_t old_gen_size = PromotedSpaceSize();
   old_gen_promotion_limit_ =
       old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3);
   old_gen_allocation_limit_ =
@@ -76,7 +76,7 @@
   if (FLAG_gc_interval >= 0 &&
       !disallow_allocation_failure_ &&
       Heap::allocation_timeout_-- <= 0) {
-    return Failure::RetryAfterGC(size_in_bytes, space);
+    return Failure::RetryAfterGC(space);
   }
   Counters::objs_since_last_full.Increment();
   Counters::objs_since_last_young.Increment();
@@ -389,8 +389,12 @@
 }
 
 
+#ifdef DEBUG
 #define GC_GREEDY_CHECK() \
-  ASSERT(!FLAG_gc_greedy || v8::internal::Heap::GarbageCollectionGreedyCheck())
+  if (FLAG_gc_greedy) v8::internal::Heap::GarbageCollectionGreedyCheck()
+#else
+#define GC_GREEDY_CHECK() { }
+#endif
 
 
 // Calls the FUNCTION_CALL function and retries it up to three times
@@ -409,8 +413,7 @@
       v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\
     }                                                                     \
     if (!__object__->IsRetryAfterGC()) RETURN_EMPTY;                      \
-    Heap::CollectGarbage(Failure::cast(__object__)->requested(),          \
-                         Failure::cast(__object__)->allocation_space());  \
+    Heap::CollectGarbage(Failure::cast(__object__)->allocation_space());  \
     __object__ = FUNCTION_CALL;                                           \
     if (!__object__->IsFailure()) RETURN_VALUE;                           \
     if (__object__->IsOutOfMemoryFailure()) {                             \
diff --git a/src/heap.cc b/src/heap.cc
index 047e331..675639a 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -54,6 +54,7 @@
 
 String* Heap::hidden_symbol_;
 Object* Heap::roots_[Heap::kRootListLength];
+Object* Heap::global_contexts_list_;
 
 NewSpace Heap::new_space_;
 OldSpace* Heap::old_pointer_space_ = NULL;
@@ -63,8 +64,8 @@
 CellSpace* Heap::cell_space_ = NULL;
 LargeObjectSpace* Heap::lo_space_ = NULL;
 
-int Heap::old_gen_promotion_limit_ = kMinimumPromotionLimit;
-int Heap::old_gen_allocation_limit_ = kMinimumAllocationLimit;
+intptr_t Heap::old_gen_promotion_limit_ = kMinimumPromotionLimit;
+intptr_t Heap::old_gen_allocation_limit_ = kMinimumAllocationLimit;
 
 int Heap::old_gen_exhausted_ = false;
 
@@ -75,19 +76,19 @@
 // a multiple of Page::kPageSize.
 #if defined(ANDROID)
 int Heap::max_semispace_size_  = 2*MB;
-int Heap::max_old_generation_size_ = 192*MB;
+intptr_t Heap::max_old_generation_size_ = 192*MB;
 int Heap::initial_semispace_size_ = 128*KB;
-size_t Heap::code_range_size_ = 0;
+intptr_t Heap::code_range_size_ = 0;
 #elif defined(V8_TARGET_ARCH_X64)
 int Heap::max_semispace_size_  = 16*MB;
-int Heap::max_old_generation_size_ = 1*GB;
+intptr_t Heap::max_old_generation_size_ = 1*GB;
 int Heap::initial_semispace_size_ = 1*MB;
-size_t Heap::code_range_size_ = 512*MB;
+intptr_t Heap::code_range_size_ = 512*MB;
 #else
 int Heap::max_semispace_size_  = 8*MB;
-int Heap::max_old_generation_size_ = 512*MB;
+intptr_t Heap::max_old_generation_size_ = 512*MB;
 int Heap::initial_semispace_size_ = 512*KB;
-size_t Heap::code_range_size_ = 0;
+intptr_t Heap::code_range_size_ = 0;
 #endif
 
 // The snapshot semispace size will be the default semispace size if
@@ -108,7 +109,7 @@
 // Will be 4 * reserved_semispace_size_ to ensure that young
 // generation can be aligned to its size.
 int Heap::survived_since_last_expansion_ = 0;
-int Heap::external_allocation_limit_ = 0;
+intptr_t Heap::external_allocation_limit_ = 0;
 
 Heap::HeapState Heap::gc_state_ = NOT_IN_GC;
 
@@ -137,13 +138,13 @@
 bool Heap::disallow_allocation_failure_ = false;
 #endif  // DEBUG
 
-int GCTracer::alive_after_last_gc_ = 0;
+intptr_t GCTracer::alive_after_last_gc_ = 0;
 double GCTracer::last_gc_end_timestamp_ = 0.0;
 int GCTracer::max_gc_pause_ = 0;
-int GCTracer::max_alive_after_gc_ = 0;
+intptr_t GCTracer::max_alive_after_gc_ = 0;
 int GCTracer::min_in_mutator_ = kMaxInt;
 
-int Heap::Capacity() {
+intptr_t Heap::Capacity() {
   if (!HasBeenSetup()) return 0;
 
   return new_space_.Capacity() +
@@ -155,7 +156,7 @@
 }
 
 
-int Heap::CommittedMemory() {
+intptr_t Heap::CommittedMemory() {
   if (!HasBeenSetup()) return 0;
 
   return new_space_.CommittedMemory() +
@@ -168,7 +169,7 @@
 }
 
 
-int Heap::Available() {
+intptr_t Heap::Available() {
   if (!HasBeenSetup()) return 0;
 
   return new_space_.Available() +
@@ -289,33 +290,46 @@
 #if defined(ENABLE_LOGGING_AND_PROFILING)
 void Heap::PrintShortHeapStatistics() {
   if (!FLAG_trace_gc_verbose) return;
-  PrintF("Memory allocator,   used: %8d, available: %8d\n",
+  PrintF("Memory allocator,   used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d\n",
          MemoryAllocator::Size(),
          MemoryAllocator::Available());
-  PrintF("New space,          used: %8d, available: %8d\n",
+  PrintF("New space,          used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d\n",
          Heap::new_space_.Size(),
          new_space_.Available());
-  PrintF("Old pointers,       used: %8d, available: %8d, waste: %8d\n",
+  PrintF("Old pointers,       used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d"
+             ", waste: %8" V8_PTR_PREFIX "d\n",
          old_pointer_space_->Size(),
          old_pointer_space_->Available(),
          old_pointer_space_->Waste());
-  PrintF("Old data space,     used: %8d, available: %8d, waste: %8d\n",
+  PrintF("Old data space,     used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d"
+             ", waste: %8" V8_PTR_PREFIX "d\n",
          old_data_space_->Size(),
          old_data_space_->Available(),
          old_data_space_->Waste());
-  PrintF("Code space,         used: %8d, available: %8d, waste: %8d\n",
+  PrintF("Code space,         used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d"
+             ", waste: %8" V8_PTR_PREFIX "d\n",
          code_space_->Size(),
          code_space_->Available(),
          code_space_->Waste());
-  PrintF("Map space,          used: %8d, available: %8d, waste: %8d\n",
+  PrintF("Map space,          used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d"
+             ", waste: %8" V8_PTR_PREFIX "d\n",
          map_space_->Size(),
          map_space_->Available(),
          map_space_->Waste());
-  PrintF("Cell space,         used: %8d, available: %8d, waste: %8d\n",
+  PrintF("Cell space,         used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d"
+             ", waste: %8" V8_PTR_PREFIX "d\n",
          cell_space_->Size(),
          cell_space_->Available(),
          cell_space_->Waste());
-  PrintF("Large object space, used: %8d, avaialble: %8d\n",
+  PrintF("Large object space, used: %8" V8_PTR_PREFIX "d"
+             ", available: %8" V8_PTR_PREFIX "d\n",
          lo_space_->Size(),
          lo_space_->Available());
 }
@@ -364,8 +378,8 @@
 #endif
 }
 
-int Heap::SizeOfObjects() {
-  int total = 0;
+intptr_t Heap::SizeOfObjects() {
+  intptr_t total = 0;
   AllSpaces spaces;
   for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
     total += space->Size();
@@ -388,7 +402,7 @@
   if (FLAG_code_stats) ReportCodeStatistics("After GC");
 #endif
 
-  Counters::alive_after_last_gc.Set(SizeOfObjects());
+  Counters::alive_after_last_gc.Set(static_cast<int>(SizeOfObjects()));
 
   Counters::symbol_table_capacity.Set(symbol_table()->Capacity());
   Counters::number_of_symbols.Set(symbol_table()->NumberOfElements());
@@ -407,7 +421,7 @@
   // not matter, so long as we do not specify NEW_SPACE, which would not
   // cause a full GC.
   MarkCompactCollector::SetForceCompaction(force_compaction);
-  CollectGarbage(0, OLD_POINTER_SPACE, collectionPolicy);
+  CollectGarbage(OLD_POINTER_SPACE, collectionPolicy);
   MarkCompactCollector::SetForceCompaction(false);
 }
 
@@ -418,8 +432,7 @@
 }
 
 
-bool Heap::CollectGarbage(int requested_size,
-                          AllocationSpace space,
+void Heap::CollectGarbage(AllocationSpace space,
                           CollectionPolicy collectionPolicy) {
   // The VM is in the GC state until exiting this function.
   VMState state(GC);
@@ -456,25 +469,8 @@
 
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_gc) HeapProfiler::WriteSample();
+  if (CpuProfiler::is_profiling()) CpuProfiler::ProcessMovedFunctions();
 #endif
-
-  switch (space) {
-    case NEW_SPACE:
-      return new_space_.Available() >= requested_size;
-    case OLD_POINTER_SPACE:
-      return old_pointer_space_->Available() >= requested_size;
-    case OLD_DATA_SPACE:
-      return old_data_space_->Available() >= requested_size;
-    case CODE_SPACE:
-      return code_space_->Available() >= requested_size;
-    case MAP_SPACE:
-      return map_space_->Available() >= requested_size;
-    case CELL_SPACE:
-      return cell_space_->Available() >= requested_size;
-    case LO_SPACE:
-      return lo_space_->Available() >= requested_size;
-  }
-  return false;
 }
 
 
@@ -529,27 +525,27 @@
   while (gc_performed) {
     gc_performed = false;
     if (!new_space->ReserveSpace(new_space_size)) {
-      Heap::CollectGarbage(new_space_size, NEW_SPACE);
+      Heap::CollectGarbage(NEW_SPACE);
       gc_performed = true;
     }
     if (!old_pointer_space->ReserveSpace(pointer_space_size)) {
-      Heap::CollectGarbage(pointer_space_size, OLD_POINTER_SPACE);
+      Heap::CollectGarbage(OLD_POINTER_SPACE);
       gc_performed = true;
     }
     if (!(old_data_space->ReserveSpace(data_space_size))) {
-      Heap::CollectGarbage(data_space_size, OLD_DATA_SPACE);
+      Heap::CollectGarbage(OLD_DATA_SPACE);
       gc_performed = true;
     }
     if (!(code_space->ReserveSpace(code_space_size))) {
-      Heap::CollectGarbage(code_space_size, CODE_SPACE);
+      Heap::CollectGarbage(CODE_SPACE);
       gc_performed = true;
     }
     if (!(map_space->ReserveSpace(map_space_size))) {
-      Heap::CollectGarbage(map_space_size, MAP_SPACE);
+      Heap::CollectGarbage(MAP_SPACE);
       gc_performed = true;
     }
     if (!(cell_space->ReserveSpace(cell_space_size))) {
-      Heap::CollectGarbage(cell_space_size, CELL_SPACE);
+      Heap::CollectGarbage(CELL_SPACE);
       gc_performed = true;
     }
     // We add a slack-factor of 2 in order to have space for a series of
@@ -561,7 +557,7 @@
     large_object_size += cell_space_size + map_space_size + code_space_size +
         data_space_size + pointer_space_size;
     if (!(lo_space->ReserveSpace(large_object_size))) {
-      Heap::CollectGarbage(large_object_size, LO_SPACE);
+      Heap::CollectGarbage(LO_SPACE);
       gc_performed = true;
     }
   }
@@ -611,19 +607,14 @@
 }
 
 
-class ClearThreadNormalizedMapCachesVisitor: public ThreadVisitor {
-  virtual void VisitThread(ThreadLocalTop* top) {
-    Context* context = top->context_;
-    if (context == NULL) return;
-    context->global()->global_context()->normalized_map_cache()->Clear();
-  }
-};
-
-
 void Heap::ClearNormalizedMapCaches() {
   if (Bootstrapper::IsActive()) return;
-  ClearThreadNormalizedMapCachesVisitor visitor;
-  ThreadManager::IterateArchivedThreads(&visitor);
+
+  Object* context = global_contexts_list_;
+  while (!context->IsUndefined()) {
+    Context::cast(context)->normalized_map_cache()->Clear();
+    context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK);
+  }
 }
 
 
@@ -672,6 +663,10 @@
 void Heap::PerformGarbageCollection(GarbageCollector collector,
                                     GCTracer* tracer,
                                     CollectionPolicy collectionPolicy) {
+  if (collector != SCAVENGER) {
+    PROFILE(CodeMovingGCEvent());
+  }
+
   VerifySymbolTable();
   if (collector == MARK_COMPACTOR && global_gc_prologue_callback_) {
     ASSERT(!allocation_allowed_);
@@ -690,7 +685,7 @@
 
   EnsureFromSpaceIsCommitted();
 
-  int start_new_space_size = Heap::new_space()->Size();
+  int start_new_space_size = Heap::new_space()->SizeAsInt();
 
   if (collector == MARK_COMPACTOR) {
     // Perform mark-sweep with optional compaction.
@@ -962,7 +957,7 @@
   DescriptorLookupCache::Clear();
 
   // Used for updating survived_since_last_expansion_ at function end.
-  int survived_watermark = PromotedSpaceSize();
+  intptr_t survived_watermark = PromotedSpaceSize();
 
   CheckNewSpaceExpansionCriteria();
 
@@ -1021,6 +1016,9 @@
     }
   }
 
+  // Scavenge object reachable from the global contexts list directly.
+  scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_));
+
   new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
 
   UpdateNewSpaceReferencesInExternalStringTable(
@@ -1032,8 +1030,8 @@
   new_space_.set_age_mark(new_space_.top());
 
   // Update how much has survived scavenge.
-  IncrementYoungSurvivorsCounter(
-      (PromotedSpaceSize() - survived_watermark) + new_space_.Size());
+  IncrementYoungSurvivorsCounter(static_cast<int>(
+      (PromotedSpaceSize() - survived_watermark) + new_space_.Size()));
 
   LOG(ResourceEvent("scavenge", "end"));
 
@@ -1088,6 +1086,44 @@
 }
 
 
+void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
+  Object* head = undefined_value();
+  Context* tail = NULL;
+  Object* candidate = global_contexts_list_;
+  while (!candidate->IsUndefined()) {
+    // Check whether to keep the candidate in the list.
+    Context* candidate_context = reinterpret_cast<Context*>(candidate);
+    Object* retain = retainer->RetainAs(candidate);
+    if (retain != NULL) {
+      if (head->IsUndefined()) {
+        // First element in the list.
+        head = candidate_context;
+      } else {
+        // Subsequent elements in the list.
+        ASSERT(tail != NULL);
+        tail->set_unchecked(Context::NEXT_CONTEXT_LINK,
+                            candidate_context,
+                            UPDATE_WRITE_BARRIER);
+      }
+      // Retained context is new tail.
+      tail = candidate_context;
+    }
+    // Move to next element in the list.
+    candidate = candidate_context->get(Context::NEXT_CONTEXT_LINK);
+  }
+
+  // Terminate the list if there is one or more elements.
+  if (tail != NULL) {
+    tail->set_unchecked(Context::NEXT_CONTEXT_LINK,
+                        Heap::undefined_value(),
+                        UPDATE_WRITE_BARRIER);
+  }
+
+  // Update the head of the list of contexts.
+  Heap::global_contexts_list_ = head;
+}
+
+
 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
  public:
   static inline void VisitPointer(Object** p) {
@@ -1144,6 +1180,9 @@
     table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
     table_.Register(kVisitByteArray, &EvacuateByteArray);
     table_.Register(kVisitFixedArray, &EvacuateFixedArray);
+    table_.Register(kVisitGlobalContext,
+                    &ObjectEvacuationStrategy<POINTER_OBJECT>::
+                        VisitSpecialized<Context::kSize>);
 
     typedef ObjectEvacuationStrategy<POINTER_OBJECT> PointerObject;
 
@@ -1222,7 +1261,7 @@
     if (Logger::is_logging() || CpuProfiler::is_profiling()) {
       if (target->IsJSFunction()) {
         PROFILE(FunctionMoveEvent(source->address(), target->address()));
-        PROFILE(FunctionCreateEventFromMove(JSFunction::cast(target), source));
+        PROFILE(FunctionCreateEventFromMove(JSFunction::cast(target)));
       }
     }
 #endif
@@ -1634,7 +1673,9 @@
 
   obj = AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel);
   if (obj->IsFailure()) return false;
-  set_global_context_map(Map::cast(obj));
+  Map* global_context_map = Map::cast(obj);
+  global_context_map->set_visitor_id(StaticVisitorBase::kVisitGlobalContext);
+  set_global_context_map(global_context_map);
 
   obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE,
                     SharedFunctionInfo::kAlignedSize);
@@ -3418,7 +3459,7 @@
       HistogramTimerScope scope(&Counters::gc_context);
       CollectAllGarbage(false);
     } else {
-      CollectGarbage(0, NEW_SPACE);
+      CollectGarbage(NEW_SPACE);
     }
     new_space_.Shrink();
     last_gc_count = gc_count_;
@@ -3496,8 +3537,10 @@
   PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n",
          title, gc_count_);
   PrintF("mark-compact GC : %d\n", mc_count_);
-  PrintF("old_gen_promotion_limit_ %d\n", old_gen_promotion_limit_);
-  PrintF("old_gen_allocation_limit_ %d\n", old_gen_allocation_limit_);
+  PrintF("old_gen_promotion_limit_ %" V8_PTR_PREFIX "d\n",
+         old_gen_promotion_limit_);
+  PrintF("old_gen_allocation_limit_ %" V8_PTR_PREFIX "d\n",
+         old_gen_allocation_limit_);
 
   PrintF("\n");
   PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles());
@@ -4069,15 +4112,16 @@
 
 
 bool Heap::ConfigureHeapDefault() {
-  return ConfigureHeap(FLAG_max_new_space_size / 2, FLAG_max_old_space_size);
+  return ConfigureHeap(
+      FLAG_max_new_space_size * (KB / 2), FLAG_max_old_space_size * MB);
 }
 
 
 void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
   *stats->start_marker = HeapStats::kStartMarker;
   *stats->end_marker = HeapStats::kEndMarker;
-  *stats->new_space_size = new_space_.Size();
-  *stats->new_space_capacity = new_space_.Capacity();
+  *stats->new_space_size = new_space_.SizeAsInt();
+  *stats->new_space_capacity = static_cast<int>(new_space_.Capacity());
   *stats->old_pointer_space_size = old_pointer_space_->Size();
   *stats->old_pointer_space_capacity = old_pointer_space_->Capacity();
   *stats->old_data_space_size = old_data_space_->Size();
@@ -4111,7 +4155,7 @@
 }
 
 
-int Heap::PromotedSpaceSize() {
+intptr_t Heap::PromotedSpaceSize() {
   return old_pointer_space_->Size()
       + old_data_space_->Size()
       + code_space_->Size()
@@ -4220,10 +4264,12 @@
 
     // Create initial objects
     if (!CreateInitialObjects()) return false;
+
+    global_contexts_list_ = undefined_value();
   }
 
-  LOG(IntEvent("heap-capacity", Capacity()));
-  LOG(IntEvent("heap-available", Available()));
+  LOG(IntPtrTEvent("heap-capacity", Capacity()));
+  LOG(IntPtrTEvent("heap-available", Available()));
 
 #ifdef ENABLE_LOGGING_AND_PROFILING
   // This should be called only after initial objects have been created.
@@ -4257,7 +4303,8 @@
     PrintF("mark_compact_count=%d ", mc_count_);
     PrintF("max_gc_pause=%d ", GCTracer::get_max_gc_pause());
     PrintF("min_in_mutator=%d ", GCTracer::get_min_in_mutator());
-    PrintF("max_alive_after_gc=%d ", GCTracer::get_max_alive_after_gc());
+    PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ",
+           GCTracer::get_max_alive_after_gc());
     PrintF("\n\n");
   }
 
@@ -4383,7 +4430,9 @@
  public:
   void VisitPointers(Object** start, Object** end) {
     for (Object** p = start; p < end; p++)
-      PrintF("  handle %p to %p\n", p, *p);
+      PrintF("  handle %p to %p\n",
+             reinterpret_cast<void*>(p),
+             reinterpret_cast<void*>(*p));
   }
 };
 
@@ -4736,8 +4785,8 @@
 #endif
 
 
-static int CountTotalHolesSize() {
-  int holes_size = 0;
+static intptr_t CountTotalHolesSize() {
+  intptr_t holes_size = 0;
   OldSpaces spaces;
   for (OldSpace* space = spaces.next();
        space != NULL;
@@ -4835,13 +4884,14 @@
     PrintF("sweepns=%d ", static_cast<int>(scopes_[Scope::MC_SWEEP_NEWSPACE]));
     PrintF("compact=%d ", static_cast<int>(scopes_[Scope::MC_COMPACT]));
 
-    PrintF("total_size_before=%d ", start_size_);
-    PrintF("total_size_after=%d ", Heap::SizeOfObjects());
-    PrintF("holes_size_before=%d ", in_free_list_or_wasted_before_gc_);
-    PrintF("holes_size_after=%d ", CountTotalHolesSize());
+    PrintF("total_size_before=%" V8_PTR_PREFIX "d ", start_size_);
+    PrintF("total_size_after=%" V8_PTR_PREFIX "d ", Heap::SizeOfObjects());
+    PrintF("holes_size_before=%" V8_PTR_PREFIX "d ",
+           in_free_list_or_wasted_before_gc_);
+    PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize());
 
-    PrintF("allocated=%d ", allocated_since_last_gc_);
-    PrintF("promoted=%d ", promoted_objects_size_);
+    PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc_);
+    PrintF("promoted=%" V8_PTR_PREFIX "d ", promoted_objects_size_);
 
     PrintF("\n");
   }
@@ -4917,11 +4967,11 @@
 
 
 #ifdef DEBUG
-bool Heap::GarbageCollectionGreedyCheck() {
+void Heap::GarbageCollectionGreedyCheck() {
   ASSERT(FLAG_gc_greedy);
-  if (Bootstrapper::IsActive()) return true;
-  if (disallow_allocation_failure()) return true;
-  return CollectGarbage(0, NEW_SPACE);
+  if (Bootstrapper::IsActive()) return;
+  if (disallow_allocation_failure()) return;
+  CollectGarbage(NEW_SPACE);
 }
 #endif
 
diff --git a/src/heap.h b/src/heap.h
index 8a11530..6d32a4b 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -202,9 +202,10 @@
   V(closure_symbol, "(closure)")
 
 
-// Forward declaration of the GCTracer class.
+// Forward declarations.
 class GCTracer;
 class HeapStats;
+class WeakObjectRetainer;
 
 
 typedef String* (*ExternalStringTableUpdaterCallback)(Object** pointer);
@@ -245,31 +246,31 @@
   // semi space.  The young generation consists of two semi spaces and
   // we reserve twice the amount needed for those in order to ensure
   // that new space can be aligned to its size.
-  static int MaxReserved() {
+  static intptr_t MaxReserved() {
     return 4 * reserved_semispace_size_ + max_old_generation_size_;
   }
   static int MaxSemiSpaceSize() { return max_semispace_size_; }
   static int ReservedSemiSpaceSize() { return reserved_semispace_size_; }
   static int InitialSemiSpaceSize() { return initial_semispace_size_; }
-  static int MaxOldGenerationSize() { return max_old_generation_size_; }
+  static intptr_t MaxOldGenerationSize() { return max_old_generation_size_; }
 
   // Returns the capacity of the heap in bytes w/o growing. Heap grows when
   // more spaces are needed until it reaches the limit.
-  static int Capacity();
+  static intptr_t Capacity();
 
   // Returns the amount of memory currently committed for the heap.
-  static int CommittedMemory();
+  static intptr_t CommittedMemory();
 
   // Returns the available bytes in space w/o growing.
   // Heap doesn't guarantee that it can allocate an object that requires
   // all available bytes. Check MaxHeapObjectSize() instead.
-  static int Available();
+  static intptr_t Available();
 
   // Returns the maximum object size in paged space.
   static inline int MaxObjectSizeInPagedSpace();
 
   // Returns of size of all objects residing in the heap.
-  static int SizeOfObjects();
+  static intptr_t SizeOfObjects();
 
   // Return the starting address and a mask for the new space.  And-masking an
   // address with the mask will result in the start address of the new space
@@ -696,8 +697,7 @@
 
   // Performs garbage collection operation.
   // Returns whether required_space bytes are available after the collection.
-  static bool CollectGarbage(int required_space,
-                             AllocationSpace space,
+  static void CollectGarbage(AllocationSpace space,
                              CollectionPolicy collectionPolicy = NORMAL);
 
   // Performs a full garbage collection. Force compaction if the
@@ -717,7 +717,7 @@
 
 #ifdef DEBUG
   // Utility used with flag gc-greedy.
-  static bool GarbageCollectionGreedyCheck();
+  static void GarbageCollectionGreedyCheck();
 #endif
 
   static void AddGCPrologueCallback(
@@ -767,6 +767,11 @@
   // not match the empty string.
   static String* hidden_symbol() { return hidden_symbol_; }
 
+  static void set_global_contexts_list(Object* object) {
+    global_contexts_list_ = object;
+  }
+  static Object* global_contexts_list() { return global_contexts_list_; }
+
   // Iterates over all roots in the heap.
   static void IterateRoots(ObjectVisitor* v, VisitMode mode);
   // Iterates over all strong roots in the heap.
@@ -870,6 +875,11 @@
   // Generated code can embed this address to get access to the roots.
   static Object** roots_address() { return roots_; }
 
+  // Get address of global contexts list for serialization support.
+  static Object** global_contexts_list_address() {
+    return &global_contexts_list_;
+  }
+
 #ifdef DEBUG
   static void Print();
   static void PrintHandles();
@@ -1051,6 +1061,8 @@
   static void UpdateNewSpaceReferencesInExternalStringTable(
       ExternalStringTableUpdaterCallback updater_func);
 
+  static void ProcessWeakReferences(WeakObjectRetainer* retainer);
+
   // Helper function that governs the promotion policy from new space to
   // old.  If the object's old address lies below the new space's age
   // mark or if we've already filled the bottom 1/16th of the to space,
@@ -1069,8 +1081,8 @@
   static int reserved_semispace_size_;
   static int max_semispace_size_;
   static int initial_semispace_size_;
-  static int max_old_generation_size_;
-  static size_t code_range_size_;
+  static intptr_t max_old_generation_size_;
+  static intptr_t code_range_size_;
 
   // For keeping track of how much data has survived
   // scavenge since last new space expansion.
@@ -1098,7 +1110,7 @@
   static HeapState gc_state_;
 
   // Returns the size of object residing in non new spaces.
-  static int PromotedSpaceSize();
+  static intptr_t PromotedSpaceSize();
 
   // Returns the amount of external memory registered since last global gc.
   static int PromotedExternalMemorySize();
@@ -1133,16 +1145,16 @@
   // Limit that triggers a global GC on the next (normally caused) GC.  This
   // is checked when we have already decided to do a GC to help determine
   // which collector to invoke.
-  static int old_gen_promotion_limit_;
+  static intptr_t old_gen_promotion_limit_;
 
   // Limit that triggers a global GC as soon as is reasonable.  This is
   // checked before expanding a paged space in the old generation and on
   // every allocation in large object space.
-  static int old_gen_allocation_limit_;
+  static intptr_t old_gen_allocation_limit_;
 
   // Limit on the amount of externally allocated memory allowed
   // between global GCs. If reached a global GC is forced.
-  static int external_allocation_limit_;
+  static intptr_t external_allocation_limit_;
 
   // The amount of external memory registered through the API kept alive
   // by global handles
@@ -1157,6 +1169,8 @@
 
   static Object* roots_[kRootListLength];
 
+  static Object* global_contexts_list_;
+
   struct StringTypeTable {
     InstanceType type;
     int size;
@@ -1231,8 +1245,8 @@
                                        GCTracer* tracer,
                                        CollectionPolicy collectionPolicy);
 
-  static const int kMinimumPromotionLimit = 2 * MB;
-  static const int kMinimumAllocationLimit = 8 * MB;
+  static const intptr_t kMinimumPromotionLimit = 2 * MB;
+  static const intptr_t kMinimumAllocationLimit = 8 * MB;
 
   inline static void UpdateOldSpaceLimits();
 
@@ -1385,24 +1399,24 @@
   int* start_marker;                    //  0
   int* new_space_size;                  //  1
   int* new_space_capacity;              //  2
-  int* old_pointer_space_size;          //  3
-  int* old_pointer_space_capacity;      //  4
-  int* old_data_space_size;             //  5
-  int* old_data_space_capacity;         //  6
-  int* code_space_size;                 //  7
-  int* code_space_capacity;             //  8
-  int* map_space_size;                  //  9
-  int* map_space_capacity;              // 10
-  int* cell_space_size;                 // 11
-  int* cell_space_capacity;             // 12
-  int* lo_space_size;                   // 13
+  intptr_t* old_pointer_space_size;          //  3
+  intptr_t* old_pointer_space_capacity;      //  4
+  intptr_t* old_data_space_size;             //  5
+  intptr_t* old_data_space_capacity;         //  6
+  intptr_t* code_space_size;                 //  7
+  intptr_t* code_space_capacity;             //  8
+  intptr_t* map_space_size;                  //  9
+  intptr_t* map_space_capacity;              // 10
+  intptr_t* cell_space_size;                 // 11
+  intptr_t* cell_space_capacity;             // 12
+  intptr_t* lo_space_size;                   // 13
   int* global_handle_count;             // 14
   int* weak_global_handle_count;        // 15
   int* pending_global_handle_count;     // 16
   int* near_death_global_handle_count;  // 17
   int* destroyed_global_handle_count;   // 18
-  int* memory_allocator_size;           // 19
-  int* memory_allocator_capacity;       // 20
+  intptr_t* memory_allocator_size;           // 19
+  intptr_t* memory_allocator_capacity;       // 20
   int* objects_per_type;                // 21
   int* size_per_type;                   // 22
   int* os_error;                        // 23
@@ -1837,7 +1851,7 @@
   static int get_max_gc_pause() { return max_gc_pause_; }
 
   // Returns maximum size of objects alive after GC.
-  static int get_max_alive_after_gc() { return max_alive_after_gc_; }
+  static intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; }
 
   // Returns minimal interval between two subsequent collections.
   static int get_min_in_mutator() { return min_in_mutator_; }
@@ -1852,7 +1866,7 @@
   }
 
   double start_time_;  // Timestamp set in the constructor.
-  int start_size_;  // Size of objects in heap set in constructor.
+  intptr_t start_size_;  // Size of objects in heap set in constructor.
   GarbageCollector collector_;  // Type of collector.
 
   // A count (including this one, eg, the first collection is 1) of the
@@ -1884,30 +1898,30 @@
 
   // Total amount of space either wasted or contained in one of free lists
   // before the current GC.
-  int in_free_list_or_wasted_before_gc_;
+  intptr_t in_free_list_or_wasted_before_gc_;
 
   // Difference between space used in the heap at the beginning of the current
   // collection and the end of the previous collection.
-  int allocated_since_last_gc_;
+  intptr_t allocated_since_last_gc_;
 
   // Amount of time spent in mutator that is time elapsed between end of the
   // previous collection and the beginning of the current one.
   double spent_in_mutator_;
 
   // Size of objects promoted during the current collection.
-  int promoted_objects_size_;
+  intptr_t promoted_objects_size_;
 
   // Maximum GC pause.
   static int max_gc_pause_;
 
   // Maximum size of objects alive after GC.
-  static int max_alive_after_gc_;
+  static intptr_t max_alive_after_gc_;
 
   // Minimal interval between two subsequent collections.
   static int min_in_mutator_;
 
   // Size of objects alive after last GC.
-  static int alive_after_last_gc_;
+  static intptr_t alive_after_last_gc_;
 
   static double last_gc_end_timestamp_;
 };
@@ -2043,6 +2057,19 @@
   static List<Object*> old_space_strings_;
 };
 
+
+// Abstract base class for checking whether a weak object should be retained.
+class WeakObjectRetainer {
+ public:
+  virtual ~WeakObjectRetainer() {}
+
+  // Return whether this object should be retained. If NULL is returned the
+  // object has no references. Otherwise the address of the retained object
+  // should be returned as in some GC situations the object has been moved.
+  virtual Object* RetainAs(Object* object) = 0;
+};
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_HEAP_H_
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index e2f4547..e201179 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -2414,7 +2414,7 @@
 
 
 void Assembler::ptest(XMMRegister dst, XMMRegister src) {
-  ASSERT(CpuFeatures::IsEnabled(SSE2));
+  ASSERT(CpuFeatures::IsEnabled(SSE4_1));
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
   EMIT(0x66);
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 1dab0a6..d8051c8 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -376,6 +376,7 @@
   static bool IsSupported(CpuFeature f) {
     if (f == SSE2 && !FLAG_enable_sse2) return false;
     if (f == SSE3 && !FLAG_enable_sse3) return false;
+    if (f == SSE4_1 && !FLAG_enable_sse4_1) return false;
     if (f == CMOV && !FLAG_enable_cmov) return false;
     if (f == RDTSC && !FLAG_enable_rdtsc) return false;
     return (supported_ & (static_cast<uint64_t>(1) << f)) != 0;
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 3e2b7ae..348bb14 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -2638,7 +2638,7 @@
     __ j(not_zero, &non_smi, not_taken);
     __ sub(edx, Operand(eax));  // Return on the result of the subtraction.
     __ j(no_overflow, &smi_done);
-    __ neg(edx);  // Correct sign in case of overflow.
+    __ not_(edx);  // Correct sign in case of overflow. edx is never 0 here.
     __ bind(&smi_done);
     __ mov(eax, edx);
     __ ret(0);
@@ -2964,16 +2964,7 @@
 
 
 void StackCheckStub::Generate(MacroAssembler* masm) {
-  // Because builtins always remove the receiver from the stack, we
-  // have to fake one to avoid underflowing the stack. The receiver
-  // must be inserted below the return address on the stack so we
-  // temporarily store that in a register.
-  __ pop(eax);
-  __ push(Immediate(Smi::FromInt(0)));
-  __ push(eax);
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kStackGuard, 1, 1);
+  __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
 }
 
 
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 9c8573c..f2ac7f7 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -179,20 +179,11 @@
 
   // Adjust for function-level loop nesting.
   ASSERT_EQ(0, loop_nesting_);
-  loop_nesting_ = info->loop_nesting();
+  loop_nesting_ = info->is_in_loop() ? 1 : 0;
 
   JumpTarget::set_compiling_deferred_code(false);
 
-#ifdef DEBUG
-  if (strlen(FLAG_stop_at) > 0 &&
-      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
-    frame_->SpillAll();
-    __ int3();
-  }
-#endif
-
-  // New scope to get automatic timing calculation.
-  { HistogramTimerScope codegen_timer(&Counters::code_generation);
+  {
     CodeGenState state(this);
 
     // Entry:
@@ -203,6 +194,14 @@
     // esi: callee's context
     allocator_->Initialize();
 
+#ifdef DEBUG
+    if (strlen(FLAG_stop_at) > 0 &&
+        info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+      frame_->SpillAll();
+      __ int3();
+    }
+#endif
+
     frame_->Enter();
 
     // Allocate space for locals and initialize them.
@@ -358,7 +357,7 @@
   }
 
   // Adjust for function-level loop nesting.
-  ASSERT_EQ(loop_nesting_, info->loop_nesting());
+  ASSERT_EQ(loop_nesting_, info->is_in_loop() ? 1 : 0);
   loop_nesting_ = 0;
 
   // Code generation state must be reset.
@@ -369,7 +368,6 @@
 
   // Process any deferred code using the register allocator.
   if (!HasStackOverflow()) {
-    HistogramTimerScope deferred_timer(&Counters::deferred_code_generation);
     JumpTarget::set_compiling_deferred_code(true);
     ProcessDeferred();
     JumpTarget::set_compiling_deferred_code(false);
@@ -4925,9 +4923,12 @@
   ASSERT(!in_safe_int32_mode());
   // Build the function info and instantiate it.
   Handle<SharedFunctionInfo> function_info =
-      Compiler::BuildFunctionInfo(node, script(), this);
+      Compiler::BuildFunctionInfo(node, script());
   // Check for stack-overflow exception.
-  if (HasStackOverflow()) return;
+  if (function_info.is_null()) {
+    SetStackOverflow();
+    return;
+  }
   Result result = InstantiateFunction(function_info);
   frame()->Push(&result);
 }
@@ -9149,7 +9150,8 @@
       : dst_(dst),
         receiver_(receiver),
         name_(name),
-        is_contextual_(is_contextual) {
+        is_contextual_(is_contextual),
+        is_dont_delete_(false) {
     set_comment(is_contextual
                 ? "[ DeferredReferenceGetNamedValue (contextual)"
                 : "[ DeferredReferenceGetNamedValue");
@@ -9159,12 +9161,18 @@
 
   Label* patch_site() { return &patch_site_; }
 
+  void set_is_dont_delete(bool value) {
+    ASSERT(is_contextual_);
+    is_dont_delete_ = value;
+  }
+
  private:
   Label patch_site_;
   Register dst_;
   Register receiver_;
   Handle<String> name_;
   bool is_contextual_;
+  bool is_dont_delete_;
 };
 
 
@@ -9181,8 +9189,8 @@
   // The call must be followed by:
   // - a test eax instruction to indicate that the inobject property
   //   case was inlined.
-  // - a mov ecx instruction to indicate that the contextual property
-  //   load was inlined.
+  // - a mov ecx or mov edx instruction to indicate that the
+  //   contextual property load was inlined.
   //
   // Store the delta to the map check instruction here in the test
   // instruction.  Use masm_-> instead of the __ macro since the
@@ -9191,8 +9199,11 @@
   // Here we use masm_-> instead of the __ macro because this is the
   // instruction that gets patched and coverage code gets in the way.
   if (is_contextual_) {
-    masm_->mov(ecx, -delta_to_patch_site);
+    masm_->mov(is_dont_delete_ ? edx : ecx, -delta_to_patch_site);
     __ IncrementCounter(&Counters::named_load_global_inline_miss, 1);
+    if (is_dont_delete_) {
+      __ IncrementCounter(&Counters::dont_delete_hint_miss, 1);
+    }
   } else {
     masm_->test(eax, Immediate(-delta_to_patch_site));
     __ IncrementCounter(&Counters::named_load_inline_miss, 1);
@@ -9436,9 +9447,34 @@
       }
       __ mov(result.reg(),
              FieldOperand(result.reg(), JSGlobalPropertyCell::kValueOffset));
-      __ cmp(result.reg(), Factory::the_hole_value());
-      deferred->Branch(equal);
+      bool is_dont_delete = false;
+      if (!info_->closure().is_null()) {
+        // When doing lazy compilation we can check if the global cell
+        // already exists and use its "don't delete" status as a hint.
+        AssertNoAllocation no_gc;
+        v8::internal::GlobalObject* global_object =
+            info_->closure()->context()->global();
+        LookupResult lookup;
+        global_object->LocalLookupRealNamedProperty(*name, &lookup);
+        if (lookup.IsProperty() && lookup.type() == NORMAL) {
+          ASSERT(lookup.holder() == global_object);
+          ASSERT(global_object->property_dictionary()->ValueAt(
+              lookup.GetDictionaryEntry())->IsJSGlobalPropertyCell());
+          is_dont_delete = lookup.IsDontDelete();
+        }
+      }
+      deferred->set_is_dont_delete(is_dont_delete);
+      if (!is_dont_delete) {
+        __ cmp(result.reg(), Factory::the_hole_value());
+        deferred->Branch(equal);
+      } else if (FLAG_debug_code) {
+        __ cmp(result.reg(), Factory::the_hole_value());
+        __ Check(not_equal, "DontDelete cells can't contain the hole");
+      }
       __ IncrementCounter(&Counters::named_load_global_inline, 1);
+      if (is_dont_delete) {
+        __ IncrementCounter(&Counters::dont_delete_hint_hit, 1);
+      }
     } else {
       // The initial (invalid) offset has to be large enough to force a 32-bit
       // instruction encoding to allow patching with an arbitrary offset.  Use
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index c4a03d1..b072409 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -300,9 +300,7 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  // Takes a function literal, generates code for it. This function should only
-  // be called by compiler.cc.
-  static Handle<Code> MakeCode(CompilationInfo* info);
+  static bool MakeCode(CompilationInfo* info);
 
   // Printing of AST, etc. as requested by flags.
   static void MakeCodePrologue(CompilationInfo* info);
@@ -626,9 +624,6 @@
 
   void CheckStack();
 
-  static InlineFunctionGenerator FindInlineFunctionGenerator(
-      Runtime::FunctionId function_id);
-
   bool CheckForInlineRuntimeCall(CallRuntime* node);
 
   void ProcessDeclarations(ZoneList<Declaration*>* declarations);
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index cf53f4b..150df99 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -61,6 +61,13 @@
   SetFunctionPosition(function());
   Comment cmnt(masm_, "[ function compiled by full code generator");
 
+#ifdef DEBUG
+  if (strlen(FLAG_stop_at) > 0 &&
+      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+    __ int3();
+  }
+#endif
+
   __ push(ebp);  // Caller's frame pointer.
   __ mov(ebp, esp);
   __ push(esi);  // Callee's context.
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 413c36e..b5f4dee 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -885,8 +885,8 @@
   __ test(edx, Immediate(kSmiTagMask));
   __ j(zero, &slow, not_taken);
 
-  // Check that the key is a smi.
-  __ test(eax, Immediate(kSmiTagMask));
+  // Check that the key is an array index, that is Uint32.
+  __ test(eax, Immediate(kSmiTagMask | kSmiSignMask));
   __ j(not_zero, &slow, not_taken);
 
   // Get the map of the receiver.
@@ -1662,17 +1662,37 @@
 
 
 // One byte opcode for mov ecx,0xXXXXXXXX.
+// Marks inlined contextual loads using all kinds of cells. Generated
+// code has the hole check:
+//   mov reg, <cell>
+//   mov reg, (<cell>, value offset)
+//   cmp reg, <the hole>
+//   je  slow
+//   ;; use reg
 static const byte kMovEcxByte = 0xB9;
 
+// One byte opcode for mov edx,0xXXXXXXXX.
+// Marks inlined contextual loads using only "don't delete"
+// cells. Generated code doesn't have the hole check:
+//   mov reg, <cell>
+//   mov reg, (<cell>, value offset)
+//   ;; use reg
+static const byte kMovEdxByte = 0xBA;
+
 bool LoadIC::PatchInlinedContextualLoad(Address address,
                                         Object* map,
-                                        Object* cell) {
+                                        Object* cell,
+                                        bool is_dont_delete) {
   // The address of the instruction following the call.
   Address mov_instruction_address =
       address + Assembler::kCallTargetAddressOffset;
-  // If the instruction following the call is not a cmp eax, nothing
-  // was inlined.
-  if (*mov_instruction_address != kMovEcxByte) return false;
+  // If the instruction following the call is not a mov ecx/edx,
+  // nothing was inlined.
+  byte b = *mov_instruction_address;
+  if (b != kMovEcxByte && b != kMovEdxByte) return false;
+  // If we don't have the hole check generated, we can only support
+  // "don't delete" cells.
+  if (b == kMovEdxByte && !is_dont_delete) return false;
 
   Address delta_address = mov_instruction_address + 1;
   // The delta to the start of the map check instruction.
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index 2aab7a8..e2853e8 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -133,7 +133,6 @@
 
 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) {
   if (by != 0) {
-    Label inside_string;
     __ add(Operand(edi), Immediate(by * char_size()));
   }
 }
@@ -964,6 +963,17 @@
   __ add(backtrack_stackpointer(), Operand(ebp, kStackHighEnd));
 }
 
+void RegExpMacroAssemblerIA32::SetCurrentPositionFromEnd(int by)  {
+  NearLabel after_position;
+  __ cmp(edi, -by * char_size());
+  __ j(greater_equal, &after_position);
+  __ mov(edi, -by * char_size());
+  // On RegExp code entry (where this operation is used), the character before
+  // the current position is expected to be already loaded.
+  // We have advanced the position, so it's safe to read backwards.
+  LoadCurrentCharacterUnchecked(-1, 1);
+  __ bind(&after_position);
+}
 
 void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
   ASSERT(register_index >= num_saved_registers_);  // Reserved for positions!
diff --git a/src/ia32/regexp-macro-assembler-ia32.h b/src/ia32/regexp-macro-assembler-ia32.h
index 8b8eeed..51e2cb0 100644
--- a/src/ia32/regexp-macro-assembler-ia32.h
+++ b/src/ia32/regexp-macro-assembler-ia32.h
@@ -98,6 +98,7 @@
                             StackCheckFlag check_stack_limit);
   virtual void ReadCurrentPositionFromRegister(int reg);
   virtual void ReadStackPointerFromRegister(int reg);
+  virtual void SetCurrentPositionFromEnd(int by);
   virtual void SetRegister(int register_index, int to);
   virtual void Succeed();
   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index dd0d636..bb0a46c 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1944,6 +1944,109 @@
 }
 
 
+Object* CallStubCompiler::CompileMathAbsCall(Object* object,
+                                             JSObject* holder,
+                                             JSGlobalPropertyCell* cell,
+                                             JSFunction* function,
+                                             String* name) {
+  // ----------- S t a t e -------------
+  //  -- ecx                 : name
+  //  -- esp[0]              : return address
+  //  -- esp[(argc - n) * 4] : arg[n] (zero-based)
+  //  -- ...
+  //  -- esp[(argc + 1) * 4] : receiver
+  // -----------------------------------
+
+  const int argc = arguments().immediate();
+
+  // If the object is not a JSObject or we got an unexpected number of
+  // arguments, bail out to the regular call.
+  if (!object->IsJSObject() || argc != 1) return Heap::undefined_value();
+
+  Label miss;
+  GenerateNameCheck(name, &miss);
+
+  if (cell == NULL) {
+    __ mov(edx, Operand(esp, 2 * kPointerSize));
+
+    STATIC_ASSERT(kSmiTag == 0);
+    __ test(edx, Immediate(kSmiTagMask));
+    __ j(zero, &miss);
+
+    CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
+                    &miss);
+  } else {
+    ASSERT(cell->value() == function);
+    GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
+    GenerateLoadFunctionFromCell(cell, function, &miss);
+  }
+
+  // Load the (only) argument into eax.
+  __ mov(eax, Operand(esp, 1 * kPointerSize));
+
+  // Check if the argument is a smi.
+  Label not_smi;
+  STATIC_ASSERT(kSmiTag == 0);
+  __ test(eax, Immediate(kSmiTagMask));
+  __ j(not_zero, &not_smi);
+
+  // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
+  // otherwise.
+  __ mov(ebx, eax);
+  __ sar(ebx, kBitsPerInt - 1);
+
+  // Do bitwise not or do nothing depending on ebx.
+  __ xor_(eax, Operand(ebx));
+
+  // Add 1 or do nothing depending on ebx.
+  __ sub(eax, Operand(ebx));
+
+  // If the result is still negative, go to the slow case.
+  // This only happens for the most negative smi.
+  Label slow;
+  __ j(negative, &slow);
+
+  // Smi case done.
+  __ ret(2 * kPointerSize);
+
+  // Check if the argument is a heap number and load its exponent and
+  // sign into ebx.
+  __ bind(&not_smi);
+  __ CheckMap(eax, Factory::heap_number_map(), &slow, true);
+  __ mov(ebx, FieldOperand(eax, HeapNumber::kExponentOffset));
+
+  // Check the sign of the argument. If the argument is positive,
+  // just return it.
+  Label negative_sign;
+  __ test(ebx, Immediate(HeapNumber::kSignMask));
+  __ j(not_zero, &negative_sign);
+  __ ret(2 * kPointerSize);
+
+  // If the argument is negative, clear the sign, and return a new
+  // number.
+  __ bind(&negative_sign);
+  __ and_(ebx, ~HeapNumber::kSignMask);
+  __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset));
+  __ AllocateHeapNumber(eax, edi, edx, &slow);
+  __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx);
+  __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
+  __ ret(2 * kPointerSize);
+
+  // Tail call the full function. We do not have to patch the receiver
+  // because the function makes no use of it.
+  __ bind(&slow);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+
+  __ bind(&miss);
+  // ecx: function name.
+  Object* obj = GenerateMissBranch();
+  if (obj->IsFailure()) return obj;
+
+  // Return the generated code.
+  return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
+}
+
+
 Object* CallStubCompiler::CompileCallConstant(Object* object,
                                               JSObject* holder,
                                               JSFunction* function,
diff --git a/src/ic.cc b/src/ic.cc
index 5b62a8a..adf365a 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -299,7 +299,10 @@
   // present) to guarantee failure by holding an invalid map (the null
   // value).  The offset can be patched to anything.
   PatchInlinedLoad(address, Heap::null_value(), 0);
-  PatchInlinedContextualLoad(address, Heap::null_value(), Heap::null_value());
+  PatchInlinedContextualLoad(address,
+                             Heap::null_value(),
+                             Heap::null_value(),
+                             true);
 }
 
 
@@ -848,7 +851,10 @@
     JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(
         lookup.holder()->property_dictionary()->ValueAt(
             lookup.GetDictionaryEntry()));
-    if (PatchInlinedContextualLoad(address(), map, cell)) {
+    if (PatchInlinedContextualLoad(address(),
+                                   map,
+                                   cell,
+                                   lookup.IsDontDelete())) {
       set_target(megamorphic_stub());
       TRACE_IC_NAMED("[LoadIC : inline contextual patch %s]\n", name);
       ASSERT(cell->value() != Heap::the_hole_value());
@@ -1541,18 +1547,17 @@
 // Static IC stub generators.
 //
 
-static Object* CompileFunction(Object* result,
-                               Handle<Object> object,
-                               InLoopFlag in_loop) {
+static JSFunction* CompileFunction(JSFunction* function,
+                                   InLoopFlag in_loop) {
   // Compile now with optimization.
   HandleScope scope;
-  Handle<JSFunction> function = Handle<JSFunction>(JSFunction::cast(result));
+  Handle<JSFunction> function_handle(function);
   if (in_loop == IN_LOOP) {
-    CompileLazyInLoop(function, object, CLEAR_EXCEPTION);
+    CompileLazyInLoop(function_handle, CLEAR_EXCEPTION);
   } else {
-    CompileLazy(function, object, CLEAR_EXCEPTION);
+    CompileLazy(function_handle, CLEAR_EXCEPTION);
   }
-  return *function;
+  return *function_handle;
 }
 
 
@@ -1575,7 +1580,7 @@
   if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
     return result;
   }
-  return CompileFunction(result, args.at<Object>(0), ic.target()->ic_in_loop());
+  return CompileFunction(JSFunction::cast(result), ic.target()->ic_in_loop());
 }
 
 
@@ -1591,7 +1596,7 @@
   if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
     return result;
   }
-  return CompileFunction(result, args.at<Object>(0), ic.target()->ic_in_loop());
+  return CompileFunction(JSFunction::cast(result), ic.target()->ic_in_loop());
 }
 
 
diff --git a/src/ic.h b/src/ic.h
index a5fada0..437e45a 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -300,7 +300,8 @@
 
   static bool PatchInlinedContextualLoad(Address address,
                                          Object* map,
-                                         Object* cell);
+                                         Object* cell,
+                                         bool is_dont_delete);
 
   friend class IC;
 };
diff --git a/src/interpreter-irregexp.cc b/src/interpreter-irregexp.cc
index a904447..c9c3cc4 100644
--- a/src/interpreter-irregexp.cc
+++ b/src/interpreter-irregexp.cc
@@ -607,6 +607,15 @@
           pc = code_base + Load32Aligned(pc + 4);
         }
         break;
+      BYTECODE(SET_CURRENT_POSITION_FROM_END) {
+        int by = static_cast<uint32_t>(insn) >> BYTECODE_SHIFT;
+        if (subject.length() - current > by) {
+          current = subject.length() - by;
+          current_char = subject[current - 1];
+        }
+        pc += BC_SET_CURRENT_POSITION_FROM_END_LENGTH;
+        break;
+      }
       default:
         UNREACHABLE();
         break;
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 30d4dcb..3c5ddfb 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -125,7 +125,7 @@
   PostponeInterruptsScope postpone;
   RegExpCompileData parse_result;
   FlatStringReader reader(pattern);
-  if (!ParseRegExp(&reader, flags.is_multiline(), &parse_result)) {
+  if (!Parser::ParseRegExp(&reader, flags.is_multiline(), &parse_result)) {
     // Throw an exception if we fail to parse the pattern.
     ThrowRegExpException(re,
                          pattern,
@@ -267,7 +267,7 @@
 
   RegExpCompileData compile_data;
   FlatStringReader reader(pattern);
-  if (!ParseRegExp(&reader, flags.is_multiline(), &compile_data)) {
+  if (!Parser::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,
@@ -5180,7 +5180,10 @@
                                                     &compiler,
                                                     compiler.accept());
   RegExpNode* node = captured_body;
-  if (!data->tree->IsAnchored()) {
+  bool is_end_anchored = data->tree->IsAnchoredAtEnd();
+  bool is_start_anchored = data->tree->IsAnchoredAtStart();
+  int max_length = data->tree->max_match();
+  if (!is_start_anchored) {
     // Add a .*? at the beginning, outside the body capture, unless
     // this expression is anchored at the beginning.
     RegExpNode* loop_node =
@@ -5236,6 +5239,15 @@
   RegExpMacroAssemblerIrregexp macro_assembler(codes);
 #endif  // V8_INTERPRETED_REGEXP
 
+  // Inserted here, instead of in Assembler, because it depends on information
+  // in the AST that isn't replicated in the Node structure.
+  static const int kMaxBacksearchLimit = 1024;
+  if (is_end_anchored &&
+      !is_start_anchored &&
+      max_length < kMaxBacksearchLimit) {
+    macro_assembler.SetCurrentPositionFromEnd(max_length);
+  }
+
   return compiler.Assemble(&macro_assembler,
                            node,
                            data->capture_count,
diff --git a/src/liveedit-debugger.js b/src/liveedit-debugger.js
index be97989..83b703f 100644
--- a/src/liveedit-debugger.js
+++ b/src/liveedit-debugger.js
@@ -46,8 +46,7 @@
 
   // Forward declaration for minifier.
   var FunctionStatus;
-  
-  
+
   // Applies the change to the script.
   // The change is in form of list of chunks encoded in a single array as
   // a series of triplets (pos1_start, pos1_end, pos2_end)
@@ -58,7 +57,7 @@
 
     // Gather compile information about old version of script.
     var old_compile_info = GatherCompileInfo(old_source, script);
-  
+
     // Build tree structures for old and new versions of the script.
     var root_old_node = BuildCodeInfoTree(old_compile_info);
 
@@ -69,7 +68,7 @@
 
     // Find all SharedFunctionInfo's that were compiled from this script.
     FindLiveSharedInfos(root_old_node, script);
-    
+
     // Gather compile information about new version of script.
     var new_compile_info;
     try {
@@ -81,7 +80,7 @@
 
     // Link recompiled script data with other data.
     FindCorrespondingFunctions(root_old_node, root_new_node);
-    
+
     // Prepare to-do lists.
     var replace_code_list = new Array();
     var link_to_old_script_list = new Array();
@@ -104,7 +103,7 @@
           CollectNew(node_list[i].children);
         }
       }
-      
+
       if (old_node.status == FunctionStatus.DAMAGED) {
         CollectDamaged(old_node);
         return;
@@ -131,17 +130,17 @@
         },
         updated: false
     };
-    
+
     if (preview_only) {
       return preview_description;
     }
-    
+
     HarvestTodo(root_old_node);
-    
+
     // Collect shared infos for functions whose code need to be patched.
     var replaced_function_infos = new Array();
     for (var i = 0; i < replace_code_list.length; i++) {
-      var info_wrapper = replace_code_list[i].live_shared_info_wrapper; 
+      var info_wrapper = replace_code_list[i].live_shared_info_wrapper;
       if (info_wrapper) {
         replaced_function_infos.push(info_wrapper);
       }
@@ -149,14 +148,14 @@
 
     // We haven't changed anything before this line yet.
     // Committing all changes.
-    
+
     // Check that function being patched is not currently on stack or drop them.
     var dropped_functions_number =
         CheckStackActivations(replaced_function_infos, change_log);
-    
-    preview_description.stack_modified = dropped_functions_number != 0; 
-  
-    // Start with breakpoints. Convert their line/column positions and 
+
+    preview_description.stack_modified = dropped_functions_number != 0;
+
+    // Start with breakpoints. Convert their line/column positions and
     // temporary remove.
     var break_points_restorer = TemporaryRemoveBreakPoints(script, change_log);
 
@@ -169,24 +168,24 @@
       old_script = void 0;
     } else {
       var old_script_name = CreateNameForOldScript(script);
-      
+
       // Update the script text and create a new script representing an old
       // version of the script.
       old_script = %LiveEditReplaceScript(script, new_source,
           old_script_name);
-      
+
       var link_to_old_script_report = new Array();
       change_log.push( { linked_to_old_script: link_to_old_script_report } );
-    
+
       // We need to link to old script all former nested functions.
       for (var i = 0; i < link_to_old_script_list.length; i++) {
         LinkToOldScript(link_to_old_script_list[i], old_script,
             link_to_old_script_report);
       }
-      
+
       preview_description.created_script_name = old_script_name;
     }
-    
+
     // Link to an actual script all the functions that we are going to use.
     for (var i = 0; i < link_to_original_script_list.length; i++) {
       %LiveEditFunctionSetScript(
@@ -196,26 +195,26 @@
     for (var i = 0; i < replace_code_list.length; i++) {
       PatchFunctionCode(replace_code_list[i], change_log);
     }
-  
+
     var position_patch_report = new Array();
     change_log.push( {position_patched: position_patch_report} );
-    
+
     for (var i = 0; i < update_positions_list.length; i++) {
       // TODO(LiveEdit): take into account wether it's source_changed or
       // unchanged and whether positions changed at all.
       PatchPositions(update_positions_list[i], diff_array,
           position_patch_report);
     }
-    
+
     break_points_restorer(pos_translator, old_script);
-    
+
     preview_description.updated = true;
     return preview_description;
   }
   // Function is public.
   this.ApplyPatchMultiChunk = ApplyPatchMultiChunk;
 
-  
+
   // Fully compiles source string as a script. Returns Array of
   // FunctionCompileInfo -- a descriptions of all functions of the script.
   // Elements of array are ordered by start positions of functions (from top
@@ -224,7 +223,7 @@
   //
   // All functions get compiled linked to script provided as parameter script.
   // TODO(LiveEdit): consider not using actual scripts as script, because
-  //     we have to manually erase all links right after compile. 
+  // we have to manually erase all links right after compile.
   function GatherCompileInfo(source, script) {
     // Get function info, elements are partially sorted (it is a tree of
     // nested functions serialized as parent followed by serialized children.
@@ -291,7 +290,7 @@
     return compile_info;
   }
 
-  
+
   // Replaces function's Code.
   function PatchFunctionCode(old_node, change_log) {
     var new_info = old_node.corresponding_node.info;
@@ -318,7 +317,7 @@
           }
         }
       }
-      
+
       change_log.push( {function_patched: new_info.function_name} );
     } else {
       change_log.push( {function_patched: new_info.function_name,
@@ -326,7 +325,7 @@
     }
   }
 
-  
+
   // Makes a function associated with another instance of a script (the
   // one representing its old version). This way the function still
   // may access its own text.
@@ -340,12 +339,12 @@
           { name: old_info_node.info.function_name, not_found: true } );
     }
   }
-  
+
 
   // Returns function that restores breakpoints.
   function TemporaryRemoveBreakPoints(original_script, change_log) {
     var script_break_points = GetScriptBreakPoints(original_script);
-    
+
     var break_points_update_report = [];
     change_log.push( { break_points_update: break_points_update_report } );
 
@@ -354,11 +353,11 @@
       var break_point = script_break_points[i];
 
       break_point.clear();
-      
-      // TODO(LiveEdit): be careful with resource offset here. 
+
+      // TODO(LiveEdit): be careful with resource offset here.
       var break_point_position = Debug.findScriptSourcePosition(original_script,
           break_point.line(), break_point.column());
-      
+
       var old_position_description = {
           position: break_point_position,
           line: break_point.line(),
@@ -366,8 +365,8 @@
       }
       break_point_old_positions.push(old_position_description);
     }
-    
-    
+
+
     // Restores breakpoints and creates their copies in the "old" copy of
     // the script.
     return function (pos_translator, old_script_copy_opt) {
@@ -378,19 +377,19 @@
         if (old_script_copy_opt) {
           var clone = break_point.cloneForOtherScript(old_script_copy_opt);
           clone.set(old_script_copy_opt);
-          
+
           break_points_update_report.push( {
             type: "copied_to_old",
             id: break_point.number(),
-            new_id: clone.number(), 
+            new_id: clone.number(),
             positions: break_point_old_positions[i]
             } );
         }
-        
+
         var updated_position = pos_translator.Translate(
             break_point_old_positions[i].position,
             PosTranslator.ShiftWithTopInsideChunkHandler);
-        
+
         var new_location =
             original_script.locationFromPosition(updated_position, false);
 
@@ -401,9 +400,9 @@
             line: new_location.line,
             column: new_location.column
         }
-        
+
         break_point.set(original_script);
-        
+
         break_points_update_report.push( { type: "position_changed",
           id: break_point.number(),
           old_positions: break_point_old_positions[i],
@@ -413,7 +412,7 @@
     }
   }
 
-  
+
   function Assert(condition, message) {
     if (!condition) {
       if (message) {
@@ -430,7 +429,7 @@
     this.len1 = len1;
     this.len2 = len2;
   }
-  
+
   function PosTranslator(diff_array) {
     var chunks = new Array();
     var current_diff = 0;
@@ -441,16 +440,16 @@
       var pos2_end = diff_array[i + 2];
       chunks.push(new DiffChunk(pos1_begin, pos2_begin, pos1_end - pos1_begin,
           pos2_end - pos2_begin));
-      current_diff = pos2_end - pos1_end; 
+      current_diff = pos2_end - pos1_end;
     }
     this.chunks = chunks;
   }
   PosTranslator.prototype.GetChunks = function() {
     return this.chunks;
   }
-  
+
   PosTranslator.prototype.Translate = function(pos, inside_chunk_handler) {
-    var array = this.chunks; 
+    var array = this.chunks;
     if (array.length == 0 || pos < array[0].pos1) {
       return pos;
     }
@@ -467,9 +466,9 @@
     }
     var chunk = array[chunk_index1];
     if (pos >= chunk.pos1 + chunk.len1) {
-      return pos + chunk.pos2 + chunk.len2 - chunk.pos1 - chunk.len1; 
+      return pos + chunk.pos2 + chunk.len2 - chunk.pos1 - chunk.len1;
     }
-    
+
     if (!inside_chunk_handler) {
       inside_chunk_handler = PosTranslator.DefaultInsideChunkHandler;
     }
@@ -479,17 +478,17 @@
   PosTranslator.DefaultInsideChunkHandler = function(pos, diff_chunk) {
     Assert(false, "Cannot translate position in changed area");
   }
-  
+
   PosTranslator.ShiftWithTopInsideChunkHandler =
       function(pos, diff_chunk) {
     // We carelessly do not check whether we stay inside the chunk after
     // translation.
-    return pos - diff_chunk.pos1 + diff_chunk.pos2; 
+    return pos - diff_chunk.pos1 + diff_chunk.pos2;
   }
-  
+
   var FunctionStatus = {
       // No change to function or its inner functions; however its positions
-      // in script may have been shifted. 
+      // in script may have been shifted.
       UNCHANGED: "unchanged",
       // The code of a function remains unchanged, but something happened inside
       // some inner functions.
@@ -500,14 +499,14 @@
       // Function is changed but cannot be patched.
       DAMAGED: "damaged"
   }
-  
+
   function CodeInfoTreeNode(code_info, children, array_index) {
     this.info = code_info;
     this.children = children;
     // an index in array of compile_info
-    this.array_index = array_index; 
+    this.array_index = array_index;
     this.parent = void 0;
-    
+
     this.status = FunctionStatus.UNCHANGED;
     // Status explanation is used for debugging purposes and will be shown
     // in user UI if some explanations are needed.
@@ -516,26 +515,26 @@
     this.new_end_pos = void 0;
     this.corresponding_node = void 0;
     this.unmatched_new_nodes = void 0;
-    
+
     // 'Textual' correspondence/matching is weaker than 'pure'
     // correspondence/matching. We need 'textual' level for visual presentation
     // in UI, we use 'pure' level for actual code manipulation.
     // Sometimes only function body is changed (functions in old and new script
     // textually correspond), but we cannot patch the code, so we see them
-    // as an old function deleted and new function created.  
+    // as an old function deleted and new function created.
     this.textual_corresponding_node = void 0;
     this.textually_unmatched_new_nodes = void 0;
-    
+
     this.live_shared_info_wrapper = void 0;
   }
-  
+
   // From array of function infos that is implicitly a tree creates
   // an actual tree of functions in script.
   function BuildCodeInfoTree(code_info_array) {
     // Throughtout all function we iterate over input array.
     var index = 0;
 
-    // Recursive function that builds a branch of tree. 
+    // Recursive function that builds a branch of tree.
     function BuildNode() {
       var my_index = index;
       index++;
@@ -551,7 +550,7 @@
       }
       return node;
     }
-    
+
     var root = BuildNode();
     Assert(index == code_info_array.length);
     return root;
@@ -570,7 +569,7 @@
       this.current = function() { return chunks[chunk_index]; }
       this.next = function() {
         var chunk = chunks[chunk_index];
-        pos_diff = chunk.pos2 + chunk.len2 - (chunk.pos1 + chunk.len1); 
+        pos_diff = chunk.pos2 + chunk.len2 - (chunk.pos1 + chunk.len1);
         chunk_index++;
       }
       this.done = function() { return chunk_index >= chunks.length; }
@@ -582,7 +581,7 @@
     // below function start.
     function ProcessInternals(info_node) {
       info_node.new_start_pos = chunk_it.TranslatePos(
-          info_node.info.start_position); 
+          info_node.info.start_position);
       var child_index = 0;
       var code_changed = false;
       var source_changed = false;
@@ -591,7 +590,7 @@
           chunk_it.current().pos1 < info_node.info.end_position) {
         if (child_index < info_node.children.length) {
           var child = info_node.children[child_index];
-          
+
           if (child.info.end_position <= chunk_it.current().pos1) {
             ProcessUnchangedChild(child);
             child_index++;
@@ -620,7 +619,7 @@
             continue;
           }
         } else {
-          if (chunk_it.current().pos1 + chunk_it.current().len1 <= 
+          if (chunk_it.current().pos1 + chunk_it.current().len1 <=
               info_node.info.end_position) {
             info_node.status = FunctionStatus.CHANGED;
             chunk_it.next();
@@ -645,14 +644,14 @@
         info_node.status = FunctionStatus.SOURCE_CHANGED;
       }
       info_node.new_end_pos =
-          chunk_it.TranslatePos(info_node.info.end_position); 
+          chunk_it.TranslatePos(info_node.info.end_position);
     }
-    
+
     function ProcessUnchangedChild(node) {
       node.new_start_pos = chunk_it.TranslatePos(node.info.start_position);
       node.new_end_pos = chunk_it.TranslatePos(node.info.end_position);
     }
-    
+
     ProcessInternals(code_info_tree);
   }
 
@@ -670,7 +669,7 @@
     function ProcessChildren(old_node, new_node) {
       var old_children = old_node.children;
       var new_children = new_node.children;
-      
+
       var unmatched_new_nodes_list = [];
       var textually_unmatched_new_nodes_list = [];
 
@@ -728,13 +727,13 @@
           old_index++;
         }
       }
-      
+
       while (new_index < new_children.length) {
         unmatched_new_nodes_list.push(new_children[new_index]);
         textually_unmatched_new_nodes_list.push(new_children[new_index]);
         new_index++;
       }
-      
+
       if (old_node.status == FunctionStatus.CHANGED) {
         var why_wrong_expectations =
             WhyFunctionExpectationsDiffer(old_node.info, new_node.info);
@@ -749,23 +748,23 @@
     }
 
     ProcessChildren(old_code_tree, new_code_tree);
-    
+
     old_code_tree.corresponding_node = new_code_tree;
     old_code_tree.textual_corresponding_node = new_code_tree;
 
     Assert(old_code_tree.status != FunctionStatus.DAMAGED,
         "Script became damaged");
   }
-  
+
   function FindLiveSharedInfos(old_code_tree, script) {
     var shared_raw_list = %LiveEditFindSharedFunctionInfosForScript(script);
-    
+
     var shared_infos = new Array();
-  
+
     for (var i = 0; i < shared_raw_list.length; i++) {
       shared_infos.push(new SharedInfoWrapper(shared_raw_list[i]));
     }
-    
+
     // Finds SharedFunctionInfo that corresponds compile info with index
     // in old version of the script.
     function FindFunctionInfo(compile_info) {
@@ -777,7 +776,7 @@
         }
       }
     }
-    
+
     function TraverseTree(node) {
       var info_wrapper = FindFunctionInfo(node.info);
       if (info_wrapper) {
@@ -791,7 +790,7 @@
     TraverseTree(old_code_tree);
   }
 
-  
+
   // An object describing function compilation details. Its index fields
   // apply to indexes inside array that stores these objects.
   function FunctionCompileInfo(raw_array) {
@@ -807,7 +806,7 @@
     this.next_sibling_index = null;
     this.raw_array = raw_array;
   }
-  
+
   function SharedInfoWrapper(raw_array) {
     this.function_name = raw_array[0];
     this.start_position = raw_array[1];
@@ -821,7 +820,7 @@
     var shared_info_wrapper = old_info_node.live_shared_info_wrapper;
     if (!shared_info_wrapper) {
       // TODO(LiveEdit): function is not compiled yet or is already collected.
-      report_array.push( 
+      report_array.push(
           { name: old_info_node.info.function_name, info_not_found: true } );
       return;
     }
@@ -835,44 +834,44 @@
     // TODO(635): try better than this; support several changes.
     return script.name + " (old)";
   }
-  
+
   // Compares a function interface old and new version, whether it
   // changed or not. Returns explanation if they differ.
   function WhyFunctionExpectationsDiffer(function_info1, function_info2) {
     // Check that function has the same number of parameters (there may exist
     // an adapter, that won't survive function parameter number change).
     if (function_info1.param_num != function_info2.param_num) {
-      return "Changed parameter number: " + function_info1.param_num + 
+      return "Changed parameter number: " + function_info1.param_num +
           " and " + function_info2.param_num;
     }
     var scope_info1 = function_info1.scope_info;
     var scope_info2 = function_info2.scope_info;
 
-    var scope_info1_text; 
-    var scope_info2_text; 
-    
+    var scope_info1_text;
+    var scope_info2_text;
+
     if (scope_info1) {
-      scope_info1_text = scope_info1.toString(); 
+      scope_info1_text = scope_info1.toString();
     } else {
       scope_info1_text = "";
     }
     if (scope_info2) {
-      scope_info2_text = scope_info2.toString(); 
+      scope_info2_text = scope_info2.toString();
     } else {
       scope_info2_text = "";
     }
-    
+
     if (scope_info1_text != scope_info2_text) {
       return "Incompatible variable maps: [" + scope_info1_text +
-          "] and [" + scope_info2_text + "]";  
+          "] and [" + scope_info2_text + "]";
     }
     // No differences. Return undefined.
     return;
   }
-  
+
   // Minifier forward declaration.
   var FunctionPatchabilityStatus;
-  
+
   // For array of wrapped shared function infos checks that none of them
   // have activations on stack (of any thread). Throws a Failure exception
   // if this proves to be false.
@@ -886,7 +885,7 @@
       // Extra array element may contain error message.
       throw new Failure(result[shared_list.length]);
     }
-  
+
     var problems = new Array();
     var dropped = new Array();
     for (var i = 0; i < shared_list.length; i++) {
@@ -896,7 +895,7 @@
       } else if (result[i] != FunctionPatchabilityStatus.AVAILABLE_FOR_PATCH) {
         var description = {
             name: shared.function_name,
-            start_pos: shared.start_position, 
+            start_pos: shared.start_position,
             end_pos: shared.end_position,
             replace_problem:
                 FunctionPatchabilityStatus.SymbolName(result[i])
@@ -911,10 +910,10 @@
       change_log.push( { functions_on_stack: problems } );
       throw new Failure("Blocked by functions on stack");
     }
-    
+
     return dropped.length;
   }
-  
+
   // A copy of the FunctionPatchabilityStatus enum from liveedit.h
   var FunctionPatchabilityStatus = {
       AVAILABLE_FOR_PATCH: 1,
@@ -923,17 +922,17 @@
       BLOCKED_UNDER_NATIVE_CODE: 4,
       REPLACED_ON_ACTIVE_STACK: 5
   }
-  
+
   FunctionPatchabilityStatus.SymbolName = function(code) {
     var enum = FunctionPatchabilityStatus;
     for (name in enum) {
       if (enum[name] == code) {
         return name;
       }
-    }      
+    }
   }
-  
-  
+
+
   // A logical failure in liveedit process. This means that change_log
   // is valid and consistent description of what happened.
   function Failure(message) {
@@ -941,11 +940,11 @@
   }
   // Function (constructor) is public.
   this.Failure = Failure;
-  
+
   Failure.prototype.toString = function() {
     return "LiveEdit Failure: " + this.message;
   }
-  
+
   // A testing entry.
   function GetPcFromSourcePos(func, source_pos) {
     return %GetFunctionCodePositionFromSource(func, source_pos);
@@ -962,7 +961,7 @@
   }
   // Function is public.
   this.SetScriptSource = SetScriptSource;
-  
+
   function CompareStringsLinewise(s1, s2) {
     return %LiveEditCompareStringsLinewise(s1, s2);
   }
@@ -978,19 +977,19 @@
   function ApplySingleChunkPatch(script, change_pos, change_len, new_str,
       change_log) {
     var old_source = script.source;
-  
+
     // Prepare new source string.
     var new_source = old_source.substring(0, change_pos) +
         new_str + old_source.substring(change_pos + change_len);
-    
+
     return ApplyPatchMultiChunk(script,
         [ change_pos, change_pos + change_len, change_pos + new_str.length],
         new_source, false, change_log);
   }
-  
+
   // Creates JSON description for a change tree.
   function DescribeChangeTree(old_code_tree) {
-    
+
     function ProcessOldNode(node) {
       var child_infos = [];
       for (var i = 0; i < node.children.length; i++) {
@@ -1011,7 +1010,7 @@
         positions: DescribePositions(node),
         status: node.status,
         children: child_infos,
-        new_children: new_child_infos  
+        new_children: new_child_infos
       };
       if (node.status_explanation) {
         res.status_explanation = node.status_explanation;
@@ -1021,7 +1020,7 @@
       }
       return res;
     }
-    
+
     function ProcessNewNode(node) {
       var child_infos = [];
       // Do not list ancestors.
@@ -1037,18 +1036,18 @@
       };
       return res;
     }
-    
+
     function DescribePositions(node) {
       return {
         start_position: node.info.start_position,
         end_position: node.info.end_position
       };
     }
-    
+
     return ProcessOldNode(old_code_tree);
   }
 
-  
+
   // Functions are public for tests.
   this.TestApi = {
     PosTranslator: PosTranslator,
diff --git a/src/liveedit.cc b/src/liveedit.cc
index c07e83f..3cbd244 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -29,13 +29,15 @@
 #include "v8.h"
 
 #include "liveedit.h"
+
 #include "compiler.h"
-#include "oprofile-agent.h"
-#include "scopes.h"
-#include "scopeinfo.h"
-#include "global-handles.h"
 #include "debug.h"
+#include "global-handles.h"
 #include "memory.h"
+#include "oprofile-agent.h"
+#include "parser.h"
+#include "scopeinfo.h"
+#include "scopes.h"
 
 namespace v8 {
 namespace internal {
@@ -396,45 +398,31 @@
 
 
 static void CompileScriptForTracker(Handle<Script> script) {
-  const bool is_eval = false;
-  const bool is_global = true;
   // TODO(635): support extensions.
-  Extension* extension = NULL;
-
   PostponeInterruptsScope postpone;
 
-  // Only allow non-global compiles for eval.
-  ASSERT(is_eval || is_global);
-
   // Build AST.
-  ScriptDataImpl* pre_data = NULL;
-  FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data);
-
-  // Check for parse errors.
-  if (lit == NULL) {
-    ASSERT(Top::has_pending_exception());
-    return;
+  CompilationInfo info(script);
+  info.MarkAsGlobal();
+  if (Parser::Parse(&info)) {
+    // Compile the code.
+    LiveEditFunctionTracker tracker(info.function());
+    if (Compiler::MakeCodeForLiveEdit(&info)) {
+      ASSERT(!info.code().is_null());
+      tracker.RecordRootFunctionInfo(info.code());
+    } else {
+      Top::StackOverflow();
+    }
   }
-
-  // Compile the code.
-  CompilationInfo info(lit, script, is_eval);
-
-  LiveEditFunctionTracker tracker(lit);
-  Handle<Code> code = MakeCodeForLiveEdit(&info);
-
-  // Check for stack-overflow exceptions.
-  if (code.is_null()) {
-    Top::StackOverflow();
-    return;
-  }
-  tracker.RecordRootFunctionInfo(code);
 }
 
+
 // Unwraps JSValue object, returning its field "value"
 static Handle<Object> UnwrapJSValue(Handle<JSValue> jsValue) {
   return Handle<Object>(jsValue->value());
 }
 
+
 // Wraps any object into a OpaqueReference, that will hide the object
 // from JavaScript.
 static Handle<JSValue> WrapInJSValue(Object* object) {
@@ -445,6 +433,7 @@
   return result;
 }
 
+
 // Simple helper class that creates more or less typed structures over
 // JSArray object. This is an adhoc method of passing structures from C++
 // to JavaScript.
@@ -465,6 +454,7 @@
   Handle<JSArray> GetJSArray() {
     return array_;
   }
+
  protected:
   void SetField(int field_position, Handle<Object> value) {
     SetElement(array_, field_position, value);
@@ -479,6 +469,7 @@
     Object* res = GetField(field_position);
     return Smi::cast(res)->value();
   }
+
  private:
   Handle<JSArray> array_;
 };
@@ -551,6 +542,7 @@
   friend class JSArrayBasedStruct<FunctionInfoWrapper>;
 };
 
+
 // Wraps SharedFunctionInfo along with some of its fields for passing it
 // back to JavaScript. SharedFunctionInfo object itself is additionally
 // wrapped into BlindReference for sanitizing reasons.
@@ -591,6 +583,7 @@
   friend class JSArrayBasedStruct<SharedInfoWrapper>;
 };
 
+
 class FunctionInfoListener {
  public:
   FunctionInfoListener() {
@@ -617,7 +610,6 @@
     current_parent_index_ = info.GetParentIndex();
   }
 
- public:
   // Saves only function code, because for a script function we
   // may never create a SharedFunctionInfo object.
   void FunctionCode(Handle<Code> function_code) {
@@ -705,6 +697,7 @@
   int current_parent_index_;
 };
 
+
 static FunctionInfoListener* active_function_info_listener = NULL;
 
 JSArray* LiveEdit::GatherCompileInfo(Handle<Script> script,
diff --git a/src/log-utils.cc b/src/log-utils.cc
index 62f0ca6..d6d8754 100644
--- a/src/log-utils.cc
+++ b/src/log-utils.cc
@@ -122,6 +122,7 @@
 bool Log::is_stopped_ = false;
 Log::WritePtr Log::Write = NULL;
 FILE* Log::output_handle_ = NULL;
+FILE* Log::output_code_handle_ = NULL;
 LogDynamicBuffer* Log::output_buffer_ = NULL;
 // Must be the same message as in Logger::PauseProfiler.
 const char* Log::kDynamicBufferSeal = "profiler,\"pause\"\n";
@@ -143,9 +144,22 @@
 }
 
 
+static const char kCodeLogExt[] = ".code";
+
+
 void Log::OpenFile(const char* name) {
   ASSERT(!IsEnabled());
   output_handle_ = OS::FOpen(name, OS::LogFileOpenMode);
+  if (FLAG_ll_prof) {
+    // Open a file for logging the contents of code objects so that
+    // they can be disassembled later.
+    size_t name_len = strlen(name);
+    ScopedVector<char> code_name(
+        static_cast<int>(name_len + sizeof(kCodeLogExt)));
+    memcpy(code_name.start(), name, name_len);
+    memcpy(code_name.start() + name_len, kCodeLogExt, sizeof(kCodeLogExt));
+    output_code_handle_ = OS::FOpen(code_name.start(), OS::LogFileOpenMode);
+  }
   Write = WriteToFile;
   Init();
 }
@@ -165,6 +179,8 @@
   if (Write == WriteToFile) {
     if (output_handle_ != NULL) fclose(output_handle_);
     output_handle_ = NULL;
+    if (output_code_handle_ != NULL) fclose(output_code_handle_);
+    output_code_handle_ = NULL;
   } else if (Write == WriteToMemory) {
     delete output_buffer_;
     output_buffer_ = NULL;
diff --git a/src/log-utils.h b/src/log-utils.h
index 8889f1b..ffea928 100644
--- a/src/log-utils.h
+++ b/src/log-utils.h
@@ -132,6 +132,7 @@
     size_t rv = fwrite(msg, 1, length, output_handle_);
     ASSERT(static_cast<size_t>(length) == rv);
     USE(rv);
+    fflush(output_handle_);
     return length;
   }
 
@@ -151,6 +152,9 @@
   // mutex_ should be acquired before using output_handle_ or output_buffer_.
   static FILE* output_handle_;
 
+  // Used when low-level profiling is active to save code object contents.
+  static FILE* output_code_handle_;
+
   static LogDynamicBuffer* output_buffer_;
 
   // Size of dynamic buffer block (and dynamic buffer initial size).
@@ -170,6 +174,7 @@
   // mutex_ should be acquired before using it.
   static char* message_buffer_;
 
+  friend class Logger;
   friend class LogMessageBuilder;
   friend class LogRecordCompressor;
 };
diff --git a/src/log.cc b/src/log.cc
index 5c70057..1b0fdeb 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -191,11 +191,12 @@
 
   ~Ticker() { if (IsActive()) Stop(); }
 
-  void SampleStack(TickSample* sample) {
+  virtual void SampleStack(TickSample* sample) {
+    ASSERT(IsSynchronous());
     StackTracer::Trace(sample);
   }
 
-  void Tick(TickSample* sample) {
+  virtual void Tick(TickSample* sample) {
     if (profiler_) profiler_->Insert(sample);
     if (window_) window_->AddState(sample->state);
   }
@@ -393,6 +394,13 @@
 }
 
 
+void Logger::IntPtrTEvent(const char* name, intptr_t value) {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+  if (FLAG_log) UncheckedIntPtrTEvent(name, value);
+#endif
+}
+
+
 #ifdef ENABLE_LOGGING_AND_PROFILING
 void Logger::UncheckedIntEvent(const char* name, int value) {
   if (!Log::IsEnabled()) return;
@@ -403,6 +411,16 @@
 #endif
 
 
+#ifdef ENABLE_LOGGING_AND_PROFILING
+void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
+  if (!Log::IsEnabled()) return;
+  LogMessageBuilder msg;
+  msg.Append("%s,%" V8_PTR_PREFIX "d\n", name, value);
+  msg.WriteToLogFile();
+}
+#endif
+
+
 void Logger::HandleEvent(const char* name, Object** location) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (!Log::IsEnabled() || !FLAG_log_handles) return;
@@ -748,6 +766,7 @@
     msg.Append(*p);
   }
   msg.Append('"');
+  LowLevelCodeCreateEvent(code, &msg);
   if (FLAG_compress_log) {
     ASSERT(compression_helper_ != NULL);
     if (!compression_helper_->HandleMessage(&msg)) return;
@@ -767,6 +786,7 @@
   msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]);
   msg.AppendAddress(code->address());
   msg.Append(",%d,\"%s\"", code->ExecutableSize(), *str);
+  LowLevelCodeCreateEvent(code, &msg);
   if (FLAG_compress_log) {
     ASSERT(compression_helper_ != NULL);
     if (!compression_helper_->HandleMessage(&msg)) return;
@@ -791,6 +811,7 @@
   msg.AppendAddress(code->address());
   msg.Append(",%d,\"%s %s:%d\"",
              code->ExecutableSize(), *str, *sourcestr, line);
+  LowLevelCodeCreateEvent(code, &msg);
   if (FLAG_compress_log) {
     ASSERT(compression_helper_ != NULL);
     if (!compression_helper_->HandleMessage(&msg)) return;
@@ -808,6 +829,7 @@
   msg.Append("%s,%s,", log_events_[CODE_CREATION_EVENT], log_events_[tag]);
   msg.AppendAddress(code->address());
   msg.Append(",%d,\"args_count: %d\"", code->ExecutableSize(), args_count);
+  LowLevelCodeCreateEvent(code, &msg);
   if (FLAG_compress_log) {
     ASSERT(compression_helper_ != NULL);
     if (!compression_helper_->HandleMessage(&msg)) return;
@@ -818,6 +840,17 @@
 }
 
 
+void Logger::CodeMovingGCEvent() {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+  if (!Log::IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
+  LogMessageBuilder msg;
+  msg.Append("%s\n", log_events_[CODE_MOVING_GC]);
+  msg.WriteToLogFile();
+  OS::SignalCodeMovingGC();
+#endif
+}
+
+
 void Logger::RegExpCodeCreateEvent(Code* code, String* source) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (!Log::IsEnabled() || !FLAG_log_code) return;
@@ -828,6 +861,7 @@
   msg.Append(",%d,\"", code->ExecutableSize());
   msg.AppendDetailed(source, false);
   msg.Append('\"');
+  LowLevelCodeCreateEvent(code, &msg);
   if (FLAG_compress_log) {
     ASSERT(compression_helper_ != NULL);
     if (!compression_helper_->HandleMessage(&msg)) return;
@@ -892,8 +926,7 @@
 }
 
 
-void Logger::FunctionCreateEventFromMove(JSFunction* function,
-                                         HeapObject*) {
+void Logger::FunctionCreateEventFromMove(JSFunction* function) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (function->unchecked_code() != Builtins::builtin(Builtins::LazyCompile)) {
     FunctionCreateEvent(function);
@@ -1005,11 +1038,12 @@
 
 
 void Logger::HeapSampleStats(const char* space, const char* kind,
-                             int capacity, int used) {
+                             intptr_t capacity, intptr_t used) {
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (!Log::IsEnabled() || !FLAG_log_gc) return;
   LogMessageBuilder msg;
-  msg.Append("heap-sample-stats,\"%s\",\"%s\",%d,%d\n",
+  msg.Append("heap-sample-stats,\"%s\",\"%s\","
+                 "%" V8_PTR_PREFIX "d,%" V8_PTR_PREFIX "d\n",
              space, kind, capacity, used);
   msg.WriteToLogFile();
 #endif
@@ -1322,6 +1356,34 @@
 }
 
 
+void Logger::LogCodeInfo() {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+  if (!Log::IsEnabled() || !FLAG_log_code || !FLAG_ll_prof) return;
+#if V8_TARGET_ARCH_IA32
+  const char arch[] = "ia32";
+#elif V8_TARGET_ARCH_X64
+  const char arch[] = "x64";
+#elif V8_TARGET_ARCH_ARM
+  const char arch[] = "arm";
+#else
+  const char arch[] = "unknown";
+#endif
+  LogMessageBuilder msg;
+  msg.Append("code-info,%s,%d\n", arch, Code::kHeaderSize);
+  msg.WriteToLogFile();
+#endif  // ENABLE_LOGGING_AND_PROFILING
+}
+
+
+void Logger::LowLevelCodeCreateEvent(Code* code, LogMessageBuilder* msg) {
+  if (!FLAG_ll_prof || Log::output_code_handle_ == NULL) return;
+  int pos = static_cast<int>(ftell(Log::output_code_handle_));
+  fwrite(code->instruction_start(), 1, code->instruction_size(),
+         Log::output_code_handle_);
+  msg->Append(",%d", pos);
+}
+
+
 void Logger::LogCodeObjects() {
   AssertNoAllocation no_alloc;
   HeapIterator iterator;
@@ -1433,6 +1495,12 @@
   // --prof implies --log-code.
   if (FLAG_prof) FLAG_log_code = true;
 
+  // --ll-prof implies --log-code and --log-snapshot-positions.
+  if (FLAG_ll_prof) {
+    FLAG_log_code = true;
+    FLAG_log_snapshot_positions = true;
+  }
+
   // --prof_lazy controls --log-code, implies --noprof_auto.
   if (FLAG_prof_lazy) {
     FLAG_log_code = false;
@@ -1494,6 +1562,8 @@
 
   ASSERT(VMState::is_outermost_external());
 
+  if (FLAG_ll_prof) LogCodeInfo();
+
   ticker_ = new Ticker(kSamplingIntervalMs);
 
   if (FLAG_sliding_state_window && sliding_state_window_ == NULL) {
diff --git a/src/log.h b/src/log.h
index 2534e1e..3a4d79b 100644
--- a/src/log.h
+++ b/src/log.h
@@ -91,6 +91,7 @@
   V(CODE_CREATION_EVENT,            "code-creation",          "cc")       \
   V(CODE_MOVE_EVENT,                "code-move",              "cm")       \
   V(CODE_DELETE_EVENT,              "code-delete",            "cd")       \
+  V(CODE_MOVING_GC,                 "code-moving-gc",         "cg")       \
   V(FUNCTION_CREATION_EVENT,        "function-creation",      "fc")       \
   V(FUNCTION_MOVE_EVENT,            "function-move",          "fm")       \
   V(FUNCTION_DELETE_EVENT,          "function-delete",        "fd")       \
@@ -159,6 +160,7 @@
 
   // Emits an event with an int value -> (name, value).
   static void IntEvent(const char* name, int value);
+  static void IntPtrTEvent(const char* name, intptr_t value);
 
   // Emits an event with an handle value -> (name, location).
   static void HandleEvent(const char* name, Object** location);
@@ -208,6 +210,7 @@
   static void CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name,
                               String* source, int line);
   static void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count);
+  static void CodeMovingGCEvent();
   // Emits a code create event for a RegExp.
   static void RegExpCodeCreateEvent(Code* code, String* source);
   // Emits a code move event.
@@ -216,8 +219,7 @@
   static void CodeDeleteEvent(Address from);
   // Emits a function object create event.
   static void FunctionCreateEvent(JSFunction* function);
-  static void FunctionCreateEventFromMove(JSFunction* function,
-                                          HeapObject*);
+  static void FunctionCreateEventFromMove(JSFunction* function);
   // Emits a function move event.
   static void FunctionMoveEvent(Address from, Address to);
   // Emits a function delete event.
@@ -237,7 +239,7 @@
   static void HeapSampleJSProducerEvent(const char* constructor,
                                         Address* stack);
   static void HeapSampleStats(const char* space, const char* kind,
-                              int capacity, int used);
+                              intptr_t capacity, intptr_t used);
 
   static void SharedLibraryEvent(const char* library_path,
                                  uintptr_t start,
@@ -316,6 +318,12 @@
   // Used for logging stubs found in the snapshot.
   static void LogCodeObject(Object* code_object);
 
+  // Emits general information about generated code.
+  static void LogCodeInfo();
+
+  // Handles code creation when low-level profiling is active.
+  static void LowLevelCodeCreateEvent(Code* code, LogMessageBuilder* msg);
+
   // Emits a profiler tick event. Used by the profiler thread.
   static void TickEvent(TickSample* sample, bool overflow);
 
@@ -326,6 +334,7 @@
 
   // Logs an IntEvent regardless of whether FLAG_log is true.
   static void UncheckedIntEvent(const char* name, int value);
+  static void UncheckedIntPtrTEvent(const char* name, intptr_t value);
 
   // Stops logging and profiling in case of insufficient resources.
   static void StopLoggingAndProfiling();
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index c847b84..ad928ea 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -167,8 +167,8 @@
   // reclaiming the waste and free list blocks).
   static const int kFragmentationLimit = 15;        // Percent.
   static const int kFragmentationAllowed = 1 * MB;  // Absolute.
-  int old_gen_recoverable = 0;
-  int old_gen_used = 0;
+  intptr_t old_gen_recoverable = 0;
+  intptr_t old_gen_used = 0;
 
   OldSpaces spaces;
   for (OldSpace* space = spaces.next(); space != NULL; space = spaces.next()) {
@@ -282,6 +282,11 @@
                                          FixedArray::BodyDescriptor,
                                          void>::Visit);
 
+    table_.Register(kVisitGlobalContext,
+                    &FixedBodyVisitor<StaticMarkingVisitor,
+                                      Context::MarkCompactBodyDescriptor,
+                                      void>::Visit);
+
     table_.Register(kVisitSharedFunctionInfo, &VisitSharedFunctionInfo);
 
     table_.Register(kVisitByteArray, &DataObjectVisitor::Visit);
@@ -578,6 +583,7 @@
     VisitPointers(SLOT_ADDR(object,
                             JSFunction::kCodeEntryOffset + kPointerSize),
                   SLOT_ADDR(object, JSFunction::kSize));
+
 #undef SLOT_ADDR
   }
 
@@ -738,6 +744,21 @@
 };
 
 
+// Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
+// are retained.
+class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
+ public:
+  virtual Object* RetainAs(Object* object) {
+    MapWord first_word = HeapObject::cast(object)->map_word();
+    if (first_word.IsMarked()) {
+      return object;
+    } else {
+      return NULL;
+    }
+  }
+};
+
+
 void MarkCompactCollector::MarkUnmarkedObject(HeapObject* object) {
   ASSERT(!object->IsMarked());
   ASSERT(Heap::Contains(object));
@@ -1069,6 +1090,10 @@
   ExternalStringTable::Iterate(&v);
   ExternalStringTable::CleanUp();
 
+  // Process the weak references.
+  MarkCompactWeakObjectRetainer mark_compact_object_retainer;
+  Heap::ProcessWeakReferences(&mark_compact_object_retainer);
+
   // Remove object groups after marking phase.
   GlobalHandles::RemoveObjectGroups();
 }
@@ -1639,6 +1664,9 @@
     }
   }
 
+  // Update pointer from the global contexts list.
+  updating_visitor.VisitPointer(Heap::global_contexts_list_address());
+
   // Update pointers from external string table.
   Heap::UpdateNewSpaceReferencesInExternalStringTable(
       &UpdateNewSpaceReferenceInExternalStringTableEntry);
@@ -2008,8 +2036,10 @@
 
 #ifdef DEBUG
       if (FLAG_gc_verbose) {
-        PrintF("update %p : %p -> %p\n", obj->address(),
-              map, new_map);
+        PrintF("update %p : %p -> %p\n",
+               obj->address(),
+               reinterpret_cast<void*>(map),
+               reinterpret_cast<void*>(new_map));
       }
 #endif
     }
@@ -2068,8 +2098,8 @@
                             &UpdatePointerToNewGen,
                             Heap::WATERMARK_SHOULD_BE_VALID);
 
-  int live_maps_size = Heap::map_space()->Size();
-  int live_maps = live_maps_size / Map::kSize;
+  intptr_t live_maps_size = Heap::map_space()->Size();
+  int live_maps = static_cast<int>(live_maps_size / Map::kSize);
   ASSERT(live_map_objects_size_ == live_maps_size);
 
   if (Heap::map_space()->NeedsCompaction(live_maps)) {
@@ -2243,6 +2273,9 @@
   Heap::IterateRoots(&updating_visitor, VISIT_ONLY_STRONG);
   GlobalHandles::IterateWeakRoots(&updating_visitor);
 
+  // Update the pointer to the head of the weak list of global contexts.
+  updating_visitor.VisitPointer(&Heap::global_contexts_list_);
+
   int live_maps_size = IterateLiveObjects(Heap::map_space(),
                                           &UpdatePointersInOldObject);
   int live_pointer_olds_size = IterateLiveObjects(Heap::old_pointer_space(),
@@ -2520,7 +2553,7 @@
   HeapObject* copied_to = HeapObject::FromAddress(new_addr);
   if (copied_to->IsJSFunction()) {
     PROFILE(FunctionMoveEvent(old_addr, new_addr));
-    PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to), obj));
+    PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to)));
   }
   HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr));
 
@@ -2613,7 +2646,7 @@
   HeapObject* copied_to = HeapObject::FromAddress(new_addr);
   if (copied_to->IsJSFunction()) {
     PROFILE(FunctionMoveEvent(old_addr, new_addr));
-    PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to), obj));
+    PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to)));
   }
   HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr));
 
diff --git a/src/messages.js b/src/messages.js
index 4f492bc..7f9c0f8 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -438,18 +438,18 @@
 
 /**
  * Returns the name of script if available, contents of sourceURL comment
- * otherwise. See 
+ * otherwise. See
  * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
  * for details on using //@ sourceURL comment to identify scritps that don't
  * have name.
- * 
+ *
  * @return {?string} script name if present, value for //@ sourceURL comment
  * otherwise.
  */
 Script.prototype.nameOrSourceURL = function() {
   if (this.name)
     return this.name;
-  // TODO(608): the spaces in a regexp below had to be escaped as \040 
+  // TODO(608): the spaces in a regexp below had to be escaped as \040
   // because this file is being processed by js2c whose handling of spaces
   // in regexps is broken. Also, ['"] are excluded from allowed URLs to
   // avoid matches against sources that invoke evals with sourceURL.
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 57bed6a..59a5373 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -39,7 +39,7 @@
 
 namespace v8i = v8::internal;
 
-#if !defined(__mips)
+#if !defined(__mips) || defined(USE_SIMULATOR)
 
 // Only build the simulator if not compiling for real MIPS hardware.
 namespace assembler {
@@ -1645,6 +1645,6 @@
 
 } }  // namespace assembler::mips
 
-#endif  // __mips
+#endif  // !__mips || USE_SIMULATOR
 
 #endif  // V8_TARGET_ARCH_MIPS
diff --git a/src/mips/simulator-mips.h b/src/mips/simulator-mips.h
index d5dfc30..6e42683 100644
--- a/src/mips/simulator-mips.h
+++ b/src/mips/simulator-mips.h
@@ -38,7 +38,7 @@
 
 #include "allocation.h"
 
-#if defined(__mips)
+#if defined(__mips) && !defined(USE_SIMULATOR)
 
 // When running without a simulator we call the entry directly.
 #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
@@ -79,7 +79,7 @@
   reinterpret_cast<TryCatch*>(try_catch_address)
 
 
-#else   // #if defined(__mips)
+#else  // #if !defined(__mips) || defined(USE_SIMULATOR)
 
 // When running with the simulator transition into simulated execution at this
 // point.
@@ -305,7 +305,7 @@
   }
 };
 
-#endif  // defined(__mips)
+#endif  // !defined(__mips) || defined(USE_SIMULATOR)
 
 #endif  // V8_MIPS_SIMULATOR_MIPS_H_
 
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index 761b9b3..6b9e965 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -1611,7 +1611,7 @@
     result += ' returning ';
     result += this.returnValue().toText();
   }
-  
+
   return result;
 }
 
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index ed08468..5883f8b 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -89,7 +89,7 @@
 
 
 void HeapObject::PrintHeader(const char* id) {
-  PrintF("%p: [%s]\n", this, id);
+  PrintF("%p: [%s]\n", reinterpret_cast<void*>(this), id);
 }
 
 
@@ -522,9 +522,9 @@
 
 
 void JSObject::JSObjectPrint() {
-  PrintF("%p: [JSObject]\n", this);
-  PrintF(" - map = %p\n", map());
-  PrintF(" - prototype = %p\n", GetPrototype());
+  PrintF("%p: [JSObject]\n", reinterpret_cast<void*>(this));
+  PrintF(" - map = %p\n", reinterpret_cast<void*>(map()));
+  PrintF(" - prototype = %p\n", reinterpret_cast<void*>(GetPrototype()));
   PrintF(" {\n");
   PrintProperties();
   PrintElements();
@@ -744,7 +744,7 @@
 
 void JSFunction::JSFunctionPrint() {
   HeapObject::PrintHeader("Function");
-  PrintF(" - map = 0x%p\n", map());
+  PrintF(" - map = 0x%p\n", reinterpret_cast<void*>(map()));
   PrintF(" - initial_map = ");
   if (has_initial_map()) {
     initial_map()->ShortPrint();
@@ -1224,9 +1224,9 @@
 
 void BreakPointInfo::BreakPointInfoPrint() {
   HeapObject::PrintHeader("BreakPointInfo");
-  PrintF("\n - code_position: %d", code_position());
-  PrintF("\n - source_position: %d", source_position());
-  PrintF("\n - statement_position: %d", statement_position());
+  PrintF("\n - code_position: %d", code_position()->value());
+  PrintF("\n - source_position: %d", source_position()->value());
+  PrintF("\n - statement_position: %d", statement_position()->value());
   PrintF("\n - break_point_objects: ");
   break_point_objects()->ShortPrint();
 }
diff --git a/src/objects-inl.h b/src/objects-inl.h
index f63d672..11f9d34 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -844,15 +844,6 @@
 }
 
 
-int Failure::requested() const {
-  const int kShiftBits =
-      kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
-  STATIC_ASSERT(kShiftBits >= 0);
-  ASSERT(type() == RETRY_AFTER_GC);
-  return static_cast<int>(value() >> kShiftBits);
-}
-
-
 AllocationSpace Failure::allocation_space() const {
   ASSERT_EQ(RETRY_AFTER_GC, type());
   return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
@@ -881,20 +872,14 @@
 }
 
 
-Failure* Failure::RetryAfterGC(int requested_bytes) {
-  // Assert that the space encoding fits in the three bytes allotted for it.
-  ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
-  uintptr_t requested =
-      static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
-  int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
-  if (((requested << tag_bits) >> tag_bits) != requested) {
-    // No room for entire requested size in the bits. Round down to
-    // maximally representable size.
-    requested = static_cast<intptr_t>(
-                    (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
-  }
-  int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
-  return Construct(RETRY_AFTER_GC, value);
+Failure* Failure::RetryAfterGC() {
+  return RetryAfterGC(NEW_SPACE);
+}
+
+
+Failure* Failure::RetryAfterGC(AllocationSpace space) {
+  ASSERT((space & ~kSpaceTagMask) == 0);
+  return Construct(RETRY_AFTER_GC, space);
 }
 
 
@@ -1485,6 +1470,15 @@
 }
 
 
+void FixedArray::set_unchecked(int index,
+                               Object* value,
+                               WriteBarrierMode mode) {
+  int offset = kHeaderSize + index * kPointerSize;
+  WRITE_FIELD(this, offset, value);
+  CONDITIONAL_WRITE_BARRIER(this, offset, mode);
+}
+
+
 void FixedArray::set_null_unchecked(int index) {
   ASSERT(index >= 0 && index < this->length());
   ASSERT(!Heap::InNewSpace(Heap::null_value()));
diff --git a/src/objects-visiting.h b/src/objects-visiting.h
index a6d6b12..ed76cb9 100644
--- a/src/objects-visiting.h
+++ b/src/objects-visiting.h
@@ -25,8 +25,8 @@
 // (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_OBJECTS_ITERATION_H_
-#define V8_OBJECTS_ITERATION_H_
+#ifndef V8_OBJECTS_VISITING_H_
+#define V8_OBJECTS_VISITING_H_
 
 // This file provides base classes and auxiliary methods for defining
 // static object visitors used during GC.
@@ -50,6 +50,7 @@
     kVisitShortcutCandidate,
     kVisitByteArray,
     kVisitFixedArray,
+    kVisitGlobalContext,
 
     // For data objects, JS objects and structs along with generic visitor which
     // can visit object of any size we provide visitors specialized by
@@ -263,6 +264,11 @@
                                          FixedArray::BodyDescriptor,
                                          int>::Visit);
 
+    table_.Register(kVisitGlobalContext,
+                    &FixedBodyVisitor<StaticVisitor,
+                                      Context::ScavengeBodyDescriptor,
+                                      int>::Visit);
+
     table_.Register(kVisitByteArray, &VisitByteArray);
 
     table_.Register(kVisitSharedFunctionInfo,
@@ -389,4 +395,4 @@
 
 } }  // namespace v8::internal
 
-#endif  // V8_OBJECTS_ITERATION_H_
+#endif  // V8_OBJECTS_VISITING_H_
diff --git a/src/objects.cc b/src/objects.cc
index 737bf57..ac20b2e 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -574,28 +574,6 @@
 }
 
 
-Failure* Failure::RetryAfterGC(int requested_bytes, AllocationSpace space) {
-  ASSERT((space & ~kSpaceTagMask) == 0);
-  // TODO(X64): Stop using Smi validation for non-smi checks, even if they
-  // happen to be identical at the moment.
-
-  int requested = requested_bytes >> kObjectAlignmentBits;
-  int value = (requested << kSpaceTagSize) | space;
-  // We can't very well allocate a heap number in this situation, and if the
-  // requested memory is so large it seems reasonable to say that this is an
-  // out of memory situation.  This fixes a crash in
-  // js1_5/Regress/regress-303213.js.
-  if (value >> kSpaceTagSize != requested ||
-      !Smi::IsValid(value) ||
-      value != ((value << kFailureTypeTagSize) >> kFailureTypeTagSize) ||
-      !Smi::IsValid(value << kFailureTypeTagSize)) {
-    Top::context()->mark_out_of_memory();
-    return Failure::OutOfMemoryException();
-  }
-  return Construct(RETRY_AFTER_GC, value);
-}
-
-
 // Should a word be prefixed by 'a' or 'an' in order to read naturally in
 // English?  Returns false for non-ASCII or words that don't start with
 // a capital letter.  The a/an rule follows pronunciation in English.
@@ -1180,7 +1158,11 @@
   if (map()->constructor()->IsJSFunction()) {
     JSFunction* constructor = JSFunction::cast(map()->constructor());
     String* name = String::cast(constructor->shared()->name());
-    return name->length() > 0 ? name : constructor->shared()->inferred_name();
+    if (name->length() > 0) return name;
+    String* inferred_name = constructor->shared()->inferred_name();
+    if (inferred_name->length() > 0) return inferred_name;
+    Object* proto = GetPrototype();
+    if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
   }
   // If the constructor is not present, return "Object".
   return Heap::Object_symbol();
@@ -3601,9 +3583,17 @@
 
 Object* FixedArray::UnionOfKeys(FixedArray* other) {
   int len0 = length();
+#ifdef DEBUG
+  if (FLAG_enable_slow_asserts) {
+    for (int i = 0; i < len0; i++) {
+      ASSERT(get(i)->IsString() || get(i)->IsNumber());
+    }
+  }
+#endif
   int len1 = other->length();
-  // Optimize if either is empty.
-  if (len0 == 0) return other;
+  // Optimize if 'other' is empty.
+  // We cannot optimize if 'this' is empty, as other may have holes
+  // or non keys.
   if (len1 == 0) return this;
 
   // Compute how many elements are not in this.
@@ -3623,14 +3613,18 @@
   FixedArray* result = FixedArray::cast(obj);
   WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
   for (int i = 0; i < len0; i++) {
-    result->set(i, get(i), mode);
+    Object* e = get(i);
+    ASSERT(e->IsString() || e->IsNumber());
+    result->set(i, e, mode);
   }
   // Fill in the extra keys.
   int index = 0;
   for (int y = 0; y < len1; y++) {
     Object* value = other->get(y);
     if (!value->IsTheHole() && !HasKey(this, value)) {
-      result->set(len0 + index, other->get(y), mode);
+      Object* e = other->get(y);
+      ASSERT(e->IsString() || e->IsNumber());
+      result->set(len0 + index, e, mode);
       index++;
     }
   }
@@ -5227,6 +5221,13 @@
 }
 
 
+String* SharedFunctionInfo::DebugName() {
+  Object* n = name();
+  if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
+  return String::cast(n);
+}
+
+
 bool SharedFunctionInfo::HasSourceCode() {
   return !script()->IsUndefined() &&
          !reinterpret_cast<Script*>(script())->source()->IsUndefined();
@@ -6454,7 +6455,7 @@
         // When we set the is_extensible flag to false we always force
         // the element into dictionary mode (and force them to stay there).
         if (!map()->is_extensible()) {
-          Handle<Object> number(Heap::NumberFromUint32(index));
+          Handle<Object> number(Factory::NewNumberFromUint(index));
           Handle<String> index_string(Factory::NumberToString(number));
           Handle<Object> args[1] = { index_string };
           return Top::Throw(*Factory::NewTypeError("object_not_extensible",
@@ -8568,7 +8569,9 @@
   details = PropertyDetails(details.attributes(),
                             details.type(),
                             DetailsAt(entry).index());
-  SetEntry(entry, NumberDictionaryShape::AsObject(key), value, details);
+  Object* object_key = NumberDictionaryShape::AsObject(key);
+  if (object_key->IsFailure()) return object_key;
+  SetEntry(entry, object_key, value, details);
   return this;
 }
 
@@ -8719,6 +8722,11 @@
   int inobject_props = obj->map()->inobject_properties();
   int number_of_allocated_fields =
       number_of_fields + unused_property_fields - inobject_props;
+  if (number_of_allocated_fields < 0) {
+    // There is enough inobject space for all fields (including unused).
+    number_of_allocated_fields = 0;
+    unused_property_fields = inobject_props - number_of_fields;
+  }
 
   // Allocate the fixed array for the fields.
   Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields);
diff --git a/src/objects.h b/src/objects.h
index 7f301b5..d917a57 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -794,7 +794,7 @@
 //
 // Failures are a single word, encoded as follows:
 // +-------------------------+---+--+--+
-// |...rrrrrrrrrrrrrrrrrrrrrr|sss|tt|11|
+// |.........unused..........|sss|tt|11|
 // +-------------------------+---+--+--+
 //                          7 6 4 32 10
 //
@@ -810,11 +810,6 @@
 // allocation space tag is 000 for all failure types except
 // RETRY_AFTER_GC.  For RETRY_AFTER_GC, the possible values are the
 // allocation spaces (the encoding is found in globals.h).
-//
-// The remaining bits is the size of the allocation request in units
-// of the pointer size, and is zeroed except for RETRY_AFTER_GC
-// failures.  The 25 bits (on a 32 bit platform) gives a representable
-// range of 2^27 bytes (128MB).
 
 // Failure type tag info.
 const int kFailureTypeTagSize = 2;
@@ -836,15 +831,11 @@
   // Returns the space that needs to be collected for RetryAfterGC failures.
   inline AllocationSpace allocation_space() const;
 
-  // Returns the number of bytes requested (up to the representable maximum)
-  // for RetryAfterGC failures.
-  inline int requested() const;
-
   inline bool IsInternalError() const;
   inline bool IsOutOfMemoryException() const;
 
-  static Failure* RetryAfterGC(int requested_bytes, AllocationSpace space);
-  static inline Failure* RetryAfterGC(int requested_bytes);  // NEW_SPACE
+  static inline Failure* RetryAfterGC(AllocationSpace space);
+  static inline Failure* RetryAfterGC();  // NEW_SPACE
   static inline Failure* Exception();
   static inline Failure* InternalError();
   static inline Failure* OutOfMemoryException();
@@ -1760,6 +1751,7 @@
   // Setters with less debug checks for the GC to use.
   inline void set_unchecked(int index, Smi* value);
   inline void set_null_unchecked(int index);
+  inline void set_unchecked(int index, Object* value, WriteBarrierMode mode);
 
   // Gives access to raw memory which stores the array's data.
   inline Object** data_start();
@@ -3537,7 +3529,7 @@
   //  Important: inobject slack tracking is not attempted during the snapshot
   //  creation.
 
-  static const int kGenerousAllocationCount = 16;
+  static const int kGenerousAllocationCount = 8;
 
   // [construction_count]: Counter for constructor calls made during
   // the tracking phase.
@@ -3621,6 +3613,9 @@
   // properties.
   DECL_ACCESSORS(inferred_name, String)
 
+  // The function's name if it is non-empty, otherwise the inferred name.
+  String* DebugName();
+
   // Position of the 'function' token in the script source.
   inline int function_token_position();
   inline void set_function_token_position(int function_token_position);
diff --git a/src/parser.cc b/src/parser.cc
index a3f469a..7690e92 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -47,14 +47,6 @@
 namespace v8 {
 namespace internal {
 
-class ParserFactory;
-class ParserLog;
-class TemporaryScope;
-class Target;
-
-template <typename T> class ZoneListWrapper;
-
-
 // PositionStack is used for on-stack allocation of token positions for
 // new expressions. Please look at ParseNewExpression.
 
@@ -95,254 +87,6 @@
 };
 
 
-class Parser {
- 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() { }
-
-  // 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);
-
-  void ReportMessage(const char* message, Vector<const char*> args);
-  virtual void ReportMessageAt(Scanner::Location loc,
-                               const char* message,
-                               Vector<const char*> args) = 0;
-
-
-  // Returns NULL if parsing failed.
-  FunctionLiteral* ParseProgram(Handle<String> source,
-                                bool in_global_context);
-  FunctionLiteral* ParseLazy(Handle<String> source,
-                             Handle<String> name,
-                             int start_position,
-                             int end_position,
-                             bool is_expression);
-  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;
-
- protected:
-
-  enum Mode {
-    PARSE_LAZILY,
-    PARSE_EAGERLY
-  };
-
-  // 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_;
-
-  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_; }
-
-  // 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.
-  void* ParseSourceElements(ZoneListWrapper<Statement>* processor,
-                            int end_token, bool* ok);
-  Statement* ParseStatement(ZoneStringList* labels, bool* ok);
-  Statement* ParseFunctionDeclaration(bool* ok);
-  Statement* ParseNativeDeclaration(bool* ok);
-  Block* ParseBlock(ZoneStringList* labels, bool* ok);
-  Block* ParseVariableStatement(bool* ok);
-  Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok);
-  Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
-                                                bool* ok);
-  IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
-  Statement* ParseContinueStatement(bool* ok);
-  Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
-  Statement* ParseReturnStatement(bool* ok);
-  Block* WithHelper(Expression* obj,
-                    ZoneStringList* labels,
-                    bool is_catch_block,
-                    bool* ok);
-  Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
-  CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
-  SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
-  DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
-  WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
-  Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
-  Statement* ParseThrowStatement(bool* ok);
-  Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
-  TryStatement* ParseTryStatement(bool* ok);
-  DebuggerStatement* 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* ParseNewPrefix(PositionStack* stack, bool* ok);
-  Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
-                                                   bool* ok);
-  Expression* ParsePrimaryExpression(bool* ok);
-  Expression* ParseArrayLiteral(bool* ok);
-  Expression* ParseObjectLiteral(bool* ok);
-  ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
-  Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
-
-  Expression* NewCompareNode(Token::Value op,
-                             Expression* x,
-                             Expression* y,
-                             int position);
-
-  // Populate the constant properties fixed array for a materialized object
-  // literal.
-  void BuildObjectLiteralConstantProperties(
-      ZoneList<ObjectLiteral::Property*>* properties,
-      Handle<FixedArray> constants,
-      bool* is_simple,
-      bool* fast_elements,
-      int* depth);
-
-  // Populate the literals fixed array for a materialized array literal.
-  void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
-                                            Handle<FixedArray> constants,
-                                            bool* is_simple,
-                                            int* depth);
-
-  // Decide if a property should be in the object boilerplate.
-  bool IsBoilerplateProperty(ObjectLiteral::Property* property);
-  // If the expression is a literal, return the literal value;
-  // if the expression is a materialized literal and is simple return a
-  // compile time value as encoded by CompileTimeValue::GetValue().
-  // Otherwise, return undefined literal as the placeholder
-  // in the object literal boilerplate.
-  Handle<Object> GetBoilerplateValue(Expression* expression);
-
-  enum FunctionLiteralType {
-    EXPRESSION,
-    DECLARATION,
-    NESTED
-  };
-
-  ZoneList<Expression*>* ParseArguments(bool* ok);
-  FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
-                                        int function_token_position,
-                                        FunctionLiteralType type,
-                                        bool* ok);
-
-
-  // Magical syntax support.
-  Expression* ParseV8Intrinsic(bool* ok);
-
-  INLINE(Token::Value peek()) { return scanner_.peek(); }
-  INLINE(Token::Value Next()) { return scanner_.Next(); }
-  INLINE(void Consume(Token::Value token));
-  void Expect(Token::Value token, bool* ok);
-  bool Check(Token::Value token);
-  void ExpectSemicolon(bool* ok);
-
-  Handle<String> GetSymbol(bool* ok);
-
-  // Get odd-ball literals.
-  Literal* GetLiteralUndefined();
-  Literal* GetLiteralTheHole();
-  Literal* GetLiteralNumber(double value);
-
-  Handle<String> ParseIdentifier(bool* ok);
-  Handle<String> ParseIdentifierName(bool* ok);
-  Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
-                                           bool* is_set,
-                                           bool* ok);
-
-  // Parser support
-  virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
-                                 FunctionLiteral* fun,
-                                 bool resolve,
-                                 bool* ok) = 0;
-
-  bool TargetStackContainsLabel(Handle<String> label);
-  BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
-  IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
-
-  void RegisterTargetUse(BreakTarget* target, Target* stop);
-
-  // Create a number literal.
-  Literal* NewNumberLiteral(double value);
-
-  // Generate AST node that throw a ReferenceError with the given type.
-  Expression* NewThrowReferenceError(Handle<String> type);
-
-  // Generate AST node that throw a SyntaxError with the given
-  // type. The first argument may be null (in the handle sense) in
-  // which case no arguments are passed to the constructor.
-  Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
-
-  // Generate AST node that throw a TypeError with the given
-  // type. Both arguments must be non-null (in the handle sense).
-  Expression* NewThrowTypeError(Handle<String> type,
-                                Handle<Object> first,
-                                Handle<Object> second);
-
-  // Generic AST generator for throwing errors from compiled code.
-  Expression* NewThrowError(Handle<String> constructor,
-                            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).
-
-  // Parse JSON input as a single JSON value.
-  Expression* ParseJson(bool* ok);
-
-  // 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);
-
-  friend class Target;
-  friend class TargetScope;
-  friend class LexicalScope;
-  friend class TemporaryScope;
-};
-
-
 template <typename T, int initial_size>
 class BufferedZoneList {
  public:
@@ -877,12 +621,30 @@
   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)
@@ -970,15 +732,31 @@
     return data;
   }
 
+  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
@@ -991,6 +769,7 @@
   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));
@@ -1061,13 +840,6 @@
 };
 
 
-void ScriptDataImpl::SkipFunctionEntry(int start) {
-  ASSERT(function_index_ + FunctionEntry::kSize <= store_.length());
-  ASSERT(static_cast<int>(store_[function_index_]) == start);
-  function_index_ += FunctionEntry::kSize;
-}
-
-
 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
   // The current pre-data entry must be a FunctionEntry with the given
   // start position.
@@ -1126,7 +898,10 @@
 
 
 
-PartialParserRecorder::PartialParserRecorder() : function_store_(0) {
+PartialParserRecorder::PartialParserRecorder()
+    : function_store_(0),
+      is_recording_(true),
+      pause_count_(0) {
   preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber;
   preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion;
   preamble_[ScriptDataImpl::kHasErrorOffset] = false;
@@ -1202,6 +977,7 @@
   for (int i = 0; i < args.length(); i++) {
     WriteString(CStrVector(args[i]));
   }
+  is_recording_ = false;
 }
 
 
@@ -1248,7 +1024,7 @@
   ASSERT(start > prev_start);
   prev_start = start;
 #endif
-  if (has_error()) return FunctionEntry();
+  if (!is_recording_) return FunctionEntry();
   FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0));
   result.set_start_pos(start);
   return result;
@@ -1343,6 +1119,8 @@
                                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;
 }
 
@@ -1415,6 +1193,7 @@
   }
 
   ~LexicalScope() {
+    parser_->top_scope_->Leave();
     parser_->top_scope_ = prev_scope_;
     parser_->with_nesting_level_ = prev_level_;
   }
@@ -1480,7 +1259,8 @@
   NoHandleAllocation no_handle_allocation;
   scanner_.Initialize(source, stream, JAVASCRIPT);
   ASSERT(target_stack_ == NULL);
-  mode_ = PARSE_EAGERLY;
+  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);
@@ -1551,21 +1331,20 @@
 }
 
 
-FunctionLiteral* Parser::ParseLazy(Handle<String> source,
-                                   Handle<String> name,
-                                   int start_position,
-                                   int end_position,
-                                   bool is_expression) {
+FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) {
   CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
   HistogramTimerScope timer(&Counters::parse_lazy);
+  Handle<String> source(String::cast(script_->source()));
   Counters::total_parse_size.Increment(source->length());
 
+  Handle<String> name(String::cast(info->name()));
   fni_ = new FuncNameInferrer();
   fni_->PushEnclosingName(name);
 
   // Initialize parser state.
   source->TryFlatten();
-  scanner_.Initialize(source, start_position, end_position, JAVASCRIPT);
+  scanner_.Initialize(source, info->start_position(), info->end_position(),
+                      JAVASCRIPT);
   ASSERT(target_stack_ == NULL);
   mode_ = PARSE_EAGERLY;
 
@@ -1580,7 +1359,8 @@
     LexicalScope lexical_scope(this, scope);
     TemporaryScope temp_scope(this);
 
-    FunctionLiteralType type = is_expression ? EXPRESSION : DECLARATION;
+    FunctionLiteralType type =
+        info->is_expression() ? EXPRESSION : DECLARATION;
     bool ok = true;
     result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok);
     // Make sure the results agree.
@@ -1601,6 +1381,7 @@
   return result;
 }
 
+
 FunctionLiteral* Parser::ParseJson(Handle<String> source) {
   CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
 
@@ -1658,7 +1439,10 @@
 
 
 Handle<String> Parser::GetSymbol(bool* ok) {
-  log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
+  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();
@@ -1971,7 +1755,7 @@
   }
 
   // Propagate the collected information on this property assignments.
-  if (top_scope_->is_function_scope()) {
+  if (!is_pre_parsing_ && 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;
@@ -4123,8 +3907,8 @@
 
   int num_parameters = 0;
   // Parse function body.
-  { Scope::Type type = Scope::FUNCTION_SCOPE;
-    Scope* scope = factory()->NewScope(top_scope_, type, inside_with());
+  { Scope* scope =
+        factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
     LexicalScope lexical_scope(this, scope);
     TemporaryScope temp_scope(this);
     top_scope_->SetScopeName(name);
@@ -4155,7 +3939,9 @@
     // 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 (!function_name.is_null() && function_name->length() > 0) {
+    if (!is_pre_parsing_
+        && !function_name.is_null()
+        && function_name->length() > 0) {
       Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
       VariableProxy* fproxy =
           top_scope_->NewUnresolved(function_name, inside_with());
@@ -4189,22 +3975,18 @@
       }
       Counters::total_preparse_skipped.Increment(end_pos - function_block_pos);
       scanner_.SeekForward(end_pos);
-      pre_data()->Skip(entry.predata_function_skip(),
-                       entry.predata_symbol_skip());
       materialized_literal_count = entry.literal_count();
       expected_property_count = entry.property_count();
       only_simple_this_property_assignments = false;
       this_property_assignments = Factory::empty_fixed_array();
       Expect(Token::RBRACE, CHECK_OK);
     } else {
-      if (pre_data() != NULL) {
-        // Skip pre-data entry for non-lazily compiled function.
-        pre_data()->SkipFunctionEntry(function_block_pos);
+      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);
       }
-      FunctionEntry entry = log()->LogFunction(function_block_pos);
-      int predata_function_position_before = log()->function_position();
-      int predata_symbol_position_before = log()->symbol_position();
-      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 =
@@ -4214,13 +3996,11 @@
       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);
-        entry.set_predata_function_skip(
-            log()->function_position() - predata_function_position_before);
-        entry.set_predata_symbol_skip(
-            log()->symbol_position() - predata_symbol_position_before);
       }
     }
 
@@ -5440,12 +5220,6 @@
 // ----------------------------------------------------------------------------
 // The Parser interface.
 
-// MakeAST() is just a wrapper for the corresponding Parser calls
-// so we don't have to expose the entire Parser class in the .h file.
-
-static bool always_allow_natives_syntax = false;
-
-
 ParserMessage::~ParserMessage() {
   for (int i = 0; i < args().length(); i++)
     DeleteArray(args()[i]);
@@ -5475,14 +5249,12 @@
 
 // Preparse, but only collect data that is immediately useful,
 // even if the preparser data is only used once.
-ScriptDataImpl* PartialPreParse(Handle<String> source,
-                                unibrow::CharacterStream* stream,
-                                v8::Extension* extension) {
+ScriptDataImpl* Parser::PartialPreParse(Handle<String> source,
+                                        unibrow::CharacterStream* stream,
+                                        v8::Extension* extension) {
   Handle<Script> no_script;
   bool allow_natives_syntax =
-      always_allow_natives_syntax ||
-      FLAG_allow_natives_syntax ||
-      Bootstrapper::IsActive();
+      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
@@ -5535,14 +5307,12 @@
 }
 
 
-ScriptDataImpl* PreParse(Handle<String> source,
-                         unibrow::CharacterStream* stream,
-                         v8::Extension* extension) {
+ScriptDataImpl* Parser::PreParse(Handle<String> source,
+                                 unibrow::CharacterStream* stream,
+                                 v8::Extension* extension) {
   Handle<Script> no_script;
   bool allow_natives_syntax =
-      always_allow_natives_syntax ||
-      FLAG_allow_natives_syntax ||
-      Bootstrapper::IsActive();
+      FLAG_allow_natives_syntax || Bootstrapper::IsActive();
   CompletePreParser parser(no_script, allow_natives_syntax, extension);
   if (!parser.PreParseProgram(source, stream)) return NULL;
   // Extract the accumulated data from the recorder as a single
@@ -5552,9 +5322,9 @@
 }
 
 
-bool ParseRegExp(FlatStringReader* input,
-                 bool multiline,
-                 RegExpCompileData* result) {
+bool Parser::ParseRegExp(FlatStringReader* input,
+                         bool multiline,
+                         RegExpCompileData* result) {
   ASSERT(result != NULL);
   RegExpParser parser(input, &result->error, multiline);
   RegExpTree* tree = parser.ParsePattern();
@@ -5574,59 +5344,44 @@
 }
 
 
-FunctionLiteral* MakeAST(bool compile_in_global_context,
-                         Handle<Script> script,
-                         v8::Extension* extension,
-                         ScriptDataImpl* pre_data,
-                         bool is_json) {
-  bool allow_natives_syntax =
-      always_allow_natives_syntax ||
-      FLAG_allow_natives_syntax ||
-      Bootstrapper::IsActive();
-  AstBuildingParser parser(script, allow_natives_syntax, extension, pre_data);
-  if (pre_data != NULL && pre_data->has_error()) {
-    Scanner::Location loc = pre_data->MessageLocation();
-    const char* message = pre_data->BuildMessage();
-    Vector<const char*> args = pre_data->BuildArgs();
-    parser.ReportMessageAt(loc, message, args);
-    DeleteArray(message);
-    for (int i = 0; i < args.length(); i++) {
-      DeleteArray(args[i]);
-    }
-    DeleteArray(args.start());
-    return NULL;
-  }
-  Handle<String> source = Handle<String>(String::cast(script->source()));
-  FunctionLiteral* result;
-  if (is_json) {
-    ASSERT(compile_in_global_context);
-    result = parser.ParseJson(source);
+bool Parser::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);
+    result = parser.ParseLazy(info->shared_info());
   } else {
-    result = parser.ParseProgram(source, compile_in_global_context);
+    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);
+    if (pre_data != NULL && pre_data->has_error()) {
+      Scanner::Location loc = pre_data->MessageLocation();
+      const char* message = pre_data->BuildMessage();
+      Vector<const char*> args = pre_data->BuildArgs();
+      parser.ReportMessageAt(loc, message, args);
+      DeleteArray(message);
+      for (int i = 0; i < args.length(); i++) {
+        DeleteArray(args[i]);
+      }
+      DeleteArray(args.start());
+      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());
+    }
   }
-  return result;
+
+  info->SetFunction(result);
+  return (result != NULL);
 }
 
-
-FunctionLiteral* MakeLazyAST(Handle<Script> script,
-                             Handle<String> name,
-                             int start_position,
-                             int end_position,
-                             bool is_expression) {
-  bool allow_natives_syntax_before = always_allow_natives_syntax;
-  always_allow_natives_syntax = true;
-  AstBuildingParser parser(script, true, NULL, NULL);  // always allow
-  always_allow_natives_syntax = allow_natives_syntax_before;
-  // Parse the function by pointing to the function source in the script source.
-  Handle<String> script_source(String::cast(script->source()));
-  FunctionLiteral* result =
-      parser.ParseLazy(script_source, name,
-                       start_position, end_position, is_expression);
-  return result;
-}
-
-
 #undef NEW
 
-
 } }  // namespace v8::internal
diff --git a/src/parser.h b/src/parser.h
index 8c00857..7142551 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -28,12 +28,23 @@
 #ifndef V8_PARSER_H_
 #define V8_PARSER_H_
 
-#include "scanner.h"
 #include "allocation.h"
+#include "ast.h"
+#include "scanner.h"
 
 namespace v8 {
 namespace internal {
 
+class CompilationInfo;
+class FuncNameInferrer;
+class ParserFactory;
+class ParserLog;
+class PositionStack;
+class Target;
+class TemporaryScope;
+
+template <typename T> class ZoneListWrapper;
+
 
 class ParserMessage : public Malloced {
  public:
@@ -72,19 +83,9 @@
     backing_[kPropertyCountOffset] = value;
   }
 
-  int predata_function_skip() { return backing_[kPredataFunctionSkipOffset]; }
-  void set_predata_function_skip(int value) {
-    backing_[kPredataFunctionSkipOffset] = value;
-  }
-
-  int predata_symbol_skip() { return backing_[kPredataSymbolSkipOffset]; }
-  void set_predata_symbol_skip(int value) {
-    backing_[kPredataSymbolSkipOffset] = value;
-  }
-
   bool is_valid() { return backing_.length() > 0; }
 
-  static const int kSize = 6;
+  static const int kSize = 4;
 
  private:
   Vector<unsigned> backing_;
@@ -92,8 +93,6 @@
   static const int kEndPosOffset = 1;
   static const int kLiteralCountOffset = 2;
   static const int kPropertyCountOffset = 3;
-  static const int kPredataFunctionSkipOffset = 4;
-  static const int kPredataSymbolSkipOffset = 5;
 };
 
 
@@ -117,7 +116,6 @@
 
   FunctionEntry GetFunctionEntry(int start);
   int GetSymbolIdentifier();
-  void SkipFunctionEntry(int start);
   bool SanityCheck();
 
   Scanner::Location MessageLocation();
@@ -133,28 +131,8 @@
   unsigned magic() { return store_[kMagicOffset]; }
   unsigned version() { return store_[kVersionOffset]; }
 
-  // Skip forward in the preparser data by the given number
-  // of unsigned ints of function entries and the given number of bytes of
-  // symbol id encoding.
-  void Skip(int function_entries, int symbol_entries) {
-    ASSERT(function_entries >= 0);
-    ASSERT(function_entries
-           <= (static_cast<int>(store_[kFunctionsSizeOffset])
-               - (function_index_ - kHeaderSize)));
-    ASSERT(symbol_entries >= 0);
-    ASSERT(symbol_entries <= symbol_data_end_ - symbol_data_);
-
-    unsigned max_function_skip = store_[kFunctionsSizeOffset] -
-        static_cast<unsigned>(function_index_ - kHeaderSize);
-    function_index_ +=
-        Min(static_cast<unsigned>(function_entries), max_function_skip);
-    symbol_data_ +=
-        Min(static_cast<unsigned>(symbol_entries),
-            static_cast<unsigned>(symbol_data_end_ - symbol_data_));
-  }
-
   static const unsigned kMagicNumber = 0xBadDead;
-  static const unsigned kCurrentVersion = 3;
+  static const unsigned kCurrentVersion = 4;
 
   static const int kMagicOffset = 0;
   static const int kVersionOffset = 1;
@@ -186,9 +164,10 @@
 
   ScriptDataImpl(const char* backing_store, int length)
       : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
-               length / sizeof(unsigned)),
+               length / static_cast<int>(sizeof(unsigned))),
         owns_store_(false) {
-    ASSERT_EQ(0, reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned));
+    ASSERT_EQ(0, static_cast<int>(
+        reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
   }
 
   // Read strings written by ParserRecorder::WriteString.
@@ -198,46 +177,268 @@
 };
 
 
-// The parser: Takes a script and and context information, and builds a
-// FunctionLiteral AST node. Returns NULL and deallocates any allocated
-// AST nodes if parsing failed.
-FunctionLiteral* MakeAST(bool compile_in_global_context,
-                         Handle<Script> script,
-                         v8::Extension* extension,
-                         ScriptDataImpl* pre_data,
-                         bool is_json = false);
+class Parser {
+ 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() { }
 
-// Generic preparser generating full preparse data.
-ScriptDataImpl* PreParse(Handle<String> source,
-                         unibrow::CharacterStream* stream,
-                         v8::Extension* extension);
+  // 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.
+  static bool Parse(CompilationInfo* info);
 
-// Preparser that only does preprocessing that makes sense if only used
-// immediately after.
-ScriptDataImpl* PartialPreParse(Handle<String> source,
-                                unibrow::CharacterStream* stream,
-                                v8::Extension* extension);
+  // Generic preparser generating full preparse data.
+  static ScriptDataImpl* PreParse(Handle<String> source,
+                                  unibrow::CharacterStream* stream,
+                                  v8::Extension* extension);
+
+  // Preparser that only does preprocessing that makes sense if only used
+  // immediately after.
+  static ScriptDataImpl* PartialPreParse(Handle<String> source,
+                                         unibrow::CharacterStream* stream,
+                                         v8::Extension* extension);
+
+  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);
+
+  void ReportMessage(const char* message, Vector<const char*> args);
+  virtual void ReportMessageAt(Scanner::Location loc,
+                               const char* message,
+                               Vector<const char*> args) = 0;
 
 
-bool ParseRegExp(FlatStringReader* input,
-                 bool multiline,
-                 RegExpCompileData* result);
+  // 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;
+
+ protected:
+
+  enum Mode {
+    PARSE_LAZILY,
+    PARSE_EAGERLY
+  };
+
+  // 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_;
+
+  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_; }
+
+  // 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.
+  void* ParseSourceElements(ZoneListWrapper<Statement>* processor,
+                            int end_token, bool* ok);
+  Statement* ParseStatement(ZoneStringList* labels, bool* ok);
+  Statement* ParseFunctionDeclaration(bool* ok);
+  Statement* ParseNativeDeclaration(bool* ok);
+  Block* ParseBlock(ZoneStringList* labels, bool* ok);
+  Block* ParseVariableStatement(bool* ok);
+  Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok);
+  Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
+                                                bool* ok);
+  IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
+  Statement* ParseContinueStatement(bool* ok);
+  Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
+  Statement* ParseReturnStatement(bool* ok);
+  Block* WithHelper(Expression* obj,
+                    ZoneStringList* labels,
+                    bool is_catch_block,
+                    bool* ok);
+  Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
+  CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
+  SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
+  DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
+  WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
+  Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
+  Statement* ParseThrowStatement(bool* ok);
+  Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
+  TryStatement* ParseTryStatement(bool* ok);
+  DebuggerStatement* 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* ParseNewPrefix(PositionStack* stack, bool* ok);
+  Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
+                                                   bool* ok);
+  Expression* ParsePrimaryExpression(bool* ok);
+  Expression* ParseArrayLiteral(bool* ok);
+  Expression* ParseObjectLiteral(bool* ok);
+  ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
+  Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
+
+  Expression* NewCompareNode(Token::Value op,
+                             Expression* x,
+                             Expression* y,
+                             int position);
+
+  // Populate the constant properties fixed array for a materialized object
+  // literal.
+  void BuildObjectLiteralConstantProperties(
+      ZoneList<ObjectLiteral::Property*>* properties,
+      Handle<FixedArray> constants,
+      bool* is_simple,
+      bool* fast_elements,
+      int* depth);
+
+  // Populate the literals fixed array for a materialized array literal.
+  void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
+                                            Handle<FixedArray> constants,
+                                            bool* is_simple,
+                                            int* depth);
+
+  // Decide if a property should be in the object boilerplate.
+  bool IsBoilerplateProperty(ObjectLiteral::Property* property);
+  // If the expression is a literal, return the literal value;
+  // if the expression is a materialized literal and is simple return a
+  // compile time value as encoded by CompileTimeValue::GetValue().
+  // Otherwise, return undefined literal as the placeholder
+  // in the object literal boilerplate.
+  Handle<Object> GetBoilerplateValue(Expression* expression);
+
+  enum FunctionLiteralType {
+    EXPRESSION,
+    DECLARATION,
+    NESTED
+  };
+
+  ZoneList<Expression*>* ParseArguments(bool* ok);
+  FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
+                                        int function_token_position,
+                                        FunctionLiteralType type,
+                                        bool* ok);
 
 
-// Support for doing lazy compilation. The script is the script containing full
-// source of the script where the function is declared. The start_position and
-// end_position specifies the part of the script source which has the source
-// for the function declaration in the form:
-//
-//    (<formal parameters>) { <function body> }
-//
-// without any function keyword or name.
-//
-FunctionLiteral* MakeLazyAST(Handle<Script> script,
-                             Handle<String> name,
-                             int start_position,
-                             int end_position,
-                             bool is_expression);
+  // Magical syntax support.
+  Expression* ParseV8Intrinsic(bool* ok);
+
+  INLINE(Token::Value peek()) { return scanner_.peek(); }
+  INLINE(Token::Value Next()) { return scanner_.Next(); }
+  INLINE(void Consume(Token::Value token));
+  void Expect(Token::Value token, bool* ok);
+  bool Check(Token::Value token);
+  void ExpectSemicolon(bool* ok);
+
+  Handle<String> GetSymbol(bool* ok);
+
+  // Get odd-ball literals.
+  Literal* GetLiteralUndefined();
+  Literal* GetLiteralTheHole();
+  Literal* GetLiteralNumber(double value);
+
+  Handle<String> ParseIdentifier(bool* ok);
+  Handle<String> ParseIdentifierName(bool* ok);
+  Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
+                                           bool* is_set,
+                                           bool* ok);
+
+  // Parser support
+  virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
+                                 FunctionLiteral* fun,
+                                 bool resolve,
+                                 bool* ok) = 0;
+
+  bool TargetStackContainsLabel(Handle<String> label);
+  BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
+  IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
+
+  void RegisterTargetUse(BreakTarget* target, Target* stop);
+
+  // Create a number literal.
+  Literal* NewNumberLiteral(double value);
+
+  // Generate AST node that throw a ReferenceError with the given type.
+  Expression* NewThrowReferenceError(Handle<String> type);
+
+  // Generate AST node that throw a SyntaxError with the given
+  // type. The first argument may be null (in the handle sense) in
+  // which case no arguments are passed to the constructor.
+  Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
+
+  // Generate AST node that throw a TypeError with the given
+  // type. Both arguments must be non-null (in the handle sense).
+  Expression* NewThrowTypeError(Handle<String> type,
+                                Handle<Object> first,
+                                Handle<Object> second);
+
+  // Generic AST generator for throwing errors from compiled code.
+  Expression* NewThrowError(Handle<String> constructor,
+                            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).
+
+  // Parse JSON input as a single JSON value.
+  Expression* ParseJson(bool* ok);
+
+  // 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);
+
+  friend class Target;
+  friend class TargetScope;
+  friend class LexicalScope;
+  friend class TemporaryScope;
+};
 
 
 // Support for handling complex values (array and object literals) that
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index ae44944..1003de1 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -291,6 +291,10 @@
 }
 
 
+void OS::SignalCodeMovingGC() {
+}
+
+
 int OS::StackWalk(Vector<OS::StackFrame> frames) {
   int frames_size = frames.length();
   ScopedVector<void*> addresses(frames_size);
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index f7d8609..c01c0d2 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -397,6 +397,30 @@
 }
 
 
+static const char kGCFakeMmap[] = "/tmp/__v8_gc__";
+
+
+void OS::SignalCodeMovingGC() {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+  // Support for ll_prof.py.
+  //
+  // The Linux profiler built into the kernel logs all mmap's with
+  // PROT_EXEC so that analysis tools can properly attribute ticks. We
+  // do a mmap with a name known by ll_prof.py and immediately munmap
+  // it. This injects a GC marker into the stream of events generated
+  // by the kernel and allows us to synchronize V8 code log and the
+  // kernel log.
+  int size = sysconf(_SC_PAGESIZE);
+  FILE* f = fopen(kGCFakeMmap, "w+");
+  void* addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_PRIVATE,
+                    fileno(f), 0);
+  ASSERT(addr != MAP_FAILED);
+  munmap(addr, size);
+  fclose(f);
+#endif
+}
+
+
 int OS::StackWalk(Vector<OS::StackFrame> frames) {
   // backtrace is a glibc extension.
 #ifdef __GLIBC__
@@ -748,6 +772,7 @@
   USE(info);
   if (signal != SIGPROF) return;
   if (active_sampler_ == NULL) return;
+  if (!IsVmThread()) return;
 
   TickSample sample_obj;
   TickSample* sample = CpuProfiler::TickSampleEvent();
@@ -755,6 +780,7 @@
 
   // We always sample the VM state.
   sample->state = VMState::current_state();
+
   // If profiling, we extract the current pc and sp.
   if (active_sampler_->IsProfiling()) {
     // Extracting the sample from the context is extremely machine dependent.
@@ -783,9 +809,7 @@
     // Implement this on MIPS.
     UNIMPLEMENTED();
 #endif
-    if (IsVmThread()) {
-      active_sampler_->SampleStack(sample);
-    }
+    active_sampler_->SampleStack(sample);
   }
 
   active_sampler_->Tick(sample);
@@ -806,7 +830,10 @@
 
 
 Sampler::Sampler(int interval, bool profiling)
-    : interval_(interval), profiling_(profiling), active_(false) {
+    : interval_(interval),
+      profiling_(profiling),
+      synchronous_(profiling),
+      active_(false) {
   data_ = new PlatformData();
 }
 
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 47193de..3e4daf3 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -245,6 +245,10 @@
 }
 
 
+void OS::SignalCodeMovingGC() {
+}
+
+
 uint64_t OS::CpuFeaturesImpliedByPlatform() {
   // MacOSX requires all these to install so we can assume they are present.
   // These constants are defined by the CPUid instructions.
@@ -549,17 +553,24 @@
 
   // Sampler thread handler.
   void Runner() {
-    // Loop until the sampler is disengaged, keeping the specified samling freq.
+    // Loop until the sampler is disengaged, keeping the specified
+    // sampling frequency.
     for ( ; sampler_->IsActive(); OS::Sleep(sampler_->interval_)) {
       TickSample sample_obj;
       TickSample* sample = CpuProfiler::TickSampleEvent();
       if (sample == NULL) sample = &sample_obj;
 
+      // If the sampler runs in sync with the JS thread, we try to
+      // suspend it. If we fail, we skip the current sample.
+      if (sampler_->IsSynchronous()) {
+        if (KERN_SUCCESS != thread_suspend(profiled_thread_)) continue;
+      }
+
       // We always sample the VM state.
       sample->state = VMState::current_state();
+
       // If profiling, we record the pc and sp of the profiled thread.
-      if (sampler_->IsProfiling()
-          && KERN_SUCCESS == thread_suspend(profiled_thread_)) {
+      if (sampler_->IsProfiling()) {
 #if V8_HOST_ARCH_X64
         thread_state_flavor_t flavor = x86_THREAD_STATE64;
         x86_thread_state64_t state;
@@ -591,11 +602,14 @@
           sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
           sampler_->SampleStack(sample);
         }
-        thread_resume(profiled_thread_);
       }
 
       // Invoke tick handler with program counter and stack pointer.
       sampler_->Tick(sample);
+
+      // If the sampler runs in sync with the JS thread, we have to
+      // remember to resume it.
+      if (sampler_->IsSynchronous()) thread_resume(profiled_thread_);
     }
   }
 };
@@ -613,7 +627,10 @@
 
 
 Sampler::Sampler(int interval, bool profiling)
-    : interval_(interval), profiling_(profiling), active_(false) {
+    : interval_(interval),
+      profiling_(profiling),
+      synchronous_(profiling),
+      active_(false) {
   data_ = new PlatformData(this);
 }
 
@@ -624,9 +641,9 @@
 
 
 void Sampler::Start() {
-  // If we are profiling, we need to be able to access the calling
-  // thread.
-  if (IsProfiling()) {
+  // If we are starting a synchronous sampler, we need to be able to
+  // access the calling thread.
+  if (IsSynchronous()) {
     data_->profiled_thread_ = mach_thread_self();
   }
 
@@ -655,7 +672,7 @@
   pthread_join(data_->sampler_thread_, NULL);
 
   // Deallocate Mach port for thread.
-  if (IsProfiling()) {
+  if (IsSynchronous()) {
     mach_port_deallocate(data_->task_self_, data_->profiled_thread_);
   }
 }
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index b8392e8..b5caa5e 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -240,6 +240,11 @@
 }
 
 
+void OS::SignalCodeMovingGC() {
+  UNIMPLEMENTED();
+}
+
+
 int OS::StackWalk(Vector<OS::StackFrame> frames) {
   UNIMPLEMENTED();
   return 0;
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index 05ed9ee..e03059a 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -289,6 +289,10 @@
 }
 
 
+void OS::SignalCodeMovingGC() {
+}
+
+
 int OS::StackWalk(Vector<OS::StackFrame> frames) {
   UNIMPLEMENTED();
   return 1;
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index 6d97ed7..fcd69de 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -256,6 +256,10 @@
 }
 
 
+void OS::SignalCodeMovingGC() {
+}
+
+
 struct StackWalker {
   Vector<OS::StackFrame>& frames;
   int index;
@@ -598,7 +602,10 @@
 
 
 Sampler::Sampler(int interval, bool profiling)
-    : interval_(interval), profiling_(profiling), active_(false) {
+    : interval_(interval),
+      profiling_(profiling),
+      synchronous_(profiling),
+      active_(false) {
   data_ = new PlatformData();
 }
 
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 86314a8..caea16c 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -845,14 +845,15 @@
                    bool is_executable) {
   // The address range used to randomize RWX allocations in OS::Allocate
   // Try not to map pages into the default range that windows loads DLLs
+  // Use a multiple of 64k to prevent committing unused memory.
   // Note: This does not guarantee RWX regions will be within the
   // range kAllocationRandomAddressMin to kAllocationRandomAddressMax
 #ifdef V8_HOST_ARCH_64_BIT
   static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
-  static const intptr_t kAllocationRandomAddressMax = 0x000004FFFFFFFFFF;
+  static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
 #else
   static const intptr_t kAllocationRandomAddressMin = 0x04000000;
-  static const intptr_t kAllocationRandomAddressMax = 0x4FFFFFFF;
+  static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
 #endif
 
   // VirtualAlloc rounds allocated size to page size automatically.
@@ -1217,6 +1218,10 @@
 }
 
 
+void OS::SignalCodeMovingGC() {
+}
+
+
 // Walk the stack using the facilities in dbghelp.dll and tlhelp32.dll
 
 // Switch off warning 4748 (/GS can not protect parameters and local variables
@@ -1838,17 +1843,25 @@
     // Context used for sampling the register state of the profiled thread.
     CONTEXT context;
     memset(&context, 0, sizeof(context));
-    // Loop until the sampler is disengaged, keeping the specified samling freq.
+    // Loop until the sampler is disengaged, keeping the specified
+    // sampling frequency.
     for ( ; sampler_->IsActive(); Sleep(sampler_->interval_)) {
       TickSample sample_obj;
       TickSample* sample = CpuProfiler::TickSampleEvent();
       if (sample == NULL) sample = &sample_obj;
 
+      // If the sampler runs in sync with the JS thread, we try to
+      // suspend it. If we fail, we skip the current sample.
+      if (sampler_->IsSynchronous()) {
+        static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
+        if (SuspendThread(profiled_thread_) == kSuspendFailed) continue;
+      }
+
       // We always sample the VM state.
       sample->state = VMState::current_state();
+
       // If profiling, we record the pc and sp of the profiled thread.
-      if (sampler_->IsProfiling()
-          && SuspendThread(profiled_thread_) != (DWORD)-1) {
+      if (sampler_->IsProfiling()) {
         context.ContextFlags = CONTEXT_FULL;
         if (GetThreadContext(profiled_thread_, &context) != 0) {
 #if V8_HOST_ARCH_X64
@@ -1862,11 +1875,14 @@
 #endif
           sampler_->SampleStack(sample);
         }
-        ResumeThread(profiled_thread_);
       }
 
       // Invoke tick handler with program counter and stack pointer.
       sampler_->Tick(sample);
+
+      // If the sampler runs in sync with the JS thread, we have to
+      // remember to resume it.
+      if (sampler_->IsSynchronous()) ResumeThread(profiled_thread_);
     }
   }
 };
@@ -1883,7 +1899,10 @@
 
 // Initialize a profile sampler.
 Sampler::Sampler(int interval, bool profiling)
-    : interval_(interval), profiling_(profiling), active_(false) {
+    : interval_(interval),
+      profiling_(profiling),
+      synchronous_(profiling),
+      active_(false) {
   data_ = new PlatformData(this);
 }
 
@@ -1895,9 +1914,9 @@
 
 // Start profiling.
 void Sampler::Start() {
-  // If we are profiling, we need to be able to access the calling
-  // thread.
-  if (IsProfiling()) {
+  // If we are starting a synchronous sampler, we need to be able to
+  // access the calling thread.
+  if (IsSynchronous()) {
     // Get a handle to the calling thread. This is the thread that we are
     // going to profile. We need to make a copy of the handle because we are
     // going to use it in the sampler thread. Using GetThreadHandle() will
diff --git a/src/platform.h b/src/platform.h
index e9e7c22..42e6eae 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -257,11 +257,16 @@
   static char* StrChr(char* str, int c);
   static void StrNCpy(Vector<char> dest, const char* src, size_t n);
 
-  // Support for profiler.  Can do nothing, in which case ticks
-  // occuring in shared libraries will not be properly accounted
-  // for.
+  // Support for the profiler.  Can do nothing, in which case ticks
+  // occuring in shared libraries will not be properly accounted for.
   static void LogSharedLibraryAddresses();
 
+  // Support for the profiler.  Notifies the external profiling
+  // process that a code moving garbage collection starts.  Can do
+  // nothing, in which case the code objects must not move (e.g., by
+  // using --never-compact) if accurate profiling is desired.
+  static void SignalCodeMovingGC();
+
   // The return value indicates the CPU features we are sure of because of the
   // OS.  For example MacOSX doesn't run on any x86 CPUs that don't have SSE2
   // instructions.
@@ -563,17 +568,24 @@
   void Start();
   void Stop();
 
-  // Is the sampler used for profiling.
-  inline bool IsProfiling() { return profiling_; }
+  // Is the sampler used for profiling?
+  bool IsProfiling() const { return profiling_; }
+
+  // Is the sampler running in sync with the JS thread? On platforms
+  // where the sampler is implemented with a thread that wakes up
+  // every now and then, having a synchronous sampler implies
+  // suspending/resuming the JS thread.
+  bool IsSynchronous() const { return synchronous_; }
 
   // Whether the sampler is running (that is, consumes resources).
-  inline bool IsActive() { return active_; }
+  bool IsActive() const { return active_; }
 
   class PlatformData;
 
  private:
   const int interval_;
   const bool profiling_;
+  const bool synchronous_;
   bool active_;
   PlatformData* data_;  // Platform specific data.
   DISALLOW_IMPLICIT_CONSTRUCTORS(Sampler);
diff --git a/src/powers-ten.h b/src/powers-ten.h
deleted file mode 100644
index 93d92d9..0000000
--- a/src/powers-ten.h
+++ /dev/null
@@ -1,2461 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// ------------ GENERATED FILE ----------------
-// command used:
-//  tools/generate-ten-powers --from -308 --to 342 --mantissa-size 64 --round round -o src/powers-ten.h  // NOLINT
-
-// This file is intended to be included inside another .h or .cc files
-// with the following defines set:
-//  GRISU_CACHE_STRUCT: should expand to the name of a struct that will
-//   hold the cached powers of ten. Each entry will hold a 64-bit
-//   significand, a 16-bit signed binary exponent, and a 16-bit
-//   signed decimal exponent. Each entry will be constructed as follows:
-//      { significand, binary_exponent, decimal_exponent }.
-//  GRISU_CACHE_NAME(i): generates the name for the different caches.
-//   The parameter i will be a number in the range 1-20. A cache will
-//   hold every i'th element of a full cache. GRISU_CACHE_NAME(1) will
-//   thus hold all elements. The higher i the fewer elements it has.
-//   Ideally the user should only reference one cache and let the
-//   compiler remove the unused ones.
-//  GRISU_CACHE_MAX_DISTANCE(i): generates the name for the maximum
-//   binary exponent distance between all elements of a given cache.
-//  GRISU_CACHE_OFFSET: is used as variable name for the decimal
-//   exponent offset. It is equal to -cache[0].decimal_exponent.
-//  GRISU_UINT64_C: used to construct 64-bit values in a platform
-//   independent way. In order to encode 0x123456789ABCDEF0 the macro
-//   will be invoked as follows: GRISU_UINT64_C(0x12345678,9ABCDEF0).
-
-
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(1)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0x8fd0c162, 06306bac), -1083, -307},
-  {GRISU_UINT64_C(0xb3c4f1ba, 87bc8697), -1080, -306},
-  {GRISU_UINT64_C(0xe0b62e29, 29aba83c), -1077, -305},
-  {GRISU_UINT64_C(0x8c71dcd9, ba0b4926), -1073, -304},
-  {GRISU_UINT64_C(0xaf8e5410, 288e1b6f), -1070, -303},
-  {GRISU_UINT64_C(0xdb71e914, 32b1a24b), -1067, -302},
-  {GRISU_UINT64_C(0x892731ac, 9faf056f), -1063, -301},
-  {GRISU_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
-  {GRISU_UINT64_C(0xd64d3d9d, b981787d), -1057, -299},
-  {GRISU_UINT64_C(0x85f04682, 93f0eb4e), -1053, -298},
-  {GRISU_UINT64_C(0xa76c5823, 38ed2622), -1050, -297},
-  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
-  {GRISU_UINT64_C(0x82cca4db, 847945ca), -1043, -295},
-  {GRISU_UINT64_C(0xa37fce12, 6597973d), -1040, -294},
-  {GRISU_UINT64_C(0xcc5fc196, fefd7d0c), -1037, -293},
-  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
-  {GRISU_UINT64_C(0x9faacf3d, f73609b1), -1030, -291},
-  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
-  {GRISU_UINT64_C(0xf97ae3d0, d2446f25), -1024, -289},
-  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
-  {GRISU_UINT64_C(0xc2e801fb, 244576d5), -1017, -287},
-  {GRISU_UINT64_C(0xf3a20279, ed56d48a), -1014, -286},
-  {GRISU_UINT64_C(0x9845418c, 345644d7), -1010, -285},
-  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
-  {GRISU_UINT64_C(0xedec366b, 11c6cb8f), -1004, -283},
-  {GRISU_UINT64_C(0x94b3a202, eb1c3f39), -1000, -282},
-  {GRISU_UINT64_C(0xb9e08a83, a5e34f08), -997, -281},
-  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
-  {GRISU_UINT64_C(0x91376c36, d99995be), -990, -279},
-  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
-  {GRISU_UINT64_C(0xe2e69915, b3fff9f9), -984, -277},
-  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
-  {GRISU_UINT64_C(0xb1442798, f49ffb4b), -977, -275},
-  {GRISU_UINT64_C(0xdd95317f, 31c7fa1d), -974, -274},
-  {GRISU_UINT64_C(0x8a7d3eef, 7f1cfc52), -970, -273},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0xd863b256, 369d4a41), -964, -271},
-  {GRISU_UINT64_C(0x873e4f75, e2224e68), -960, -270},
-  {GRISU_UINT64_C(0xa90de353, 5aaae202), -957, -269},
-  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
-  {GRISU_UINT64_C(0x8412d999, 1ed58092), -950, -267},
-  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
-  {GRISU_UINT64_C(0xce5d73ff, 402d98e4), -944, -265},
-  {GRISU_UINT64_C(0x80fa687f, 881c7f8e), -940, -264},
-  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
-  {GRISU_UINT64_C(0xc9874347, 44ac874f), -934, -262},
-  {GRISU_UINT64_C(0xfbe91419, 15d7a922), -931, -261},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0xc4ce17b3, 99107c23), -924, -259},
-  {GRISU_UINT64_C(0xf6019da0, 7f549b2b), -921, -258},
-  {GRISU_UINT64_C(0x99c10284, 4f94e0fb), -917, -257},
-  {GRISU_UINT64_C(0xc0314325, 637a193a), -914, -256},
-  {GRISU_UINT64_C(0xf03d93ee, bc589f88), -911, -255},
-  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
-  {GRISU_UINT64_C(0xbbb01b92, 83253ca3), -904, -253},
-  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
-  {GRISU_UINT64_C(0x92a1958a, 7675175f), -897, -251},
-  {GRISU_UINT64_C(0xb749faed, 14125d37), -894, -250},
-  {GRISU_UINT64_C(0xe51c79a8, 5916f485), -891, -249},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0xb2fe3f0b, 8599ef08), -884, -247},
-  {GRISU_UINT64_C(0xdfbdcece, 67006ac9), -881, -246},
-  {GRISU_UINT64_C(0x8bd6a141, 006042be), -877, -245},
-  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
-  {GRISU_UINT64_C(0xda7f5bf5, 90966849), -871, -243},
-  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
-  {GRISU_UINT64_C(0xaab37fd7, d8f58179), -864, -241},
-  {GRISU_UINT64_C(0xd5605fcd, cf32e1d7), -861, -240},
-  {GRISU_UINT64_C(0x855c3be0, a17fcd26), -857, -239},
-  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
-  {GRISU_UINT64_C(0xd0601d8e, fc57b08c), -851, -237},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xa2cb1717, b52481ed), -844, -235},
-  {GRISU_UINT64_C(0xcb7ddcdd, a26da269), -841, -234},
-  {GRISU_UINT64_C(0xfe5d5415, 0b090b03), -838, -233},
-  {GRISU_UINT64_C(0x9efa548d, 26e5a6e2), -834, -232},
-  {GRISU_UINT64_C(0xc6b8e9b0, 709f109a), -831, -231},
-  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
-  {GRISU_UINT64_C(0x9b407691, d7fc44f8), -824, -229},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0xf294b943, e17a2bc4), -818, -227},
-  {GRISU_UINT64_C(0x979cf3ca, 6cec5b5b), -814, -226},
-  {GRISU_UINT64_C(0xbd8430bd, 08277231), -811, -225},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0x940f4613, ae5ed137), -804, -223},
-  {GRISU_UINT64_C(0xb9131798, 99f68584), -801, -222},
-  {GRISU_UINT64_C(0xe757dd7e, c07426e5), -798, -221},
-  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
-  {GRISU_UINT64_C(0xb4bca50b, 065abe63), -791, -219},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0x8d3360f0, 9cf6e4bd), -784, -217},
-  {GRISU_UINT64_C(0xb080392c, c4349ded), -781, -216},
-  {GRISU_UINT64_C(0xdca04777, f541c568), -778, -215},
-  {GRISU_UINT64_C(0x89e42caa, f9491b61), -774, -214},
-  {GRISU_UINT64_C(0xac5d37d5, b79b6239), -771, -213},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0x86a8d39e, f77164bd), -764, -211},
-  {GRISU_UINT64_C(0xa8530886, b54dbdec), -761, -210},
-  {GRISU_UINT64_C(0xd267caa8, 62a12d67), -758, -209},
-  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
-  {GRISU_UINT64_C(0xa4611653, 8d0deb78), -751, -207},
-  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
-  {GRISU_UINT64_C(0x806bd971, 4632dff6), -744, -205},
-  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
-  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
-  {GRISU_UINT64_C(0xfad2a4b1, 3d1b5d6c), -735, -202},
-  {GRISU_UINT64_C(0x9cc3a6ee, c6311a64), -731, -201},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0xf4f1b4d5, 15acb93c), -725, -199},
-  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
-  {GRISU_UINT64_C(0xbf5cd546, 78eef0b7), -718, -197},
-  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
-  {GRISU_UINT64_C(0x9580869f, 0e7aac0f), -711, -195},
-  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
-  {GRISU_UINT64_C(0xe998d258, 869facd7), -705, -193},
-  {GRISU_UINT64_C(0x91ff8377, 5423cc06), -701, -192},
-  {GRISU_UINT64_C(0xb67f6455, 292cbf08), -698, -191},
-  {GRISU_UINT64_C(0xe41f3d6a, 7377eeca), -695, -190},
-  {GRISU_UINT64_C(0x8e938662, 882af53e), -691, -189},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0xdec681f9, f4c31f31), -685, -187},
-  {GRISU_UINT64_C(0x8b3c113c, 38f9f37f), -681, -186},
-  {GRISU_UINT64_C(0xae0b158b, 4738705f), -678, -185},
-  {GRISU_UINT64_C(0xd98ddaee, 19068c76), -675, -184},
-  {GRISU_UINT64_C(0x87f8a8d4, cfa417ca), -671, -183},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0xd47487cc, 8470652b), -665, -181},
-  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
-  {GRISU_UINT64_C(0xa5fb0a17, c777cf0a), -658, -179},
-  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
-  {GRISU_UINT64_C(0x81ac1fe2, 93d599c0), -651, -177},
-  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
-  {GRISU_UINT64_C(0xca9cf1d2, 06fdc03c), -645, -175},
-  {GRISU_UINT64_C(0xfd442e46, 88bd304b), -642, -174},
-  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
-  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
-  {GRISU_UINT64_C(0xf7549530, e188c129), -632, -171},
-  {GRISU_UINT64_C(0x9a94dd3e, 8cf578ba), -628, -170},
-  {GRISU_UINT64_C(0xc13a148e, 3032d6e8), -625, -169},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0x96f5600f, 15a7b7e5), -618, -167},
-  {GRISU_UINT64_C(0xbcb2b812, db11a5de), -615, -166},
-  {GRISU_UINT64_C(0xebdf6617, 91d60f56), -612, -165},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0xb84687c2, 69ef3bfb), -605, -163},
-  {GRISU_UINT64_C(0xe65829b3, 046b0afa), -602, -162},
-  {GRISU_UINT64_C(0x8ff71a0f, e2c2e6dc), -598, -161},
-  {GRISU_UINT64_C(0xb3f4e093, db73a093), -595, -160},
-  {GRISU_UINT64_C(0xe0f218b8, d25088b8), -592, -159},
-  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
-  {GRISU_UINT64_C(0xafbd2350, 644eead0), -585, -157},
-  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
-  {GRISU_UINT64_C(0x894bc396, ce5da772), -578, -155},
-  {GRISU_UINT64_C(0xab9eb47c, 81f5114f), -575, -154},
-  {GRISU_UINT64_C(0xd686619b, a27255a3), -572, -153},
-  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
-  {GRISU_UINT64_C(0xa798fc41, 96e952e7), -565, -151},
-  {GRISU_UINT64_C(0xd17f3b51, fca3a7a1), -562, -150},
-  {GRISU_UINT64_C(0x82ef8513, 3de648c5), -558, -149},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xcc963fee, 10b7d1b3), -552, -147},
-  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
-  {GRISU_UINT64_C(0x9fd561f1, fd0f9bd4), -545, -145},
-  {GRISU_UINT64_C(0xc7caba6e, 7c5382c9), -542, -144},
-  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
-  {GRISU_UINT64_C(0x9c1661a6, 51213e2d), -535, -142},
-  {GRISU_UINT64_C(0xc31bfa0f, e5698db8), -532, -141},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0x986ddb5c, 6b3a76b8), -525, -139},
-  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
-  {GRISU_UINT64_C(0xee2ba6c0, 678b597f), -519, -137},
-  {GRISU_UINT64_C(0x94db4838, 40b717f0), -515, -136},
-  {GRISU_UINT64_C(0xba121a46, 50e4ddec), -512, -135},
-  {GRISU_UINT64_C(0xe896a0d7, e51e1566), -509, -134},
-  {GRISU_UINT64_C(0x915e2486, ef32cd60), -505, -133},
-  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
-  {GRISU_UINT64_C(0xe3231912, d5bf60e6), -499, -131},
-  {GRISU_UINT64_C(0x8df5efab, c5979c90), -495, -130},
-  {GRISU_UINT64_C(0xb1736b96, b6fd83b4), -492, -129},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0x8aa22c0d, bef60ee4), -485, -127},
-  {GRISU_UINT64_C(0xad4ab711, 2eb3929e), -482, -126},
-  {GRISU_UINT64_C(0xd89d64d5, 7a607745), -479, -125},
-  {GRISU_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
-  {GRISU_UINT64_C(0xa93af6c6, c79b5d2e), -472, -123},
-  {GRISU_UINT64_C(0xd389b478, 79823479), -469, -122},
-  {GRISU_UINT64_C(0x843610cb, 4bf160cc), -465, -121},
-  {GRISU_UINT64_C(0xa54394fe, 1eedb8ff), -462, -120},
-  {GRISU_UINT64_C(0xce947a3d, a6a9273e), -459, -119},
-  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
-  {GRISU_UINT64_C(0xa163ff80, 2a3426a9), -452, -117},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0xfc2c3f38, 41f17c68), -446, -115},
-  {GRISU_UINT64_C(0x9d9ba783, 2936edc1), -442, -114},
-  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
-  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
-  {GRISU_UINT64_C(0x99ea0196, 163fa42e), -432, -111},
-  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
-  {GRISU_UINT64_C(0xf07da27a, 82c37088), -426, -109},
-  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
-  {GRISU_UINT64_C(0xbbe226ef, b628afeb), -419, -107},
-  {GRISU_UINT64_C(0xeadab0ab, a3b2dbe5), -416, -106},
-  {GRISU_UINT64_C(0x92c8ae6b, 464fc96f), -412, -105},
-  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
-  {GRISU_UINT64_C(0xe5599087, 9ddcaabe), -406, -103},
-  {GRISU_UINT64_C(0x8f57fa54, c2a9eab7), -402, -102},
-  {GRISU_UINT64_C(0xb32df8e9, f3546564), -399, -101},
-  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
-  {GRISU_UINT64_C(0x8bfbea76, c619ef36), -392, -99},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0xdab99e59, 958885c5), -386, -97},
-  {GRISU_UINT64_C(0x88b402f7, fd75539b), -382, -96},
-  {GRISU_UINT64_C(0xaae103b5, fcd2a882), -379, -95},
-  {GRISU_UINT64_C(0xd59944a3, 7c0752a2), -376, -94},
-  {GRISU_UINT64_C(0x857fcae6, 2d8493a5), -372, -93},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0xd097ad07, a71f26b2), -366, -91},
-  {GRISU_UINT64_C(0x825ecc24, c8737830), -362, -90},
-  {GRISU_UINT64_C(0xa2f67f2d, fa90563b), -359, -89},
-  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
-  {GRISU_UINT64_C(0xfea126b7, d78186bd), -353, -87},
-  {GRISU_UINT64_C(0x9f24b832, e6b0f436), -349, -86},
-  {GRISU_UINT64_C(0xc6ede63f, a05d3144), -346, -85},
-  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
-  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
-  {GRISU_UINT64_C(0xc24452da, 229b021c), -336, -82},
-  {GRISU_UINT64_C(0xf2d56790, ab41c2a3), -333, -81},
-  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
-  {GRISU_UINT64_C(0xbdb6b8e9, 05cb600f), -326, -79},
-  {GRISU_UINT64_C(0xed246723, 473e3813), -323, -78},
-  {GRISU_UINT64_C(0x9436c076, 0c86e30c), -319, -77},
-  {GRISU_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
-  {GRISU_UINT64_C(0xe7958cb8, 7392c2c3), -313, -75},
-  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
-  {GRISU_UINT64_C(0xb4ecd5f0, 1a4aa828), -306, -73},
-  {GRISU_UINT64_C(0xe2280b6c, 20dd5232), -303, -72},
-  {GRISU_UINT64_C(0x8d590723, 948a535f), -299, -71},
-  {GRISU_UINT64_C(0xb0af48ec, 79ace837), -296, -70},
-  {GRISU_UINT64_C(0xdcdb1b27, 98182245), -293, -69},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xac8b2d36, eed2dac6), -286, -67},
-  {GRISU_UINT64_C(0xd7adf884, aa879177), -283, -66},
-  {GRISU_UINT64_C(0x86ccbb52, ea94baeb), -279, -65},
-  {GRISU_UINT64_C(0xa87fea27, a539e9a5), -276, -64},
-  {GRISU_UINT64_C(0xd29fe4b1, 8e88640f), -273, -63},
-  {GRISU_UINT64_C(0x83a3eeee, f9153e89), -269, -62},
-  {GRISU_UINT64_C(0xa48ceaaa, b75a8e2b), -266, -61},
-  {GRISU_UINT64_C(0xcdb02555, 653131b6), -263, -60},
-  {GRISU_UINT64_C(0x808e1755, 5f3ebf12), -259, -59},
-  {GRISU_UINT64_C(0xa0b19d2a, b70e6ed6), -256, -58},
-  {GRISU_UINT64_C(0xc8de0475, 64d20a8c), -253, -57},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0x9ced737b, b6c4183d), -246, -55},
-  {GRISU_UINT64_C(0xc428d05a, a4751e4d), -243, -54},
-  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
-  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
-  {GRISU_UINT64_C(0xbf8fdb78, 849a5f97), -233, -51},
-  {GRISU_UINT64_C(0xef73d256, a5c0f77d), -230, -50},
-  {GRISU_UINT64_C(0x95a86376, 27989aae), -226, -49},
-  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
-  {GRISU_UINT64_C(0xe9d71b68, 9dde71b0), -220, -47},
-  {GRISU_UINT64_C(0x92267121, 62ab070e), -216, -46},
-  {GRISU_UINT64_C(0xb6b00d69, bb55c8d1), -213, -45},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0x8eb98a7a, 9a5b04e3), -206, -43},
-  {GRISU_UINT64_C(0xb267ed19, 40f1c61c), -203, -42},
-  {GRISU_UINT64_C(0xdf01e85f, 912e37a3), -200, -41},
-  {GRISU_UINT64_C(0x8b61313b, babce2c6), -196, -40},
-  {GRISU_UINT64_C(0xae397d8a, a96c1b78), -193, -39},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0x881cea14, 545c7575), -186, -37},
-  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
-  {GRISU_UINT64_C(0xd4ad2dbf, c3d07788), -180, -35},
-  {GRISU_UINT64_C(0x84ec3c97, da624ab5), -176, -34},
-  {GRISU_UINT64_C(0xa6274bbd, d0fadd62), -173, -33},
-  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
-  {GRISU_UINT64_C(0x81ceb32c, 4b43fcf5), -166, -31},
-  {GRISU_UINT64_C(0xa2425ff7, 5e14fc32), -163, -30},
-  {GRISU_UINT64_C(0xcad2f7f5, 359a3b3e), -160, -29},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0x9e74d1b7, 91e07e48), -153, -27},
-  {GRISU_UINT64_C(0xc6120625, 76589ddb), -150, -26},
-  {GRISU_UINT64_C(0xf79687ae, d3eec551), -147, -25},
-  {GRISU_UINT64_C(0x9abe14cd, 44753b53), -143, -24},
-  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
-  {GRISU_UINT64_C(0xf1c90080, baf72cb1), -137, -22},
-  {GRISU_UINT64_C(0x971da050, 74da7bef), -133, -21},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xec1e4a7d, b69561a5), -127, -19},
-  {GRISU_UINT64_C(0x9392ee8e, 921d5d07), -123, -18},
-  {GRISU_UINT64_C(0xb877aa32, 36a4b449), -120, -17},
-  {GRISU_UINT64_C(0xe69594be, c44de15b), -117, -16},
-  {GRISU_UINT64_C(0x901d7cf7, 3ab0acd9), -113, -15},
-  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
-  {GRISU_UINT64_C(0xe12e1342, 4bb40e13), -107, -13},
-  {GRISU_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
-  {GRISU_UINT64_C(0xafebff0b, cb24aaff), -100, -11},
-  {GRISU_UINT64_C(0xdbe6fece, bdedd5bf), -97, -10},
-  {GRISU_UINT64_C(0x89705f41, 36b4a597), -93, -9},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0xd6bf94d5, e57a42bc), -87, -7},
-  {GRISU_UINT64_C(0x8637bd05, af6c69b6), -83, -6},
-  {GRISU_UINT64_C(0xa7c5ac47, 1b478423), -80, -5},
-  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
-  {GRISU_UINT64_C(0x83126e97, 8d4fdf3b), -73, -3},
-  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
-  {GRISU_UINT64_C(0xcccccccc, cccccccd), -67, -1},
-  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
-  {GRISU_UINT64_C(0xa0000000, 00000000), -60, 1},
-  {GRISU_UINT64_C(0xc8000000, 00000000), -57, 2},
-  {GRISU_UINT64_C(0xfa000000, 00000000), -54, 3},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0xc3500000, 00000000), -47, 5},
-  {GRISU_UINT64_C(0xf4240000, 00000000), -44, 6},
-  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
-  {GRISU_UINT64_C(0xbebc2000, 00000000), -37, 8},
-  {GRISU_UINT64_C(0xee6b2800, 00000000), -34, 9},
-  {GRISU_UINT64_C(0x9502f900, 00000000), -30, 10},
-  {GRISU_UINT64_C(0xba43b740, 00000000), -27, 11},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0x9184e72a, 00000000), -20, 13},
-  {GRISU_UINT64_C(0xb5e620f4, 80000000), -17, 14},
-  {GRISU_UINT64_C(0xe35fa931, a0000000), -14, 15},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0xb1a2bc2e, c5000000), -7, 17},
-  {GRISU_UINT64_C(0xde0b6b3a, 76400000), -4, 18},
-  {GRISU_UINT64_C(0x8ac72304, 89e80000), 0, 19},
-  {GRISU_UINT64_C(0xad78ebc5, ac620000), 3, 20},
-  {GRISU_UINT64_C(0xd8d726b7, 177a8000), 6, 21},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0xa968163f, 0a57b400), 13, 23},
-  {GRISU_UINT64_C(0xd3c21bce, cceda100), 16, 24},
-  {GRISU_UINT64_C(0x84595161, 401484a0), 20, 25},
-  {GRISU_UINT64_C(0xa56fa5b9, 9019a5c8), 23, 26},
-  {GRISU_UINT64_C(0xcecb8f27, f4200f3a), 26, 27},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0xa18f07d7, 36b90be5), 33, 29},
-  {GRISU_UINT64_C(0xc9f2c9cd, 04674edf), 36, 30},
-  {GRISU_UINT64_C(0xfc6f7c40, 45812296), 39, 31},
-  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
-  {GRISU_UINT64_C(0xc5371912, 364ce305), 46, 33},
-  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
-  {GRISU_UINT64_C(0x9a130b96, 3a6c115c), 53, 35},
-  {GRISU_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
-  {GRISU_UINT64_C(0xf0bdc21a, bb48db20), 59, 37},
-  {GRISU_UINT64_C(0x96769950, b50d88f4), 63, 38},
-  {GRISU_UINT64_C(0xbc143fa4, e250eb31), 66, 39},
-  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
-  {GRISU_UINT64_C(0x92efd1b8, d0cf37be), 73, 41},
-  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
-  {GRISU_UINT64_C(0xe596b7b0, c643c719), 79, 43},
-  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
-  {GRISU_UINT64_C(0xb35dbf82, 1ae4f38c), 86, 45},
-  {GRISU_UINT64_C(0xe0352f62, a19e306f), 89, 46},
-  {GRISU_UINT64_C(0x8c213d9d, a502de45), 93, 47},
-  {GRISU_UINT64_C(0xaf298d05, 0e4395d7), 96, 48},
-  {GRISU_UINT64_C(0xdaf3f046, 51d47b4c), 99, 49},
-  {GRISU_UINT64_C(0x88d8762b, f324cd10), 103, 50},
-  {GRISU_UINT64_C(0xab0e93b6, efee0054), 106, 51},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0x85a36366, eb71f041), 113, 53},
-  {GRISU_UINT64_C(0xa70c3c40, a64e6c52), 116, 54},
-  {GRISU_UINT64_C(0xd0cf4b50, cfe20766), 119, 55},
-  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
-  {GRISU_UINT64_C(0xa321f2d7, 226895c8), 126, 57},
-  {GRISU_UINT64_C(0xcbea6f8c, eb02bb3a), 129, 58},
-  {GRISU_UINT64_C(0xfee50b70, 25c36a08), 132, 59},
-  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
-  {GRISU_UINT64_C(0xc722f0ef, 9d80aad6), 139, 61},
-  {GRISU_UINT64_C(0xf8ebad2b, 84e0d58c), 142, 62},
-  {GRISU_UINT64_C(0x9b934c3b, 330c8577), 146, 63},
-  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
-  {GRISU_UINT64_C(0xf316271c, 7fc3908b), 152, 65},
-  {GRISU_UINT64_C(0x97edd871, cfda3a57), 156, 66},
-  {GRISU_UINT64_C(0xbde94e8e, 43d0c8ec), 159, 67},
-  {GRISU_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
-  {GRISU_UINT64_C(0x945e455f, 24fb1cf9), 166, 69},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0xe7d34c64, a9c85d44), 172, 71},
-  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
-  {GRISU_UINT64_C(0xb51d13ae, a4a488dd), 179, 73},
-  {GRISU_UINT64_C(0xe264589a, 4dcdab15), 182, 74},
-  {GRISU_UINT64_C(0x8d7eb760, 70a08aed), 186, 75},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0xdd15fe86, affad912), 192, 77},
-  {GRISU_UINT64_C(0x8a2dbf14, 2dfcc7ab), 196, 78},
-  {GRISU_UINT64_C(0xacb92ed9, 397bf996), 199, 79},
-  {GRISU_UINT64_C(0xd7e77a8f, 87daf7fc), 202, 80},
-  {GRISU_UINT64_C(0x86f0ac99, b4e8dafd), 206, 81},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0xd2d80db0, 2aabd62c), 212, 83},
-  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
-  {GRISU_UINT64_C(0xa4b8cab1, a1563f52), 219, 85},
-  {GRISU_UINT64_C(0xcde6fd5e, 09abcf27), 222, 86},
-  {GRISU_UINT64_C(0x80b05e5a, c60b6178), 226, 87},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0xc913936d, d571c84c), 232, 89},
-  {GRISU_UINT64_C(0xfb587849, 4ace3a5f), 235, 90},
-  {GRISU_UINT64_C(0x9d174b2d, cec0e47b), 239, 91},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0xf5746577, 930d6501), 245, 93},
-  {GRISU_UINT64_C(0x9968bf6a, bbe85f20), 249, 94},
-  {GRISU_UINT64_C(0xbfc2ef45, 6ae276e9), 252, 95},
-  {GRISU_UINT64_C(0xefb3ab16, c59b14a3), 255, 96},
-  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
-  {GRISU_UINT64_C(0xbb445da9, ca61281f), 262, 98},
-  {GRISU_UINT64_C(0xea157514, 3cf97227), 265, 99},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0xb6e0c377, cfa2e12e), 272, 101},
-  {GRISU_UINT64_C(0xe498f455, c38b997a), 275, 102},
-  {GRISU_UINT64_C(0x8edf98b5, 9a373fec), 279, 103},
-  {GRISU_UINT64_C(0xb2977ee3, 00c50fe7), 282, 104},
-  {GRISU_UINT64_C(0xdf3d5e9b, c0f653e1), 285, 105},
-  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
-  {GRISU_UINT64_C(0xae67f1e9, aec07188), 292, 107},
-  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
-  {GRISU_UINT64_C(0x884134fe, 908658b2), 299, 109},
-  {GRISU_UINT64_C(0xaa51823e, 34a7eedf), 302, 110},
-  {GRISU_UINT64_C(0xd4e5e2cd, c1d1ea96), 305, 111},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xa6539930, bf6bff46), 312, 113},
-  {GRISU_UINT64_C(0xcfe87f7c, ef46ff17), 315, 114},
-  {GRISU_UINT64_C(0x81f14fae, 158c5f6e), 319, 115},
-  {GRISU_UINT64_C(0xa26da399, 9aef774a), 322, 116},
-  {GRISU_UINT64_C(0xcb090c80, 01ab551c), 325, 117},
-  {GRISU_UINT64_C(0xfdcb4fa0, 02162a63), 328, 118},
-  {GRISU_UINT64_C(0x9e9f11c4, 014dda7e), 332, 119},
-  {GRISU_UINT64_C(0xc646d635, 01a1511e), 335, 120},
-  {GRISU_UINT64_C(0xf7d88bc2, 4209a565), 338, 121},
-  {GRISU_UINT64_C(0x9ae75759, 6946075f), 342, 122},
-  {GRISU_UINT64_C(0xc1a12d2f, c3978937), 345, 123},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0x9745eb4d, 50ce6333), 352, 125},
-  {GRISU_UINT64_C(0xbd176620, a501fc00), 355, 126},
-  {GRISU_UINT64_C(0xec5d3fa8, ce427b00), 358, 127},
-  {GRISU_UINT64_C(0x93ba47c9, 80e98ce0), 362, 128},
-  {GRISU_UINT64_C(0xb8a8d9bb, e123f018), 365, 129},
-  {GRISU_UINT64_C(0xe6d3102a, d96cec1e), 368, 130},
-  {GRISU_UINT64_C(0x9043ea1a, c7e41393), 372, 131},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0xe16a1dc9, d8545e95), 378, 133},
-  {GRISU_UINT64_C(0x8ce2529e, 2734bb1d), 382, 134},
-  {GRISU_UINT64_C(0xb01ae745, b101e9e4), 385, 135},
-  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
-  {GRISU_UINT64_C(0x899504ae, 72497eba), 392, 137},
-  {GRISU_UINT64_C(0xabfa45da, 0edbde69), 395, 138},
-  {GRISU_UINT64_C(0xd6f8d750, 9292d603), 398, 139},
-  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
-  {GRISU_UINT64_C(0xa7f26836, f282b733), 405, 141},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0x8335616a, ed761f1f), 412, 143},
-  {GRISU_UINT64_C(0xa402b9c5, a8d3a6e7), 415, 144},
-  {GRISU_UINT64_C(0xcd036837, 130890a1), 418, 145},
-  {GRISU_UINT64_C(0x80222122, 6be55a65), 422, 146},
-  {GRISU_UINT64_C(0xa02aa96b, 06deb0fe), 425, 147},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0xfa42a8b7, 3abbf48d), 431, 149},
-  {GRISU_UINT64_C(0x9c69a972, 84b578d8), 435, 150},
-  {GRISU_UINT64_C(0xc38413cf, 25e2d70e), 438, 151},
-  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
-  {GRISU_UINT64_C(0x98bf2f79, d5993803), 445, 153},
-  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
-  {GRISU_UINT64_C(0xeeaaba2e, 5dbf6785), 451, 155},
-  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
-  {GRISU_UINT64_C(0xba756174, 393d88e0), 458, 157},
-  {GRISU_UINT64_C(0xe912b9d1, 478ceb17), 461, 158},
-  {GRISU_UINT64_C(0x91abb422, ccb812ef), 465, 159},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0xe39c4976, 5fdf9d95), 471, 161},
-  {GRISU_UINT64_C(0x8e41ade9, fbebc27d), 475, 162},
-  {GRISU_UINT64_C(0xb1d21964, 7ae6b31c), 478, 163},
-  {GRISU_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
-  {GRISU_UINT64_C(0x8aec23d6, 80043bee), 485, 165},
-  {GRISU_UINT64_C(0xada72ccc, 20054aea), 488, 166},
-  {GRISU_UINT64_C(0xd910f7ff, 28069da4), 491, 167},
-  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
-  {GRISU_UINT64_C(0xa99541bf, 57452b28), 498, 169},
-  {GRISU_UINT64_C(0xd3fa922f, 2d1675f2), 501, 170},
-  {GRISU_UINT64_C(0x847c9b5d, 7c2e09b7), 505, 171},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xcf02b2c2, 1207ef2f), 511, 173},
-  {GRISU_UINT64_C(0x8161afb9, 4b44f57d), 515, 174},
-  {GRISU_UINT64_C(0xa1ba1ba7, 9e1632dc), 518, 175},
-  {GRISU_UINT64_C(0xca28a291, 859bbf93), 521, 176},
-  {GRISU_UINT64_C(0xfcb2cb35, e702af78), 524, 177},
-  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
-  {GRISU_UINT64_C(0xc56baec2, 1c7a1916), 531, 179},
-  {GRISU_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
-  {GRISU_UINT64_C(0x9a3c2087, a63f6399), 538, 181},
-  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
-  {GRISU_UINT64_C(0xf0fdf2d3, f3c30b9f), 544, 183},
-  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
-  {GRISU_UINT64_C(0xbc4665b5, 96706115), 551, 185},
-  {GRISU_UINT64_C(0xeb57ff22, fc0c795a), 554, 186},
-  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
-  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
-  {GRISU_UINT64_C(0xe5d3ef28, 2a242e82), 564, 189},
-  {GRISU_UINT64_C(0x8fa47579, 1a569d11), 568, 190},
-  {GRISU_UINT64_C(0xb38d92d7, 60ec4455), 571, 191},
-  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
-  {GRISU_UINT64_C(0x8c469ab8, 43b89563), 578, 193},
-  {GRISU_UINT64_C(0xaf584166, 54a6babb), 581, 194},
-  {GRISU_UINT64_C(0xdb2e51bf, e9d0696a), 584, 195},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xab3c2fdd, eeaad25b), 591, 197},
-  {GRISU_UINT64_C(0xd60b3bd5, 6a5586f2), 594, 198},
-  {GRISU_UINT64_C(0x85c70565, 62757457), 598, 199},
-  {GRISU_UINT64_C(0xa738c6be, bb12d16d), 601, 200},
-  {GRISU_UINT64_C(0xd106f86e, 69d785c8), 604, 201},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0xa34d7216, 42b06084), 611, 203},
-  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
-  {GRISU_UINT64_C(0xff290242, c83396ce), 617, 205},
-  {GRISU_UINT64_C(0x9f79a169, bd203e41), 621, 206},
-  {GRISU_UINT64_C(0xc75809c4, 2c684dd1), 624, 207},
-  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
-  {GRISU_UINT64_C(0x9bbcc7a1, 42b17ccc), 631, 209},
-  {GRISU_UINT64_C(0xc2abf989, 935ddbfe), 634, 210},
-  {GRISU_UINT64_C(0xf356f7eb, f83552fe), 637, 211},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xbe1bf1b0, 59e9a8d6), 644, 213},
-  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
-  {GRISU_UINT64_C(0x9485d4d1, c63e8be8), 651, 215},
-  {GRISU_UINT64_C(0xb9a74a06, 37ce2ee1), 654, 216},
-  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
-  {GRISU_UINT64_C(0x910ab1d4, db9914a0), 661, 218},
-  {GRISU_UINT64_C(0xb54d5e4a, 127f59c8), 664, 219},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0x8da471a9, de737e24), 671, 221},
-  {GRISU_UINT64_C(0xb10d8e14, 56105dad), 674, 222},
-  {GRISU_UINT64_C(0xdd50f199, 6b947519), 677, 223},
-  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
-  {GRISU_UINT64_C(0xace73cbf, dc0bfb7b), 684, 225},
-  {GRISU_UINT64_C(0xd8210bef, d30efa5a), 687, 226},
-  {GRISU_UINT64_C(0x8714a775, e3e95c78), 691, 227},
-  {GRISU_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
-  {GRISU_UINT64_C(0xd31045a8, 341ca07c), 697, 229},
-  {GRISU_UINT64_C(0x83ea2b89, 2091e44e), 701, 230},
-  {GRISU_UINT64_C(0xa4e4b66b, 68b65d61), 704, 231},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0x80d2ae83, e9ce78f4), 711, 233},
-  {GRISU_UINT64_C(0xa1075a24, e4421731), 714, 234},
-  {GRISU_UINT64_C(0xc94930ae, 1d529cfd), 717, 235},
-  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
-  {GRISU_UINT64_C(0x9d412e08, 06e88aa6), 724, 237},
-  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
-  {GRISU_UINT64_C(0xf5b5d7ec, 8acb58a3), 730, 239},
-  {GRISU_UINT64_C(0x9991a6f3, d6bf1766), 734, 240},
-  {GRISU_UINT64_C(0xbff610b0, cc6edd3f), 737, 241},
-  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
-  {GRISU_UINT64_C(0x95f83d0a, 1fb69cd9), 744, 243},
-  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
-  {GRISU_UINT64_C(0xea53df5f, d18d5514), 750, 245},
-  {GRISU_UINT64_C(0x92746b9b, e2f8552c), 754, 246},
-  {GRISU_UINT64_C(0xb7118682, dbb66a77), 757, 247},
-  {GRISU_UINT64_C(0xe4d5e823, 92a40515), 760, 248},
-  {GRISU_UINT64_C(0x8f05b116, 3ba6832d), 764, 249},
-  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
-  {GRISU_UINT64_C(0xdf78e4b2, bd342cf7), 770, 251},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xae9672ab, a3d0c321), 777, 253},
-  {GRISU_UINT64_C(0xda3c0f56, 8cc4f3e9), 780, 254},
-  {GRISU_UINT64_C(0x88658996, 17fb1871), 784, 255},
-  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
-  {GRISU_UINT64_C(0xd51ea6fa, 85785631), 790, 257},
-  {GRISU_UINT64_C(0x8533285c, 936b35df), 794, 258},
-  {GRISU_UINT64_C(0xa67ff273, b8460357), 797, 259},
-  {GRISU_UINT64_C(0xd01fef10, a657842c), 800, 260},
-  {GRISU_UINT64_C(0x8213f56a, 67f6b29c), 804, 261},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0xcb3f2f76, 42717713), 810, 263},
-  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
-  {GRISU_UINT64_C(0x9ec95d14, 63e8a507), 817, 265},
-  {GRISU_UINT64_C(0xc67bb459, 7ce2ce49), 820, 266},
-  {GRISU_UINT64_C(0xf81aa16f, dc1b81db), 823, 267},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0xc1d4ce1f, 63f57d73), 830, 269},
-  {GRISU_UINT64_C(0xf24a01a7, 3cf2dcd0), 833, 270},
-  {GRISU_UINT64_C(0x976e4108, 8617ca02), 837, 271},
-  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
-  {GRISU_UINT64_C(0xec9c459d, 51852ba3), 843, 273},
-  {GRISU_UINT64_C(0x93e1ab82, 52f33b46), 847, 274},
-  {GRISU_UINT64_C(0xb8da1662, e7b00a17), 850, 275},
-  {GRISU_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
-  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
-  {GRISU_UINT64_C(0xb484f9dc, 9641e9db), 860, 278},
-  {GRISU_UINT64_C(0xe1a63853, bbd26451), 863, 279},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0xb049dc01, 6abc5e60), 870, 281},
-  {GRISU_UINT64_C(0xdc5c5301, c56b75f7), 873, 282},
-  {GRISU_UINT64_C(0x89b9b3e1, 1b6329bb), 877, 283},
-  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
-  {GRISU_UINT64_C(0xd732290f, bacaf134), 883, 285},
-  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
-  {GRISU_UINT64_C(0xa81f3014, 49ee8c70), 890, 287},
-  {GRISU_UINT64_C(0xd226fc19, 5c6a2f8c), 893, 288},
-  {GRISU_UINT64_C(0x83585d8f, d9c25db8), 897, 289},
-  {GRISU_UINT64_C(0xa42e74f3, d032f526), 900, 290},
-  {GRISU_UINT64_C(0xcd3a1230, c43fb26f), 903, 291},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xa0555e36, 1951c367), 910, 293},
-  {GRISU_UINT64_C(0xc86ab5c3, 9fa63441), 913, 294},
-  {GRISU_UINT64_C(0xfa856334, 878fc151), 916, 295},
-  {GRISU_UINT64_C(0x9c935e00, d4b9d8d2), 920, 296},
-  {GRISU_UINT64_C(0xc3b83581, 09e84f07), 923, 297},
-  {GRISU_UINT64_C(0xf4a642e1, 4c6262c9), 926, 298},
-  {GRISU_UINT64_C(0x98e7e9cc, cfbd7dbe), 930, 299},
-  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
-  {GRISU_UINT64_C(0xeeea5d50, 04981478), 936, 301},
-  {GRISU_UINT64_C(0x95527a52, 02df0ccb), 940, 302},
-  {GRISU_UINT64_C(0xbaa718e6, 8396cffe), 943, 303},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0x91d28b74, 16cdd27e), 950, 305},
-  {GRISU_UINT64_C(0xb6472e51, 1c81471e), 953, 306},
-  {GRISU_UINT64_C(0xe3d8f9e5, 63a198e5), 956, 307},
-  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
-  {GRISU_UINT64_C(0xb201833b, 35d63f73), 963, 309},
-  {GRISU_UINT64_C(0xde81e40a, 034bcf50), 966, 310},
-  {GRISU_UINT64_C(0x8b112e86, 420f6192), 970, 311},
-  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
-  {GRISU_UINT64_C(0xd94ad8b1, c7380874), 976, 313},
-  {GRISU_UINT64_C(0x87cec76f, 1c830549), 980, 314},
-  {GRISU_UINT64_C(0xa9c2794a, e3a3c69b), 983, 315},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0x849feec2, 81d7f329), 990, 317},
-  {GRISU_UINT64_C(0xa5c7ea73, 224deff3), 993, 318},
-  {GRISU_UINT64_C(0xcf39e50f, eae16bf0), 996, 319},
-  {GRISU_UINT64_C(0x81842f29, f2cce376), 1000, 320},
-  {GRISU_UINT64_C(0xa1e53af4, 6f801c53), 1003, 321},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xfcf62c1d, ee382c42), 1009, 323},
-  {GRISU_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
-  {GRISU_UINT64_C(0xc5a05277, 621be294), 1016, 325},
-  {GRISU_UINT64_C(0xf7086715, 3aa2db39), 1019, 326},
-  {GRISU_UINT64_C(0x9a65406d, 44a5c903), 1023, 327},
-  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
-  {GRISU_UINT64_C(0xf13e34aa, bb430a15), 1029, 329},
-  {GRISU_UINT64_C(0x96c6e0ea, b509e64d), 1033, 330},
-  {GRISU_UINT64_C(0xbc789925, 624c5fe1), 1036, 331},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  {GRISU_UINT64_C(0x933e37a5, 34cbaae8), 1043, 333},
-  {GRISU_UINT64_C(0xb80dc58e, 81fe95a1), 1046, 334},
-  {GRISU_UINT64_C(0xe61136f2, 227e3b0a), 1049, 335},
-  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
-  {GRISU_UINT64_C(0xb3bd72ed, 2af29e20), 1056, 337},
-  {GRISU_UINT64_C(0xe0accfa8, 75af45a8), 1059, 338},
-  {GRISU_UINT64_C(0x8c6c01c9, 498d8b89), 1063, 339},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  {GRISU_UINT64_C(0xdb68c2ca, 82ed2a06), 1069, 341},
-  {GRISU_UINT64_C(0x892179be, 91d43a44), 1073, 342},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(1) = 4;
-// nb elements (1): 651
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(2)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xb3c4f1ba, 87bc8697), -1080, -306},
-  {GRISU_UINT64_C(0x8c71dcd9, ba0b4926), -1073, -304},
-  {GRISU_UINT64_C(0xdb71e914, 32b1a24b), -1067, -302},
-  {GRISU_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
-  {GRISU_UINT64_C(0x85f04682, 93f0eb4e), -1053, -298},
-  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
-  {GRISU_UINT64_C(0xa37fce12, 6597973d), -1040, -294},
-  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
-  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
-  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
-  {GRISU_UINT64_C(0xf3a20279, ed56d48a), -1014, -286},
-  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
-  {GRISU_UINT64_C(0x94b3a202, eb1c3f39), -1000, -282},
-  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
-  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
-  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
-  {GRISU_UINT64_C(0xdd95317f, 31c7fa1d), -974, -274},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0x873e4f75, e2224e68), -960, -270},
-  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
-  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
-  {GRISU_UINT64_C(0x80fa687f, 881c7f8e), -940, -264},
-  {GRISU_UINT64_C(0xc9874347, 44ac874f), -934, -262},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0xf6019da0, 7f549b2b), -921, -258},
-  {GRISU_UINT64_C(0xc0314325, 637a193a), -914, -256},
-  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
-  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
-  {GRISU_UINT64_C(0xb749faed, 14125d37), -894, -250},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0xdfbdcece, 67006ac9), -881, -246},
-  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
-  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
-  {GRISU_UINT64_C(0xd5605fcd, cf32e1d7), -861, -240},
-  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xcb7ddcdd, a26da269), -841, -234},
-  {GRISU_UINT64_C(0x9efa548d, 26e5a6e2), -834, -232},
-  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0x979cf3ca, 6cec5b5b), -814, -226},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0xb9131798, 99f68584), -801, -222},
-  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0xb080392c, c4349ded), -781, -216},
-  {GRISU_UINT64_C(0x89e42caa, f9491b61), -774, -214},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0xa8530886, b54dbdec), -761, -210},
-  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
-  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
-  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
-  {GRISU_UINT64_C(0xfad2a4b1, 3d1b5d6c), -735, -202},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
-  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
-  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
-  {GRISU_UINT64_C(0x91ff8377, 5423cc06), -701, -192},
-  {GRISU_UINT64_C(0xe41f3d6a, 7377eeca), -695, -190},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0x8b3c113c, 38f9f37f), -681, -186},
-  {GRISU_UINT64_C(0xd98ddaee, 19068c76), -675, -184},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
-  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
-  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
-  {GRISU_UINT64_C(0xfd442e46, 88bd304b), -642, -174},
-  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
-  {GRISU_UINT64_C(0x9a94dd3e, 8cf578ba), -628, -170},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0xbcb2b812, db11a5de), -615, -166},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0xe65829b3, 046b0afa), -602, -162},
-  {GRISU_UINT64_C(0xb3f4e093, db73a093), -595, -160},
-  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
-  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
-  {GRISU_UINT64_C(0xab9eb47c, 81f5114f), -575, -154},
-  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
-  {GRISU_UINT64_C(0xd17f3b51, fca3a7a1), -562, -150},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
-  {GRISU_UINT64_C(0xc7caba6e, 7c5382c9), -542, -144},
-  {GRISU_UINT64_C(0x9c1661a6, 51213e2d), -535, -142},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
-  {GRISU_UINT64_C(0x94db4838, 40b717f0), -515, -136},
-  {GRISU_UINT64_C(0xe896a0d7, e51e1566), -509, -134},
-  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
-  {GRISU_UINT64_C(0x8df5efab, c5979c90), -495, -130},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xad4ab711, 2eb3929e), -482, -126},
-  {GRISU_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
-  {GRISU_UINT64_C(0xd389b478, 79823479), -469, -122},
-  {GRISU_UINT64_C(0xa54394fe, 1eedb8ff), -462, -120},
-  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0x9d9ba783, 2936edc1), -442, -114},
-  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
-  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
-  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
-  {GRISU_UINT64_C(0xeadab0ab, a3b2dbe5), -416, -106},
-  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
-  {GRISU_UINT64_C(0x8f57fa54, c2a9eab7), -402, -102},
-  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0x88b402f7, fd75539b), -382, -96},
-  {GRISU_UINT64_C(0xd59944a3, 7c0752a2), -376, -94},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0x825ecc24, c8737830), -362, -90},
-  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
-  {GRISU_UINT64_C(0x9f24b832, e6b0f436), -349, -86},
-  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
-  {GRISU_UINT64_C(0xc24452da, 229b021c), -336, -82},
-  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
-  {GRISU_UINT64_C(0xed246723, 473e3813), -323, -78},
-  {GRISU_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
-  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
-  {GRISU_UINT64_C(0xe2280b6c, 20dd5232), -303, -72},
-  {GRISU_UINT64_C(0xb0af48ec, 79ace837), -296, -70},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xd7adf884, aa879177), -283, -66},
-  {GRISU_UINT64_C(0xa87fea27, a539e9a5), -276, -64},
-  {GRISU_UINT64_C(0x83a3eeee, f9153e89), -269, -62},
-  {GRISU_UINT64_C(0xcdb02555, 653131b6), -263, -60},
-  {GRISU_UINT64_C(0xa0b19d2a, b70e6ed6), -256, -58},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0xc428d05a, a4751e4d), -243, -54},
-  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
-  {GRISU_UINT64_C(0xef73d256, a5c0f77d), -230, -50},
-  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
-  {GRISU_UINT64_C(0x92267121, 62ab070e), -216, -46},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0xb267ed19, 40f1c61c), -203, -42},
-  {GRISU_UINT64_C(0x8b61313b, babce2c6), -196, -40},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
-  {GRISU_UINT64_C(0x84ec3c97, da624ab5), -176, -34},
-  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
-  {GRISU_UINT64_C(0xa2425ff7, 5e14fc32), -163, -30},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0xc6120625, 76589ddb), -150, -26},
-  {GRISU_UINT64_C(0x9abe14cd, 44753b53), -143, -24},
-  {GRISU_UINT64_C(0xf1c90080, baf72cb1), -137, -22},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0x9392ee8e, 921d5d07), -123, -18},
-  {GRISU_UINT64_C(0xe69594be, c44de15b), -117, -16},
-  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
-  {GRISU_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
-  {GRISU_UINT64_C(0xdbe6fece, bdedd5bf), -97, -10},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0x8637bd05, af6c69b6), -83, -6},
-  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
-  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
-  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
-  {GRISU_UINT64_C(0xc8000000, 00000000), -57, 2},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0xf4240000, 00000000), -44, 6},
-  {GRISU_UINT64_C(0xbebc2000, 00000000), -37, 8},
-  {GRISU_UINT64_C(0x9502f900, 00000000), -30, 10},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0xb5e620f4, 80000000), -17, 14},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0xde0b6b3a, 76400000), -4, 18},
-  {GRISU_UINT64_C(0xad78ebc5, ac620000), 3, 20},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0xd3c21bce, cceda100), 16, 24},
-  {GRISU_UINT64_C(0xa56fa5b9, 9019a5c8), 23, 26},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0xc9f2c9cd, 04674edf), 36, 30},
-  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
-  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
-  {GRISU_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
-  {GRISU_UINT64_C(0x96769950, b50d88f4), 63, 38},
-  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
-  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
-  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
-  {GRISU_UINT64_C(0xe0352f62, a19e306f), 89, 46},
-  {GRISU_UINT64_C(0xaf298d05, 0e4395d7), 96, 48},
-  {GRISU_UINT64_C(0x88d8762b, f324cd10), 103, 50},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xa70c3c40, a64e6c52), 116, 54},
-  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
-  {GRISU_UINT64_C(0xcbea6f8c, eb02bb3a), 129, 58},
-  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
-  {GRISU_UINT64_C(0xf8ebad2b, 84e0d58c), 142, 62},
-  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
-  {GRISU_UINT64_C(0x97edd871, cfda3a57), 156, 66},
-  {GRISU_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
-  {GRISU_UINT64_C(0xe264589a, 4dcdab15), 182, 74},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0x8a2dbf14, 2dfcc7ab), 196, 78},
-  {GRISU_UINT64_C(0xd7e77a8f, 87daf7fc), 202, 80},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
-  {GRISU_UINT64_C(0xcde6fd5e, 09abcf27), 222, 86},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0xfb587849, 4ace3a5f), 235, 90},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0x9968bf6a, bbe85f20), 249, 94},
-  {GRISU_UINT64_C(0xefb3ab16, c59b14a3), 255, 96},
-  {GRISU_UINT64_C(0xbb445da9, ca61281f), 262, 98},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0xe498f455, c38b997a), 275, 102},
-  {GRISU_UINT64_C(0xb2977ee3, 00c50fe7), 282, 104},
-  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
-  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
-  {GRISU_UINT64_C(0xaa51823e, 34a7eedf), 302, 110},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xcfe87f7c, ef46ff17), 315, 114},
-  {GRISU_UINT64_C(0xa26da399, 9aef774a), 322, 116},
-  {GRISU_UINT64_C(0xfdcb4fa0, 02162a63), 328, 118},
-  {GRISU_UINT64_C(0xc646d635, 01a1511e), 335, 120},
-  {GRISU_UINT64_C(0x9ae75759, 6946075f), 342, 122},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0xbd176620, a501fc00), 355, 126},
-  {GRISU_UINT64_C(0x93ba47c9, 80e98ce0), 362, 128},
-  {GRISU_UINT64_C(0xe6d3102a, d96cec1e), 368, 130},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0x8ce2529e, 2734bb1d), 382, 134},
-  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
-  {GRISU_UINT64_C(0xabfa45da, 0edbde69), 395, 138},
-  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xa402b9c5, a8d3a6e7), 415, 144},
-  {GRISU_UINT64_C(0x80222122, 6be55a65), 422, 146},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0x9c69a972, 84b578d8), 435, 150},
-  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
-  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
-  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
-  {GRISU_UINT64_C(0xe912b9d1, 478ceb17), 461, 158},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0x8e41ade9, fbebc27d), 475, 162},
-  {GRISU_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
-  {GRISU_UINT64_C(0xada72ccc, 20054aea), 488, 166},
-  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
-  {GRISU_UINT64_C(0xd3fa922f, 2d1675f2), 501, 170},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0x8161afb9, 4b44f57d), 515, 174},
-  {GRISU_UINT64_C(0xca28a291, 859bbf93), 521, 176},
-  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
-  {GRISU_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
-  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
-  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
-  {GRISU_UINT64_C(0xeb57ff22, fc0c795a), 554, 186},
-  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
-  {GRISU_UINT64_C(0x8fa47579, 1a569d11), 568, 190},
-  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
-  {GRISU_UINT64_C(0xaf584166, 54a6babb), 581, 194},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xd60b3bd5, 6a5586f2), 594, 198},
-  {GRISU_UINT64_C(0xa738c6be, bb12d16d), 601, 200},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
-  {GRISU_UINT64_C(0x9f79a169, bd203e41), 621, 206},
-  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
-  {GRISU_UINT64_C(0xc2abf989, 935ddbfe), 634, 210},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
-  {GRISU_UINT64_C(0xb9a74a06, 37ce2ee1), 654, 216},
-  {GRISU_UINT64_C(0x910ab1d4, db9914a0), 661, 218},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0xb10d8e14, 56105dad), 674, 222},
-  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
-  {GRISU_UINT64_C(0xd8210bef, d30efa5a), 687, 226},
-  {GRISU_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
-  {GRISU_UINT64_C(0x83ea2b89, 2091e44e), 701, 230},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xa1075a24, e4421731), 714, 234},
-  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
-  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
-  {GRISU_UINT64_C(0x9991a6f3, d6bf1766), 734, 240},
-  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
-  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
-  {GRISU_UINT64_C(0x92746b9b, e2f8552c), 754, 246},
-  {GRISU_UINT64_C(0xe4d5e823, 92a40515), 760, 248},
-  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xda3c0f56, 8cc4f3e9), 780, 254},
-  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
-  {GRISU_UINT64_C(0x8533285c, 936b35df), 794, 258},
-  {GRISU_UINT64_C(0xd01fef10, a657842c), 800, 260},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
-  {GRISU_UINT64_C(0xc67bb459, 7ce2ce49), 820, 266},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0xf24a01a7, 3cf2dcd0), 833, 270},
-  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
-  {GRISU_UINT64_C(0x93e1ab82, 52f33b46), 847, 274},
-  {GRISU_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
-  {GRISU_UINT64_C(0xb484f9dc, 9641e9db), 860, 278},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0xdc5c5301, c56b75f7), 873, 282},
-  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
-  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
-  {GRISU_UINT64_C(0xd226fc19, 5c6a2f8c), 893, 288},
-  {GRISU_UINT64_C(0xa42e74f3, d032f526), 900, 290},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xc86ab5c3, 9fa63441), 913, 294},
-  {GRISU_UINT64_C(0x9c935e00, d4b9d8d2), 920, 296},
-  {GRISU_UINT64_C(0xf4a642e1, 4c6262c9), 926, 298},
-  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
-  {GRISU_UINT64_C(0x95527a52, 02df0ccb), 940, 302},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0xb6472e51, 1c81471e), 953, 306},
-  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
-  {GRISU_UINT64_C(0xde81e40a, 034bcf50), 966, 310},
-  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
-  {GRISU_UINT64_C(0x87cec76f, 1c830549), 980, 314},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0xa5c7ea73, 224deff3), 993, 318},
-  {GRISU_UINT64_C(0x81842f29, f2cce376), 1000, 320},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
-  {GRISU_UINT64_C(0xf7086715, 3aa2db39), 1019, 326},
-  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
-  {GRISU_UINT64_C(0x96c6e0ea, b509e64d), 1033, 330},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  {GRISU_UINT64_C(0xb80dc58e, 81fe95a1), 1046, 334},
-  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
-  {GRISU_UINT64_C(0xe0accfa8, 75af45a8), 1059, 338},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  {GRISU_UINT64_C(0x892179be, 91d43a44), 1073, 342},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(2) = 7;
-// nb elements (2): 326
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(3)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xe0b62e29, 29aba83c), -1077, -305},
-  {GRISU_UINT64_C(0xdb71e914, 32b1a24b), -1067, -302},
-  {GRISU_UINT64_C(0xd64d3d9d, b981787d), -1057, -299},
-  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
-  {GRISU_UINT64_C(0xcc5fc196, fefd7d0c), -1037, -293},
-  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
-  {GRISU_UINT64_C(0xc2e801fb, 244576d5), -1017, -287},
-  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
-  {GRISU_UINT64_C(0xb9e08a83, a5e34f08), -997, -281},
-  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
-  {GRISU_UINT64_C(0xb1442798, f49ffb4b), -977, -275},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0xa90de353, 5aaae202), -957, -269},
-  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
-  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0x99c10284, 4f94e0fb), -917, -257},
-  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
-  {GRISU_UINT64_C(0x92a1958a, 7675175f), -897, -251},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0x8bd6a141, 006042be), -877, -245},
-  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
-  {GRISU_UINT64_C(0x855c3be0, a17fcd26), -857, -239},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xfe5d5415, 0b090b03), -838, -233},
-  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
-  {GRISU_UINT64_C(0xf294b943, e17a2bc4), -818, -227},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0xe757dd7e, c07426e5), -798, -221},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0xdca04777, f541c568), -778, -215},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0xd267caa8, 62a12d67), -758, -209},
-  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
-  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0xbf5cd546, 78eef0b7), -718, -197},
-  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
-  {GRISU_UINT64_C(0xb67f6455, 292cbf08), -698, -191},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0xae0b158b, 4738705f), -678, -185},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0xa5fb0a17, c777cf0a), -658, -179},
-  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
-  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
-  {GRISU_UINT64_C(0x9a94dd3e, 8cf578ba), -628, -170},
-  {GRISU_UINT64_C(0x96f5600f, 15a7b7e5), -618, -167},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0x8ff71a0f, e2c2e6dc), -598, -161},
-  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
-  {GRISU_UINT64_C(0x894bc396, ce5da772), -578, -155},
-  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
-  {GRISU_UINT64_C(0x82ef8513, 3de648c5), -558, -149},
-  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
-  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0xee2ba6c0, 678b597f), -519, -137},
-  {GRISU_UINT64_C(0xe896a0d7, e51e1566), -509, -134},
-  {GRISU_UINT64_C(0xe3231912, d5bf60e6), -499, -131},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xd89d64d5, 7a607745), -479, -125},
-  {GRISU_UINT64_C(0xd389b478, 79823479), -469, -122},
-  {GRISU_UINT64_C(0xce947a3d, a6a9273e), -459, -119},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
-  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
-  {GRISU_UINT64_C(0xbbe226ef, b628afeb), -419, -107},
-  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
-  {GRISU_UINT64_C(0xb32df8e9, f3546564), -399, -101},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0xaae103b5, fcd2a882), -379, -95},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0xa2f67f2d, fa90563b), -359, -89},
-  {GRISU_UINT64_C(0x9f24b832, e6b0f436), -349, -86},
-  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
-  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
-  {GRISU_UINT64_C(0x9436c076, 0c86e30c), -319, -77},
-  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
-  {GRISU_UINT64_C(0x8d590723, 948a535f), -299, -71},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0x86ccbb52, ea94baeb), -279, -65},
-  {GRISU_UINT64_C(0x83a3eeee, f9153e89), -269, -62},
-  {GRISU_UINT64_C(0x808e1755, 5f3ebf12), -259, -59},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
-  {GRISU_UINT64_C(0xef73d256, a5c0f77d), -230, -50},
-  {GRISU_UINT64_C(0xe9d71b68, 9dde71b0), -220, -47},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0xdf01e85f, 912e37a3), -200, -41},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xd4ad2dbf, c3d07788), -180, -35},
-  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
-  {GRISU_UINT64_C(0xcad2f7f5, 359a3b3e), -160, -29},
-  {GRISU_UINT64_C(0xc6120625, 76589ddb), -150, -26},
-  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xb877aa32, 36a4b449), -120, -17},
-  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
-  {GRISU_UINT64_C(0xafebff0b, cb24aaff), -100, -11},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0xa7c5ac47, 1b478423), -80, -5},
-  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
-  {GRISU_UINT64_C(0xa0000000, 00000000), -60, 1},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
-  {GRISU_UINT64_C(0x9502f900, 00000000), -30, 10},
-  {GRISU_UINT64_C(0x9184e72a, 00000000), -20, 13},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0x8ac72304, 89e80000), 0, 19},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0x84595161, 401484a0), 20, 25},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0xfc6f7c40, 45812296), 39, 31},
-  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
-  {GRISU_UINT64_C(0xf0bdc21a, bb48db20), 59, 37},
-  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
-  {GRISU_UINT64_C(0xe596b7b0, c643c719), 79, 43},
-  {GRISU_UINT64_C(0xe0352f62, a19e306f), 89, 46},
-  {GRISU_UINT64_C(0xdaf3f046, 51d47b4c), 99, 49},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xd0cf4b50, cfe20766), 119, 55},
-  {GRISU_UINT64_C(0xcbea6f8c, eb02bb3a), 129, 58},
-  {GRISU_UINT64_C(0xc722f0ef, 9d80aad6), 139, 61},
-  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
-  {GRISU_UINT64_C(0xbde94e8e, 43d0c8ec), 159, 67},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0xb51d13ae, a4a488dd), 179, 73},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0xacb92ed9, 397bf996), 199, 79},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0xa4b8cab1, a1563f52), 219, 85},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0x9d174b2d, cec0e47b), 239, 91},
-  {GRISU_UINT64_C(0x9968bf6a, bbe85f20), 249, 94},
-  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0x8edf98b5, 9a373fec), 279, 103},
-  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
-  {GRISU_UINT64_C(0x884134fe, 908658b2), 299, 109},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0x81f14fae, 158c5f6e), 319, 115},
-  {GRISU_UINT64_C(0xfdcb4fa0, 02162a63), 328, 118},
-  {GRISU_UINT64_C(0xf7d88bc2, 4209a565), 338, 121},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0xec5d3fa8, ce427b00), 358, 127},
-  {GRISU_UINT64_C(0xe6d3102a, d96cec1e), 368, 130},
-  {GRISU_UINT64_C(0xe16a1dc9, d8545e95), 378, 133},
-  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
-  {GRISU_UINT64_C(0xd6f8d750, 9292d603), 398, 139},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xcd036837, 130890a1), 418, 145},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0xc38413cf, 25e2d70e), 438, 151},
-  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
-  {GRISU_UINT64_C(0xba756174, 393d88e0), 458, 157},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0xb1d21964, 7ae6b31c), 478, 163},
-  {GRISU_UINT64_C(0xada72ccc, 20054aea), 488, 166},
-  {GRISU_UINT64_C(0xa99541bf, 57452b28), 498, 169},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xa1ba1ba7, 9e1632dc), 518, 175},
-  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
-  {GRISU_UINT64_C(0x9a3c2087, a63f6399), 538, 181},
-  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
-  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
-  {GRISU_UINT64_C(0x8fa47579, 1a569d11), 568, 190},
-  {GRISU_UINT64_C(0x8c469ab8, 43b89563), 578, 193},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0x85c70565, 62757457), 598, 199},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0xff290242, c83396ce), 617, 205},
-  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
-  {GRISU_UINT64_C(0xf356f7eb, f83552fe), 637, 211},
-  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
-  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0xdd50f199, 6b947519), 677, 223},
-  {GRISU_UINT64_C(0xd8210bef, d30efa5a), 687, 226},
-  {GRISU_UINT64_C(0xd31045a8, 341ca07c), 697, 229},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xc94930ae, 1d529cfd), 717, 235},
-  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
-  {GRISU_UINT64_C(0xbff610b0, cc6edd3f), 737, 241},
-  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
-  {GRISU_UINT64_C(0xb7118682, dbb66a77), 757, 247},
-  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
-  {GRISU_UINT64_C(0xae9672ab, a3d0c321), 777, 253},
-  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
-  {GRISU_UINT64_C(0xa67ff273, b8460357), 797, 259},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0x9ec95d14, 63e8a507), 817, 265},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0x976e4108, 8617ca02), 837, 271},
-  {GRISU_UINT64_C(0x93e1ab82, 52f33b46), 847, 274},
-  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0x89b9b3e1, 1b6329bb), 877, 283},
-  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
-  {GRISU_UINT64_C(0x83585d8f, d9c25db8), 897, 289},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xfa856334, 878fc151), 916, 295},
-  {GRISU_UINT64_C(0xf4a642e1, 4c6262c9), 926, 298},
-  {GRISU_UINT64_C(0xeeea5d50, 04981478), 936, 301},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0xe3d8f9e5, 63a198e5), 956, 307},
-  {GRISU_UINT64_C(0xde81e40a, 034bcf50), 966, 310},
-  {GRISU_UINT64_C(0xd94ad8b1, c7380874), 976, 313},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0xcf39e50f, eae16bf0), 996, 319},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xc5a05277, 621be294), 1016, 325},
-  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
-  {GRISU_UINT64_C(0xbc789925, 624c5fe1), 1036, 331},
-  {GRISU_UINT64_C(0xb80dc58e, 81fe95a1), 1046, 334},
-  {GRISU_UINT64_C(0xb3bd72ed, 2af29e20), 1056, 337},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(3) = 10;
-// nb elements (3): 217
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(4)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0x8c71dcd9, ba0b4926), -1073, -304},
-  {GRISU_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
-  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
-  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
-  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
-  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
-  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
-  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
-  {GRISU_UINT64_C(0x80fa687f, 881c7f8e), -940, -264},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0xc0314325, 637a193a), -914, -256},
-  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
-  {GRISU_UINT64_C(0xd5605fcd, cf32e1d7), -861, -240},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0x9efa548d, 26e5a6e2), -834, -232},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
-  {GRISU_UINT64_C(0xb080392c, c4349ded), -781, -216},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
-  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
-  {GRISU_UINT64_C(0x91ff8377, 5423cc06), -701, -192},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0xd98ddaee, 19068c76), -675, -184},
-  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
-  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
-  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0xb3f4e093, db73a093), -595, -160},
-  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
-  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xc7caba6e, 7c5382c9), -542, -144},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0x94db4838, 40b717f0), -515, -136},
-  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
-  {GRISU_UINT64_C(0xa54394fe, 1eedb8ff), -462, -120},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
-  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
-  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
-  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
-  {GRISU_UINT64_C(0x88b402f7, fd75539b), -382, -96},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
-  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
-  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
-  {GRISU_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
-  {GRISU_UINT64_C(0xe2280b6c, 20dd5232), -303, -72},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xa87fea27, a539e9a5), -276, -64},
-  {GRISU_UINT64_C(0xcdb02555, 653131b6), -263, -60},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
-  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0x8b61313b, babce2c6), -196, -40},
-  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
-  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0x9abe14cd, 44753b53), -143, -24},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xe69594be, c44de15b), -117, -16},
-  {GRISU_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
-  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0xbebc2000, 00000000), -37, 8},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0xad78ebc5, ac620000), 3, 20},
-  {GRISU_UINT64_C(0xd3c21bce, cceda100), 16, 24},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
-  {GRISU_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
-  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
-  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
-  {GRISU_UINT64_C(0xaf298d05, 0e4395d7), 96, 48},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
-  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
-  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
-  {GRISU_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
-  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0xd7e77a8f, 87daf7fc), 202, 80},
-  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0xefb3ab16, c59b14a3), 255, 96},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0xb2977ee3, 00c50fe7), 282, 104},
-  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xa26da399, 9aef774a), 322, 116},
-  {GRISU_UINT64_C(0xc646d635, 01a1511e), 335, 120},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0x93ba47c9, 80e98ce0), 362, 128},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
-  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
-  {GRISU_UINT64_C(0xa402b9c5, a8d3a6e7), 415, 144},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
-  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
-  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xca28a291, 859bbf93), 521, 176},
-  {GRISU_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
-  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
-  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
-  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xa738c6be, bb12d16d), 601, 200},
-  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
-  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xb9a74a06, 37ce2ee1), 654, 216},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
-  {GRISU_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
-  {GRISU_UINT64_C(0x9991a6f3, d6bf1766), 734, 240},
-  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
-  {GRISU_UINT64_C(0xe4d5e823, 92a40515), 760, 248},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
-  {GRISU_UINT64_C(0xd01fef10, a657842c), 800, 260},
-  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
-  {GRISU_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
-  {GRISU_UINT64_C(0xd226fc19, 5c6a2f8c), 893, 288},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0x9c935e00, d4b9d8d2), 920, 296},
-  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
-  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0x81842f29, f2cce376), 1000, 320},
-  {GRISU_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
-  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(4) = 14;
-// nb elements (4): 163
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(5)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xaf8e5410, 288e1b6f), -1070, -303},
-  {GRISU_UINT64_C(0x85f04682, 93f0eb4e), -1053, -298},
-  {GRISU_UINT64_C(0xcc5fc196, fefd7d0c), -1037, -293},
-  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
-  {GRISU_UINT64_C(0xedec366b, 11c6cb8f), -1004, -283},
-  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
-  {GRISU_UINT64_C(0x8a7d3eef, 7f1cfc52), -970, -273},
-  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
-  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
-  {GRISU_UINT64_C(0xf6019da0, 7f549b2b), -921, -258},
-  {GRISU_UINT64_C(0xbbb01b92, 83253ca3), -904, -253},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0xda7f5bf5, 90966849), -871, -243},
-  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
-  {GRISU_UINT64_C(0xfe5d5415, 0b090b03), -838, -233},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0x940f4613, ae5ed137), -804, -223},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0xac5d37d5, b79b6239), -771, -213},
-  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
-  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
-  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
-  {GRISU_UINT64_C(0xe998d258, 869facd7), -705, -193},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0x87f8a8d4, cfa417ca), -671, -183},
-  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
-  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0xb84687c2, 69ef3bfb), -605, -163},
-  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
-  {GRISU_UINT64_C(0xd686619b, a27255a3), -572, -153},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
-  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
-  {GRISU_UINT64_C(0x915e2486, ef32cd60), -505, -133},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xa93af6c6, c79b5d2e), -472, -123},
-  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
-  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
-  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
-  {GRISU_UINT64_C(0xe5599087, 9ddcaabe), -406, -103},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0x857fcae6, 2d8493a5), -372, -93},
-  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
-  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
-  {GRISU_UINT64_C(0xed246723, 473e3813), -323, -78},
-  {GRISU_UINT64_C(0xb4ecd5f0, 1a4aa828), -306, -73},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xd29fe4b1, 8e88640f), -273, -63},
-  {GRISU_UINT64_C(0xa0b19d2a, b70e6ed6), -256, -58},
-  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
-  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
-  {GRISU_UINT64_C(0x8eb98a7a, 9a5b04e3), -206, -43},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xa6274bbd, d0fadd62), -173, -33},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
-  {GRISU_UINT64_C(0x9392ee8e, 921d5d07), -123, -18},
-  {GRISU_UINT64_C(0xe12e1342, 4bb40e13), -107, -13},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0x83126e97, 8d4fdf3b), -73, -3},
-  {GRISU_UINT64_C(0xc8000000, 00000000), -57, 2},
-  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0xb1a2bc2e, c5000000), -7, 17},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0xcecb8f27, f4200f3a), 26, 27},
-  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
-  {GRISU_UINT64_C(0xf0bdc21a, bb48db20), 59, 37},
-  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
-  {GRISU_UINT64_C(0x8c213d9d, a502de45), 93, 47},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xa321f2d7, 226895c8), 126, 57},
-  {GRISU_UINT64_C(0xf8ebad2b, 84e0d58c), 142, 62},
-  {GRISU_UINT64_C(0xbde94e8e, 43d0c8ec), 159, 67},
-  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
-  {GRISU_UINT64_C(0xdd15fe86, affad912), 192, 77},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0x80b05e5a, c60b6178), 226, 87},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
-  {GRISU_UINT64_C(0xe498f455, c38b997a), 275, 102},
-  {GRISU_UINT64_C(0xae67f1e9, aec07188), 292, 107},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xcb090c80, 01ab551c), 325, 117},
-  {GRISU_UINT64_C(0x9ae75759, 6946075f), 342, 122},
-  {GRISU_UINT64_C(0xec5d3fa8, ce427b00), 358, 127},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0x899504ae, 72497eba), 392, 137},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xa02aa96b, 06deb0fe), 425, 147},
-  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
-  {GRISU_UINT64_C(0xba756174, 393d88e0), 458, 157},
-  {GRISU_UINT64_C(0x8e41ade9, fbebc27d), 475, 162},
-  {GRISU_UINT64_C(0xd910f7ff, 28069da4), 491, 167},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xfcb2cb35, e702af78), 524, 177},
-  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
-  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
-  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
-  {GRISU_UINT64_C(0xab3c2fdd, eeaad25b), 591, 197},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0xc75809c4, 2c684dd1), 624, 207},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
-  {GRISU_UINT64_C(0xb10d8e14, 56105dad), 674, 222},
-  {GRISU_UINT64_C(0x8714a775, e3e95c78), 691, 227},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0x9d412e08, 06e88aa6), 724, 237},
-  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
-  {GRISU_UINT64_C(0xb7118682, dbb66a77), 757, 247},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xd51ea6fa, 85785631), 790, 257},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0xf81aa16f, dc1b81db), 823, 267},
-  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
-  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
-  {GRISU_UINT64_C(0xdc5c5301, c56b75f7), 873, 282},
-  {GRISU_UINT64_C(0xa81f3014, 49ee8c70), 890, 287},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xc3b83581, 09e84f07), 923, 297},
-  {GRISU_UINT64_C(0x95527a52, 02df0ccb), 940, 302},
-  {GRISU_UINT64_C(0xe3d8f9e5, 63a198e5), 956, 307},
-  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
-  {GRISU_UINT64_C(0x849feec2, 81d7f329), 990, 317},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0x9a65406d, 44a5c903), 1023, 327},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  {GRISU_UINT64_C(0xb3bd72ed, 2af29e20), 1056, 337},
-  {GRISU_UINT64_C(0x892179be, 91d43a44), 1073, 342},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(5) = 17;
-// nb elements (5): 131
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(6)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xdb71e914, 32b1a24b), -1067, -302},
-  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
-  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
-  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
-  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
-  {GRISU_UINT64_C(0x9a94dd3e, 8cf578ba), -628, -170},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
-  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
-  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0xe896a0d7, e51e1566), -509, -134},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xd389b478, 79823479), -469, -122},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
-  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0x9f24b832, e6b0f436), -349, -86},
-  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
-  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0x83a3eeee, f9153e89), -269, -62},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0xef73d256, a5c0f77d), -230, -50},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
-  {GRISU_UINT64_C(0xc6120625, 76589ddb), -150, -26},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0x9502f900, 00000000), -30, 10},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
-  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
-  {GRISU_UINT64_C(0xe0352f62, a19e306f), 89, 46},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xcbea6f8c, eb02bb3a), 129, 58},
-  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0x9968bf6a, bbe85f20), 249, 94},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xfdcb4fa0, 02162a63), 328, 118},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0xe6d3102a, d96cec1e), 368, 130},
-  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0xada72ccc, 20054aea), 488, 166},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
-  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
-  {GRISU_UINT64_C(0x8fa47579, 1a569d11), 568, 190},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
-  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0xd8210bef, d30efa5a), 687, 226},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
-  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
-  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
-  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0x93e1ab82, 52f33b46), 847, 274},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xf4a642e1, 4c6262c9), 926, 298},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0xde81e40a, 034bcf50), 966, 310},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
-  {GRISU_UINT64_C(0xb80dc58e, 81fe95a1), 1046, 334},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(6) = 20;
-// nb elements (6): 109
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(7)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0x892731ac, 9faf056f), -1063, -301},
-  {GRISU_UINT64_C(0xa37fce12, 6597973d), -1040, -294},
-  {GRISU_UINT64_C(0xc2e801fb, 244576d5), -1017, -287},
-  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
-  {GRISU_UINT64_C(0x8a7d3eef, 7f1cfc52), -970, -273},
-  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
-  {GRISU_UINT64_C(0xc4ce17b3, 99107c23), -924, -259},
-  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
-  {GRISU_UINT64_C(0x8bd6a141, 006042be), -877, -245},
-  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
-  {GRISU_UINT64_C(0xc6b8e9b0, 709f109a), -831, -231},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0x8d3360f0, 9cf6e4bd), -784, -217},
-  {GRISU_UINT64_C(0xa8530886, b54dbdec), -761, -210},
-  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
-  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
-  {GRISU_UINT64_C(0x8e938662, 882af53e), -691, -189},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0xca9cf1d2, 06fdc03c), -645, -175},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0x8ff71a0f, e2c2e6dc), -598, -161},
-  {GRISU_UINT64_C(0xab9eb47c, 81f5114f), -575, -154},
-  {GRISU_UINT64_C(0xcc963fee, 10b7d1b3), -552, -147},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0x915e2486, ef32cd60), -505, -133},
-  {GRISU_UINT64_C(0xad4ab711, 2eb3929e), -482, -126},
-  {GRISU_UINT64_C(0xce947a3d, a6a9273e), -459, -119},
-  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
-  {GRISU_UINT64_C(0x92c8ae6b, 464fc96f), -412, -105},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0xd097ad07, a71f26b2), -366, -91},
-  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
-  {GRISU_UINT64_C(0x9436c076, 0c86e30c), -319, -77},
-  {GRISU_UINT64_C(0xb0af48ec, 79ace837), -296, -70},
-  {GRISU_UINT64_C(0xd29fe4b1, 8e88640f), -273, -63},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0x95a86376, 27989aae), -226, -49},
-  {GRISU_UINT64_C(0xb267ed19, 40f1c61c), -203, -42},
-  {GRISU_UINT64_C(0xd4ad2dbf, c3d07788), -180, -35},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0x971da050, 74da7bef), -133, -21},
-  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
-  {GRISU_UINT64_C(0xd6bf94d5, e57a42bc), -87, -7},
-  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
-  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
-  {GRISU_UINT64_C(0xb5e620f4, 80000000), -17, 14},
-  {GRISU_UINT64_C(0xd8d726b7, 177a8000), 6, 21},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0x9a130b96, 3a6c115c), 53, 35},
-  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
-  {GRISU_UINT64_C(0xdaf3f046, 51d47b4c), 99, 49},
-  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
-  {GRISU_UINT64_C(0x9b934c3b, 330c8577), 146, 63},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0xdd15fe86, affad912), 192, 77},
-  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
-  {GRISU_UINT64_C(0x9d174b2d, cec0e47b), 239, 91},
-  {GRISU_UINT64_C(0xbb445da9, ca61281f), 262, 98},
-  {GRISU_UINT64_C(0xdf3d5e9b, c0f653e1), 285, 105},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0x9e9f11c4, 014dda7e), 332, 119},
-  {GRISU_UINT64_C(0xbd176620, a501fc00), 355, 126},
-  {GRISU_UINT64_C(0xe16a1dc9, d8545e95), 378, 133},
-  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
-  {GRISU_UINT64_C(0xa02aa96b, 06deb0fe), 425, 147},
-  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
-  {GRISU_UINT64_C(0xe39c4976, 5fdf9d95), 471, 161},
-  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
-  {GRISU_UINT64_C(0xa1ba1ba7, 9e1632dc), 518, 175},
-  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
-  {GRISU_UINT64_C(0xe5d3ef28, 2a242e82), 564, 189},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xa34d7216, 42b06084), 611, 203},
-  {GRISU_UINT64_C(0xc2abf989, 935ddbfe), 634, 210},
-  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
-  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
-  {GRISU_UINT64_C(0xa4e4b66b, 68b65d61), 704, 231},
-  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
-  {GRISU_UINT64_C(0xea53df5f, d18d5514), 750, 245},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xa67ff273, b8460357), 797, 259},
-  {GRISU_UINT64_C(0xc67bb459, 7ce2ce49), 820, 266},
-  {GRISU_UINT64_C(0xec9c459d, 51852ba3), 843, 273},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0xa81f3014, 49ee8c70), 890, 287},
-  {GRISU_UINT64_C(0xc86ab5c3, 9fa63441), 913, 294},
-  {GRISU_UINT64_C(0xeeea5d50, 04981478), 936, 301},
-  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
-  {GRISU_UINT64_C(0xa9c2794a, e3a3c69b), 983, 315},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xf13e34aa, bb430a15), 1029, 329},
-  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(7) = 24;
-// nb elements (7): 93
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(8)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300},
-  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
-  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
-  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
-  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
-  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
-  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
-  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
-  {GRISU_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
-  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
-  {GRISU_UINT64_C(0xb9447093, 8fa89bcf), -316, -76},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xcdb02555, 653131b6), -263, -60},
-  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12},
-  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0xad78ebc5, ac620000), 3, 20},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0xc097ce7b, c90715b3), 56, 36},
-  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
-  {GRISU_UINT64_C(0xed63a231, d4c4fb27), 162, 68},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
-  {GRISU_UINT64_C(0xa26da399, 9aef774a), 322, 116},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
-  {GRISU_UINT64_C(0xde469fbd, 99a05fe3), 481, 164},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xf6c69a72, a3989f5c), 534, 180},
-  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228},
-  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
-  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xd01fef10, a657842c), 800, 260},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276},
-  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
-  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(8) = 27;
-// nb elements (8): 82
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(9)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xd64d3d9d, b981787d), -1057, -299},
-  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
-  {GRISU_UINT64_C(0xb9e08a83, a5e34f08), -997, -281},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
-  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
-  {GRISU_UINT64_C(0x8bd6a141, 006042be), -877, -245},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xf294b943, e17a2bc4), -818, -227},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0xd267caa8, 62a12d67), -758, -209},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0xb67f6455, 292cbf08), -698, -191},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0x894bc396, ce5da772), -578, -155},
-  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
-  {GRISU_UINT64_C(0xee2ba6c0, 678b597f), -519, -137},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xce947a3d, a6a9273e), -459, -119},
-  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
-  {GRISU_UINT64_C(0xb32df8e9, f3546564), -399, -101},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
-  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
-  {GRISU_UINT64_C(0x86ccbb52, ea94baeb), -279, -65},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0xe9d71b68, 9dde71b0), -220, -47},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xcad2f7f5, 359a3b3e), -160, -29},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xafebff0b, cb24aaff), -100, -11},
-  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
-  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0x84595161, 401484a0), 20, 25},
-  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
-  {GRISU_UINT64_C(0xe596b7b0, c643c719), 79, 43},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xc722f0ef, 9d80aad6), 139, 61},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0xacb92ed9, 397bf996), 199, 79},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
-  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
-  {GRISU_UINT64_C(0x81f14fae, 158c5f6e), 319, 115},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0xe16a1dc9, d8545e95), 378, 133},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xc38413cf, 25e2d70e), 438, 151},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0xa99541bf, 57452b28), 498, 169},
-  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
-  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xff290242, c83396ce), 617, 205},
-  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
-  {GRISU_UINT64_C(0xdd50f199, 6b947519), 677, 223},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xbff610b0, cc6edd3f), 737, 241},
-  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
-  {GRISU_UINT64_C(0xa67ff273, b8460357), 797, 259},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
-  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
-  {GRISU_UINT64_C(0xfa856334, 878fc151), 916, 295},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0xd94ad8b1, c7380874), 976, 313},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xbc789925, 624c5fe1), 1036, 331},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(9) = 30;
-// nb elements (9): 73
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(10)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0x85f04682, 93f0eb4e), -1053, -298},
-  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
-  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
-  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
-  {GRISU_UINT64_C(0xf6019da0, 7f549b2b), -921, -258},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
-  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
-  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
-  {GRISU_UINT64_C(0xed246723, 473e3813), -323, -78},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xa0b19d2a, b70e6ed6), -256, -58},
-  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0x9392ee8e, 921d5d07), -123, -18},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0xc8000000, 00000000), -57, 2},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
-  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xf8ebad2b, 84e0d58c), 142, 62},
-  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0xe498f455, c38b997a), 275, 102},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0x9ae75759, 6946075f), 342, 122},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
-  {GRISU_UINT64_C(0x8e41ade9, fbebc27d), 475, 162},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
-  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xb10d8e14, 56105dad), 674, 222},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
-  {GRISU_UINT64_C(0xdc5c5301, c56b75f7), 873, 282},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0x95527a52, 02df0ccb), 940, 302},
-  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  {GRISU_UINT64_C(0x892179be, 91d43a44), 1073, 342},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(10) = 34;
-// nb elements (10): 66
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(11)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xa76c5823, 38ed2622), -1050, -297},
-  {GRISU_UINT64_C(0xf3a20279, ed56d48a), -1014, -286},
-  {GRISU_UINT64_C(0xb1442798, f49ffb4b), -977, -275},
-  {GRISU_UINT64_C(0x80fa687f, 881c7f8e), -940, -264},
-  {GRISU_UINT64_C(0xbbb01b92, 83253ca3), -904, -253},
-  {GRISU_UINT64_C(0x888f9979, 7a5e012d), -867, -242},
-  {GRISU_UINT64_C(0xc6b8e9b0, 709f109a), -831, -231},
-  {GRISU_UINT64_C(0x9096ea6f, 3848984f), -794, -220},
-  {GRISU_UINT64_C(0xd267caa8, 62a12d67), -758, -209},
-  {GRISU_UINT64_C(0x99171105, 2d8bf3c5), -721, -198},
-  {GRISU_UINT64_C(0xdec681f9, f4c31f31), -685, -187},
-  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
-  {GRISU_UINT64_C(0xebdf6617, 91d60f56), -612, -165},
-  {GRISU_UINT64_C(0xab9eb47c, 81f5114f), -575, -154},
-  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
-  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
-  {GRISU_UINT64_C(0x843610cb, 4bf160cc), -465, -121},
-  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
-  {GRISU_UINT64_C(0x8bfbea76, c619ef36), -392, -99},
-  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
-  {GRISU_UINT64_C(0x9436c076, 0c86e30c), -319, -77},
-  {GRISU_UINT64_C(0xd7adf884, aa879177), -283, -66},
-  {GRISU_UINT64_C(0x9ced737b, b6c4183d), -246, -55},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0xa6274bbd, d0fadd62), -173, -33},
-  {GRISU_UINT64_C(0xf1c90080, baf72cb1), -137, -22},
-  {GRISU_UINT64_C(0xafebff0b, cb24aaff), -100, -11},
-  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
-  {GRISU_UINT64_C(0xba43b740, 00000000), -27, 11},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0xc5371912, 364ce305), 46, 33},
-  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
-  {GRISU_UINT64_C(0xd0cf4b50, cfe20766), 119, 55},
-  {GRISU_UINT64_C(0x97edd871, cfda3a57), 156, 66},
-  {GRISU_UINT64_C(0xdd15fe86, affad912), 192, 77},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0xea157514, 3cf97227), 265, 99},
-  {GRISU_UINT64_C(0xaa51823e, 34a7eedf), 302, 110},
-  {GRISU_UINT64_C(0xf7d88bc2, 4209a565), 338, 121},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0x8335616a, ed761f1f), 412, 143},
-  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
-  {GRISU_UINT64_C(0x8aec23d6, 80043bee), 485, 165},
-  {GRISU_UINT64_C(0xca28a291, 859bbf93), 521, 176},
-  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
-  {GRISU_UINT64_C(0xd60b3bd5, 6a5586f2), 594, 198},
-  {GRISU_UINT64_C(0x9bbcc7a1, 42b17ccc), 631, 209},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0xa4e4b66b, 68b65d61), 704, 231},
-  {GRISU_UINT64_C(0xeff394dc, ff8a948f), 740, 242},
-  {GRISU_UINT64_C(0xae9672ab, a3d0c321), 777, 253},
-  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
-  {GRISU_UINT64_C(0xb8da1662, e7b00a17), 850, 275},
-  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
-  {GRISU_UINT64_C(0xc3b83581, 09e84f07), 923, 297},
-  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
-  {GRISU_UINT64_C(0xcf39e50f, eae16bf0), 996, 319},
-  {GRISU_UINT64_C(0x96c6e0ea, b509e64d), 1033, 330},
-  {GRISU_UINT64_C(0xdb68c2ca, 82ed2a06), 1069, 341},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(11) = 37;
-// nb elements (11): 60
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(12)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xd1476e2c, 07286faa), -1047, -296},
-  {GRISU_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0xa21727db, 38cb0030), -648, -176},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44},
-  {GRISU_UINT64_C(0xcfb11ead, 453994ba), -170, -32},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0xeb194f8e, 1ae525fd), 69, 40},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xc2781f49, ffcfa6d5), 149, 64},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0xdc21a117, 1d42645d), 388, 136},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0x969eb7c4, 7859e744), 548, 184},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xf92e0c35, 37826146), 627, 208},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xbb764c4c, a7a44410), 747, 244},
-  {GRISU_UINT64_C(0xaa7eebfb, 9df9de8e), 787, 256},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0xc0fe9088, 95cf3b44), 1026, 328},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(12) = 40;
-// nb elements (12): 55
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(13)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0x82cca4db, 847945ca), -1043, -295},
-  {GRISU_UINT64_C(0x94b3a202, eb1c3f39), -1000, -282},
-  {GRISU_UINT64_C(0xa90de353, 5aaae202), -957, -269},
-  {GRISU_UINT64_C(0xc0314325, 637a193a), -914, -256},
-  {GRISU_UINT64_C(0xda7f5bf5, 90966849), -871, -243},
-  {GRISU_UINT64_C(0xf867241c, 8cc6d4c1), -828, -230},
-  {GRISU_UINT64_C(0x8d3360f0, 9cf6e4bd), -784, -217},
-  {GRISU_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204},
-  {GRISU_UINT64_C(0xb67f6455, 292cbf08), -698, -191},
-  {GRISU_UINT64_C(0xcf79cc9d, b955c2cc), -655, -178},
-  {GRISU_UINT64_C(0xebdf6617, 91d60f56), -612, -165},
-  {GRISU_UINT64_C(0x8613fd01, 45877586), -568, -152},
-  {GRISU_UINT64_C(0x986ddb5c, 6b3a76b8), -525, -139},
-  {GRISU_UINT64_C(0xad4ab711, 2eb3929e), -482, -126},
-  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
-  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
-  {GRISU_UINT64_C(0xfea126b7, d78186bd), -353, -87},
-  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
-  {GRISU_UINT64_C(0xa48ceaaa, b75a8e2b), -266, -61},
-  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
-  {GRISU_UINT64_C(0xd4ad2dbf, c3d07788), -180, -35},
-  {GRISU_UINT64_C(0xf1c90080, baf72cb1), -137, -22},
-  {GRISU_UINT64_C(0x89705f41, 36b4a597), -93, -9},
-  {GRISU_UINT64_C(0x9c400000, 00000000), -50, 4},
-  {GRISU_UINT64_C(0xb1a2bc2e, c5000000), -7, 17},
-  {GRISU_UINT64_C(0xc9f2c9cd, 04674edf), 36, 30},
-  {GRISU_UINT64_C(0xe596b7b0, c643c719), 79, 43},
-  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
-  {GRISU_UINT64_C(0x945e455f, 24fb1cf9), 166, 69},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0xbfc2ef45, 6ae276e9), 252, 95},
-  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
-  {GRISU_UINT64_C(0xf7d88bc2, 4209a565), 338, 121},
-  {GRISU_UINT64_C(0x8ce2529e, 2734bb1d), 382, 134},
-  {GRISU_UINT64_C(0xa02aa96b, 06deb0fe), 425, 147},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0xcf02b2c2, 1207ef2f), 511, 173},
-  {GRISU_UINT64_C(0xeb57ff22, fc0c795a), 554, 186},
-  {GRISU_UINT64_C(0x85c70565, 62757457), 598, 199},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xace73cbf, dc0bfb7b), 684, 225},
-  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
-  {GRISU_UINT64_C(0xdf78e4b2, bd342cf7), 770, 251},
-  {GRISU_UINT64_C(0xfe0efb53, d30dd4d8), 813, 264},
-  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
-  {GRISU_UINT64_C(0xa42e74f3, d032f526), 900, 290},
-  {GRISU_UINT64_C(0xbaa718e6, 8396cffe), 943, 303},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0xf13e34aa, bb430a15), 1029, 329},
-  {GRISU_UINT64_C(0x892179be, 91d43a44), 1073, 342},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(13) = 44;
-// nb elements (13): 51
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(14)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xa37fce12, 6597973d), -1040, -294},
-  {GRISU_UINT64_C(0xe858ad24, 8f5c22ca), -994, -280},
-  {GRISU_UINT64_C(0xa5178fff, 668ae0b6), -947, -266},
-  {GRISU_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252},
-  {GRISU_UINT64_C(0xa6b34ad8, c9dfc070), -854, -238},
-  {GRISU_UINT64_C(0xece53cec, 4a314ebe), -808, -224},
-  {GRISU_UINT64_C(0xa8530886, b54dbdec), -761, -210},
-  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0xab9eb47c, 81f5114f), -575, -154},
-  {GRISU_UINT64_C(0xf3e2f893, dec3f126), -529, -140},
-  {GRISU_UINT64_C(0xad4ab711, 2eb3929e), -482, -126},
-  {GRISU_UINT64_C(0xf64335bc, f065d37d), -436, -112},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
-  {GRISU_UINT64_C(0xb0af48ec, 79ace837), -296, -70},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0xb267ed19, 40f1c61c), -203, -42},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0xb424dc35, 095cd80f), -110, -14},
-  {GRISU_UINT64_C(0x80000000, 00000000), -63, 0},
-  {GRISU_UINT64_C(0xb5e620f4, 80000000), -17, 14},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0xb7abc627, 050305ae), 76, 42},
-  {GRISU_UINT64_C(0x82818f12, 81ed44a0), 123, 56},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0x83c7088e, 1aab65db), 216, 84},
-  {GRISU_UINT64_C(0xbb445da9, ca61281f), 262, 98},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xbd176620, a501fc00), 355, 126},
-  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
-  {GRISU_UINT64_C(0xbeeefb58, 4aff8604), 448, 154},
-  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
-  {GRISU_UINT64_C(0xc0cb28a9, 8fcf3c80), 541, 182},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xc2abf989, 935ddbfe), 634, 210},
-  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
-  {GRISU_UINT64_C(0xc491798a, 08a2ad4f), 727, 238},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xc67bb459, 7ce2ce49), 820, 266},
-  {GRISU_UINT64_C(0x8d07e334, 55637eb3), 867, 280},
-  {GRISU_UINT64_C(0xc86ab5c3, 9fa63441), 913, 294},
-  {GRISU_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0x8fcac257, 558ee4e6), 1053, 336},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(14) = 47;
-// nb elements (14): 47
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(15)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xcc5fc196, fefd7d0c), -1037, -293},
-  {GRISU_UINT64_C(0xb5854744, 8ffffb2e), -987, -278},
-  {GRISU_UINT64_C(0xa139029f, 6a239f72), -937, -263},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0xfe5d5415, 0b090b03), -838, -233},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0xc8a883c0, fdaf7df0), -738, -203},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0x9e4a9cec, 15763e2f), -638, -173},
-  {GRISU_UINT64_C(0x8c974f73, 83725573), -588, -158},
-  {GRISU_UINT64_C(0xf9bd690a, 1b68637b), -539, -143},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xc5029163, f384a931), -439, -113},
-  {GRISU_UINT64_C(0xaefae514, 77a06b04), -389, -98},
-  {GRISU_UINT64_C(0x9b69dbe1, b548ce7d), -339, -83},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0x98968000, 00000000), -40, 7},
-  {GRISU_UINT64_C(0x87867832, 6eac9000), 10, 22},
-  {GRISU_UINT64_C(0xf0bdc21a, bb48db20), 59, 37},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xbde94e8e, 43d0c8ec), 159, 67},
-  {GRISU_UINT64_C(0xa8acd7c0, 222311bd), 209, 82},
-  {GRISU_UINT64_C(0x95d04aee, 3b80ece6), 259, 97},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xec5d3fa8, ce427b00), 358, 127},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xba756174, 393d88e0), 458, 157},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0x9316ff75, dd87cbd8), 558, 187},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0xe8111c87, c5c1ba9a), 657, 217},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xb7118682, dbb66a77), 757, 247},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0x906a617d, 450187e2), 857, 277},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xe3d8f9e5, 63a198e5), 956, 307},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xb3bd72ed, 2af29e20), 1056, 337},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(15) = 50;
-// nb elements (15): 44
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(16)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292},
-  {GRISU_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276},
-  {GRISU_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260},
-  {GRISU_UINT64_C(0xaecc4991, 4078536d), -874, -244},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0xd77485cb, 25823ac7), -768, -212},
-  {GRISU_UINT64_C(0xef340a98, 172aace5), -715, -196},
-  {GRISU_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132},
-  {GRISU_UINT64_C(0xc9bcff60, 34c13053), -449, -116},
-  {GRISU_UINT64_C(0xdff97724, 70297ebd), -396, -100},
-  {GRISU_UINT64_C(0xf8a95fcf, 88747d94), -343, -84},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0x993fe2c6, d07b7fac), -236, -52},
-  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0x813f3978, f8940984), 30, 28},
-  {GRISU_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44},
-  {GRISU_UINT64_C(0x9f4f2726, 179a2245), 136, 60},
-  {GRISU_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0xda01ee64, 1a708dea), 295, 108},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140},
-  {GRISU_UINT64_C(0x952ab45c, fa97a0b3), 455, 156},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188},
-  {GRISU_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204},
-  {GRISU_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220},
-  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0xac2820d9, 623bf429), 880, 284},
-  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
-  {GRISU_UINT64_C(0xd433179d, 9c8cb841), 986, 316},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(16) = 54;
-// nb elements (16): 41
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(17)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0x9faacf3d, f73609b1), -1030, -291},
-  {GRISU_UINT64_C(0xdd95317f, 31c7fa1d), -974, -274},
-  {GRISU_UINT64_C(0x99c10284, 4f94e0fb), -917, -257},
-  {GRISU_UINT64_C(0xd5605fcd, cf32e1d7), -861, -240},
-  {GRISU_UINT64_C(0x940f4613, ae5ed137), -804, -223},
-  {GRISU_UINT64_C(0xcd795be8, 70516656), -748, -206},
-  {GRISU_UINT64_C(0x8e938662, 882af53e), -691, -189},
-  {GRISU_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172},
-  {GRISU_UINT64_C(0x894bc396, ce5da772), -578, -155},
-  {GRISU_UINT64_C(0xbe895233, 86091466), -522, -138},
-  {GRISU_UINT64_C(0x843610cb, 4bf160cc), -465, -121},
-  {GRISU_UINT64_C(0xb77ada06, 17e3bbcb), -409, -104},
-  {GRISU_UINT64_C(0xfea126b7, d78186bd), -353, -87},
-  {GRISU_UINT64_C(0xb0af48ec, 79ace837), -296, -70},
-  {GRISU_UINT64_C(0xf5330471, 4d9265e0), -240, -53},
-  {GRISU_UINT64_C(0xaa242499, 697392d3), -183, -36},
-  {GRISU_UINT64_C(0xec1e4a7d, b69561a5), -127, -19},
-  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
-  {GRISU_UINT64_C(0xe35fa931, a0000000), -14, 15},
-  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
-  {GRISU_UINT64_C(0xdaf3f046, 51d47b4c), 99, 49},
-  {GRISU_UINT64_C(0x97edd871, cfda3a57), 156, 66},
-  {GRISU_UINT64_C(0xd2d80db0, 2aabd62c), 212, 83},
-  {GRISU_UINT64_C(0x924d692c, a61be758), 269, 100},
-  {GRISU_UINT64_C(0xcb090c80, 01ab551c), 325, 117},
-  {GRISU_UINT64_C(0x8ce2529e, 2734bb1d), 382, 134},
-  {GRISU_UINT64_C(0xc38413cf, 25e2d70e), 438, 151},
-  {GRISU_UINT64_C(0x87aa9aff, 79042287), 495, 168},
-  {GRISU_UINT64_C(0xbc4665b5, 96706115), 551, 185},
-  {GRISU_UINT64_C(0x82a45b45, 0226b39d), 608, 202},
-  {GRISU_UINT64_C(0xb54d5e4a, 127f59c8), 664, 219},
-  {GRISU_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236},
-  {GRISU_UINT64_C(0xae9672ab, a3d0c321), 777, 253},
-  {GRISU_UINT64_C(0xf24a01a7, 3cf2dcd0), 833, 270},
-  {GRISU_UINT64_C(0xa81f3014, 49ee8c70), 890, 287},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0xa1e53af4, 6f801c53), 1003, 321},
-  {GRISU_UINT64_C(0xe0accfa8, 75af45a8), 1059, 338},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(17) = 57;
-// nb elements (17): 39
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(18)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xc795830d, 75038c1e), -1027, -290},
-  {GRISU_UINT64_C(0xad1c8eab, 5ee43b67), -967, -272},
-  {GRISU_UINT64_C(0x96267c75, 35b763b5), -907, -254},
-  {GRISU_UINT64_C(0x823c1279, 5db6ce57), -847, -236},
-  {GRISU_UINT64_C(0xe1ebce4d, c7f16dfc), -788, -218},
-  {GRISU_UINT64_C(0xc3f490aa, 77bd60fd), -728, -200},
-  {GRISU_UINT64_C(0xa9f6d30a, 038d1dbc), -668, -182},
-  {GRISU_UINT64_C(0x936b9fce, bb25c996), -608, -164},
-  {GRISU_UINT64_C(0xffbbcfe9, 94e5c620), -549, -146},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0xc06481fb, 9bcf8d3a), -429, -110},
-  {GRISU_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92},
-  {GRISU_UINT64_C(0x90bd77f3, 483bb9ba), -309, -74},
-  {GRISU_UINT64_C(0xfb158592, be068d2f), -250, -56},
-  {GRISU_UINT64_C(0xd9c7dced, 53c72256), -190, -38},
-  {GRISU_UINT64_C(0xbce50864, 92111aeb), -130, -20},
-  {GRISU_UINT64_C(0xa3d70a3d, 70a3d70a), -70, -2},
-  {GRISU_UINT64_C(0x8e1bc9bf, 04000000), -10, 16},
-  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0xb975d6b6, ee39e437), 169, 70},
-  {GRISU_UINT64_C(0xa0dc75f1, 778e39d6), 229, 88},
-  {GRISU_UINT64_C(0x8b865b21, 5899f46d), 289, 106},
-  {GRISU_UINT64_C(0xf209787b, b47d6b85), 348, 124},
-  {GRISU_UINT64_C(0xd1ef0244, af2364ff), 408, 142},
-  {GRISU_UINT64_C(0xb616a12b, 7fe617aa), 468, 160},
-  {GRISU_UINT64_C(0x9defbf01, b061adab), 528, 178},
-  {GRISU_UINT64_C(0x88fcf317, f22241e2), 588, 196},
-  {GRISU_UINT64_C(0xeda2ee1c, 7064130c), 647, 214},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0xb2c71d5b, ca9023f8), 767, 250},
-  {GRISU_UINT64_C(0x9b10a4e5, e9913129), 827, 268},
-  {GRISU_UINT64_C(0x867f59a9, d4bed6c0), 887, 286},
-  {GRISU_UINT64_C(0xe950df20, 247c83fd), 946, 304},
-  {GRISU_UINT64_C(0xca5e89b1, 8b602368), 1006, 322},
-  {GRISU_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(18) = 60;
-// nb elements (18): 37
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(19)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0xf97ae3d0, d2446f25), -1024, -289},
-  {GRISU_UINT64_C(0x873e4f75, e2224e68), -960, -270},
-  {GRISU_UINT64_C(0x92a1958a, 7675175f), -897, -251},
-  {GRISU_UINT64_C(0x9efa548d, 26e5a6e2), -834, -232},
-  {GRISU_UINT64_C(0xac5d37d5, b79b6239), -771, -213},
-  {GRISU_UINT64_C(0xbae0a846, d2195713), -708, -194},
-  {GRISU_UINT64_C(0xca9cf1d2, 06fdc03c), -645, -175},
-  {GRISU_UINT64_C(0xdbac6c24, 7d62a584), -582, -156},
-  {GRISU_UINT64_C(0xee2ba6c0, 678b597f), -519, -137},
-  {GRISU_UINT64_C(0x811ccc66, 8829b887), -455, -118},
-  {GRISU_UINT64_C(0x8bfbea76, c619ef36), -392, -99},
-  {GRISU_UINT64_C(0x97c560ba, 6b0919a6), -329, -80},
-  {GRISU_UINT64_C(0xa48ceaaa, b75a8e2b), -266, -61},
-  {GRISU_UINT64_C(0xb267ed19, 40f1c61c), -203, -42},
-  {GRISU_UINT64_C(0xc16d9a00, 95928a27), -140, -23},
-  {GRISU_UINT64_C(0xd1b71758, e219652c), -77, -4},
-  {GRISU_UINT64_C(0xe35fa931, a0000000), -14, 15},
-  {GRISU_UINT64_C(0xf684df56, c3e01bc7), 49, 34},
-  {GRISU_UINT64_C(0x85a36366, eb71f041), 113, 53},
-  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
-  {GRISU_UINT64_C(0x9d174b2d, cec0e47b), 239, 91},
-  {GRISU_UINT64_C(0xaa51823e, 34a7eedf), 302, 110},
-  {GRISU_UINT64_C(0xb8a8d9bb, e123f018), 365, 129},
-  {GRISU_UINT64_C(0xc83553c5, c8965d3d), 428, 148},
-  {GRISU_UINT64_C(0xd910f7ff, 28069da4), 491, 167},
-  {GRISU_UINT64_C(0xeb57ff22, fc0c795a), 554, 186},
-  {GRISU_UINT64_C(0xff290242, c83396ce), 617, 205},
-  {GRISU_UINT64_C(0x8a5296ff, e33cc930), 681, 224},
-  {GRISU_UINT64_C(0x95f83d0a, 1fb69cd9), 744, 243},
-  {GRISU_UINT64_C(0xa298f2c5, 01f45f43), 807, 262},
-  {GRISU_UINT64_C(0xb049dc01, 6abc5e60), 870, 281},
-  {GRISU_UINT64_C(0xbf21e440, 03acdd2d), 933, 300},
-  {GRISU_UINT64_C(0xcf39e50f, eae16bf0), 996, 319},
-  {GRISU_UINT64_C(0xe0accfa8, 75af45a8), 1059, 338},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(19) = 64;
-// nb elements (19): 35
-static const GRISU_CACHE_STRUCT GRISU_CACHE_NAME(20)[] = {
-  {GRISU_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308},
-  {GRISU_UINT64_C(0x9becce62, 836ac577), -1020, -288},
-  {GRISU_UINT64_C(0xd3515c28, 31559a83), -954, -268},
-  {GRISU_UINT64_C(0x8f31cc09, 37ae58d3), -887, -248},
-  {GRISU_UINT64_C(0xc2109436, 4dfb5637), -821, -228},
-  {GRISU_UINT64_C(0x8380dea9, 3da4bc60), -754, -208},
-  {GRISU_UINT64_C(0xb23867fb, 2a35b28e), -688, -188},
-  {GRISU_UINT64_C(0xf18899b1, bc3f8ca2), -622, -168},
-  {GRISU_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148},
-  {GRISU_UINT64_C(0xddd0467c, 64bce4a1), -489, -128},
-  {GRISU_UINT64_C(0x964e858c, 91ba2655), -422, -108},
-  {GRISU_UINT64_C(0xcbb41ef9, 79346bca), -356, -88},
-  {GRISU_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68},
-  {GRISU_UINT64_C(0xbb127c53, b17ec159), -223, -48},
-  {GRISU_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28},
-  {GRISU_UINT64_C(0xabcc7711, 8461cefd), -90, -8},
-  {GRISU_UINT64_C(0xe8d4a510, 00000000), -24, 12},
-  {GRISU_UINT64_C(0x9dc5ada8, 2b70b59e), 43, 32},
-  {GRISU_UINT64_C(0xd5d238a4, abe98068), 109, 52},
-  {GRISU_UINT64_C(0x90e40fbe, ea1d3a4b), 176, 72},
-  {GRISU_UINT64_C(0xc45d1df9, 42711d9a), 242, 92},
-  {GRISU_UINT64_C(0x850fadc0, 9923329e), 309, 112},
-  {GRISU_UINT64_C(0xb454e4a1, 79dd1877), 375, 132},
-  {GRISU_UINT64_C(0xf46518c2, ef5b8cd1), 441, 152},
-  {GRISU_UINT64_C(0xa59bc234, db398c25), 508, 172},
-  {GRISU_UINT64_C(0xe070f78d, 3927556b), 574, 192},
-  {GRISU_UINT64_C(0x98165af3, 7b2153df), 641, 212},
-  {GRISU_UINT64_C(0xce1de406, 42e3f4b9), 707, 232},
-  {GRISU_UINT64_C(0x8bab8eef, b6409c1a), 774, 252},
-  {GRISU_UINT64_C(0xbd49d14a, a79dbc82), 840, 272},
-  {GRISU_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292},
-  {GRISU_UINT64_C(0xadd57a27, d29339f6), 973, 312},
-  {GRISU_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332},
-  };
-static const int GRISU_CACHE_MAX_DISTANCE(20) = 67;
-// nb elements (20): 33
-static const int GRISU_CACHE_OFFSET = 308;
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 525dea2..977c67c 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -94,12 +94,18 @@
 }
 
 
+static void DeleteIndexName(char** name_ptr) {
+  DeleteArray(*name_ptr);
+}
+
+
 StringsStorage::~StringsStorage() {
   for (HashMap::Entry* p = names_.Start();
        p != NULL;
        p = names_.Next(p)) {
     DeleteArray(reinterpret_cast<const char*>(p->value));
   }
+  index_names_.Iterate(DeleteIndexName);
 }
 
 
@@ -120,6 +126,22 @@
 }
 
 
+const char* StringsStorage::GetName(int index) {
+  ASSERT(index >= 0);
+  if (index_names_.length() <= index) {
+    index_names_.AddBlock(
+        NULL, index - index_names_.length() + 1);
+  }
+  if (index_names_[index] == NULL) {
+    const int kMaximumNameLength = 32;
+    char* name = NewArray<char>(kMaximumNameLength);
+    OS::SNPrintF(Vector<char>(name, kMaximumNameLength), "%d", index);
+    index_names_[index] = name;
+  }
+  return index_names_[index];
+}
+
+
 const char* CodeEntry::kEmptyNamePrefix = "";
 
 
@@ -485,11 +507,6 @@
 }
 
 
-static void DeleteArgsCountName(char** name_ptr) {
-  DeleteArray(*name_ptr);
-}
-
-
 static void DeleteCodeEntry(CodeEntry** entry_ptr) {
   delete *entry_ptr;
 }
@@ -508,7 +525,6 @@
   current_profiles_.Iterate(DeleteCpuProfile);
   profiles_by_token_.Iterate(DeleteProfilesList);
   code_entries_.Iterate(DeleteCodeEntry);
-  args_count_names_.Iterate(DeleteArgsCountName);
 }
 
 
@@ -706,22 +722,6 @@
 }
 
 
-const char* CpuProfilesCollection::GetName(int args_count) {
-  ASSERT(args_count >= 0);
-  if (args_count_names_.length() <= args_count) {
-    args_count_names_.AddBlock(
-        NULL, args_count - args_count_names_.length() + 1);
-  }
-  if (args_count_names_[args_count] == NULL) {
-    const int kMaximumNameLength = 32;
-    char* name = NewArray<char>(kMaximumNameLength);
-    OS::SNPrintF(Vector<char>(name, kMaximumNameLength), "%d", args_count);
-    args_count_names_[args_count] = name;
-  }
-  return args_count_names_[args_count];
-}
-
-
 void CpuProfilesCollection::AddPathToCurrentProfiles(
     const Vector<CodeEntry*>& path) {
   // As starting / stopping profiles is rare relatively to this
@@ -952,7 +952,7 @@
 
 
 void HeapEntry::Print(int max_depth, int indent) {
-  OS::Print("%6d %6d %6d [%ld] ",
+  OS::Print("%6d %6d %6d [%llu] ",
             self_size(), ReachableSize(), RetainedSize(), id_);
   if (type() != kString) {
     OS::Print("%s %.40s\n", TypeAsString(), name_);
@@ -1001,6 +1001,8 @@
     case kString: return "/string/";
     case kCode: return "/code/";
     case kArray: return "/array/";
+    case kRegExp: return "/regexp/";
+    case kHeapNumber: return "/number/";
     default: return "???";
   }
 }
@@ -1237,7 +1239,7 @@
       type_(type),
       title_(title),
       uid_(uid),
-      root_entry_index_(-1),
+      root_entry_(NULL),
       raw_entries_(NULL),
       entries_sorted_(false) {
   STATIC_ASSERT(
@@ -1276,19 +1278,24 @@
                                   int children_count,
                                   int retainers_count) {
   if (object == kInternalRootObject) {
-    ASSERT(root_entry_index_ == -1);
-    root_entry_index_ = entries_.length();
+    ASSERT(root_entry_ == NULL);
     ASSERT(retainers_count == 0);
-    return AddEntry(
+    root_entry_ = AddEntry(
         HeapEntry::kInternal, "", 0, 0, children_count, retainers_count);
+    return root_entry_;
   } else if (object->IsJSFunction()) {
     JSFunction* func = JSFunction::cast(object);
     SharedFunctionInfo* shared = func->shared();
-    String* name = String::cast(shared->name())->length() > 0 ?
-        String::cast(shared->name()) : shared->inferred_name();
     return AddEntry(object,
                     HeapEntry::kClosure,
-                    collection_->GetFunctionName(name),
+                    collection_->GetName(String::cast(shared->name())),
+                    children_count,
+                    retainers_count);
+  } else if (object->IsJSRegExp()) {
+    JSRegExp* re = JSRegExp::cast(object);
+    return AddEntry(object,
+                    HeapEntry::kRegExp,
+                    collection_->GetName(re->Pattern()),
                     children_count,
                     retainers_count);
   } else if (object->IsJSObject()) {
@@ -1333,6 +1340,12 @@
                     "",
                     children_count,
                     retainers_count);
+  } else if (object->IsHeapNumber()) {
+    return AddEntry(object,
+                    HeapEntry::kHeapNumber,
+                    "number",
+                    children_count,
+                    retainers_count);
   }
   // No interest in this object.
   return NULL;
@@ -1342,12 +1355,14 @@
 bool HeapSnapshot::WillAddEntry(HeapObject* object) {
   return object == kInternalRootObject
       || object->IsJSFunction()
+      || object->IsJSRegExp()
       || object->IsJSObject()
       || object->IsString()
       || object->IsCode()
       || object->IsSharedFunctionInfo()
       || object->IsScript()
-      || object->IsFixedArray();
+      || object->IsFixedArray()
+      || object->IsHeapNumber();
 }
 
 
@@ -1904,13 +1919,21 @@
     ExtractClosureReferences(js_obj, entry);
     ExtractPropertyReferences(js_obj, entry);
     ExtractElementReferences(js_obj, entry);
+    ExtractInternalReferences(js_obj, entry);
     SetPropertyReference(
-        obj, entry, Heap::prototype_symbol(), js_obj->map()->prototype());
+        obj, entry, Heap::Proto_symbol(), js_obj->GetPrototype());
+    if (obj->IsJSFunction()) {
+      JSFunction* js_fun = JSFunction::cast(obj);
+      if (js_fun->has_prototype()) {
+        SetPropertyReference(
+            obj, entry, Heap::prototype_symbol(), js_fun->prototype());
+      }
+    }
   } else if (obj->IsString()) {
     if (obj->IsConsString()) {
       ConsString* cs = ConsString::cast(obj);
-      SetElementReference(obj, entry, 0, cs->first());
-      SetElementReference(obj, entry, 1, cs->second());
+      SetInternalReference(obj, entry, "1", cs->first());
+      SetInternalReference(obj, entry, "2", cs->second());
     }
   } else if (obj->IsCode() || obj->IsSharedFunctionInfo() || obj->IsScript()) {
     IndexedReferencesExtractor refs_extractor(this, obj, entry);
@@ -2005,6 +2028,16 @@
 }
 
 
+void HeapSnapshotGenerator::ExtractInternalReferences(JSObject* js_obj,
+                                                      HeapEntry* entry) {
+  int length = js_obj->GetInternalFieldCount();
+  for (int i = 0; i < length; ++i) {
+    Object* o = js_obj->GetInternalField(i);
+    SetInternalReference(js_obj, entry, i, o);
+  }
+}
+
+
 void HeapSnapshotGenerator::SetClosureReference(HeapObject* parent_obj,
                                                 HeapEntry* parent_entry,
                                                 String* reference_name,
@@ -2049,13 +2082,31 @@
 }
 
 
+void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
+                                                 HeapEntry* parent_entry,
+                                                 int index,
+                                                 Object* child_obj) {
+  HeapEntry* child_entry = GetEntry(child_obj);
+  if (child_entry != NULL) {
+    filler_->SetNamedReference(HeapGraphEdge::kInternal,
+                               parent_obj,
+                               parent_entry,
+                               collection_->GetName(index),
+                               child_obj,
+                               child_entry);
+  }
+}
+
+
 void HeapSnapshotGenerator::SetPropertyReference(HeapObject* parent_obj,
                                                  HeapEntry* parent_entry,
                                                  String* reference_name,
                                                  Object* child_obj) {
   HeapEntry* child_entry = GetEntry(child_obj);
   if (child_entry != NULL) {
-    filler_->SetNamedReference(HeapGraphEdge::kProperty,
+    HeapGraphEdge::Type type = reference_name->length() > 0 ?
+        HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
+    filler_->SetNamedReference(type,
                                parent_obj,
                                parent_entry,
                                collection_->GetName(reference_name),
@@ -2095,6 +2146,11 @@
 
 HeapSnapshotsDiff* HeapSnapshotsComparator::Compare(HeapSnapshot* snapshot1,
                                                     HeapSnapshot* snapshot2) {
+  snapshot1->ClearPaint();
+  snapshot1->root()->PaintAllReachable();
+  snapshot2->ClearPaint();
+  snapshot2->root()->PaintAllReachable();
+
   List<HeapEntry*>* entries1 = snapshot1->GetSortedEntriesList();
   List<HeapEntry*>* entries2 = snapshot2->GetSortedEntriesList();
   int i = 0, j = 0;
@@ -2103,8 +2159,14 @@
     uint64_t id1 = entries1->at(i)->id();
     uint64_t id2 = entries2->at(j)->id();
     if (id1 == id2) {
-      i++;
-      j++;
+      HeapEntry* entry1 = entries1->at(i++);
+      HeapEntry* entry2 = entries2->at(j++);
+      if (entry1->painted_reachable() != entry2->painted_reachable()) {
+        if (entry1->painted_reachable())
+          deleted_entries.Add(entry1);
+        else
+          added_entries.Add(entry2);
+      }
     } else if (id1 < id2) {
       HeapEntry* entry = entries1->at(i++);
       deleted_entries.Add(entry);
@@ -2122,35 +2184,17 @@
     added_entries.Add(entry);
   }
 
-  snapshot1->ClearPaint();
-  snapshot1->root()->PaintAllReachable();
-  snapshot2->ClearPaint();
-  snapshot2->root()->PaintAllReachable();
-  int reachable_deleted_entries = 0, reachable_added_entries = 0;
-  for (int i = 0; i < deleted_entries.length(); ++i) {
-    HeapEntry* entry = deleted_entries[i];
-    if (entry->painted_reachable()) ++reachable_deleted_entries;
-  }
-  for (int i = 0; i < added_entries.length(); ++i) {
-    HeapEntry* entry = added_entries[i];
-    if (entry->painted_reachable()) ++reachable_added_entries;
-  }
-
   HeapSnapshotsDiff* diff = new HeapSnapshotsDiff(snapshot1, snapshot2);
   diffs_.Add(diff);
-  diff->CreateRoots(reachable_added_entries, reachable_deleted_entries);
+  diff->CreateRoots(added_entries.length(), deleted_entries.length());
 
-  int del_child_index = 0, deleted_entry_index = 1;
   for (int i = 0; i < deleted_entries.length(); ++i) {
     HeapEntry* entry = deleted_entries[i];
-    if (entry->painted_reachable())
-      diff->AddDeletedEntry(del_child_index++, deleted_entry_index++, entry);
+    diff->AddDeletedEntry(i, i + 1, entry);
   }
-  int add_child_index = 0, added_entry_index = 1;
   for (int i = 0; i < added_entries.length(); ++i) {
     HeapEntry* entry = added_entries[i];
-    if (entry->painted_reachable())
-      diff->AddAddedEntry(add_child_index++, added_entry_index++, entry);
+    diff->AddAddedEntry(i, i + 1, entry);
   }
   return diff;
 }
@@ -2358,7 +2402,9 @@
             "," JSON_S("string")
             "," JSON_S("object")
             "," JSON_S("code")
-            "," JSON_S("closure"))
+            "," JSON_S("closure")
+            "," JSON_S("regexp")
+            "," JSON_S("number"))
         "," JSON_S("string")
         "," JSON_S("number")
         "," JSON_S("number")
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 1e949a2..6f63f6a 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -67,6 +67,7 @@
   ~StringsStorage();
 
   const char* GetName(String* name);
+  const char* GetName(int index);
   inline const char* GetFunctionName(String* name);
   inline const char* GetFunctionName(const char* name);
 
@@ -78,6 +79,8 @@
 
   // Mapping of strings by String::Hash to const char* strings.
   HashMap names_;
+  // Mapping from ints to char* strings.
+  List<char*> index_names_;
 
   DISALLOW_COPY_AND_ASSIGN(StringsStorage);
 };
@@ -284,6 +287,9 @@
   const char* GetName(String* name) {
     return function_and_resource_names_.GetName(name);
   }
+  const char* GetName(int args_count) {
+    return function_and_resource_names_.GetName(args_count);
+  }
   CpuProfile* GetProfile(int security_token_id, unsigned uid);
   bool IsLastProfile(const char* title);
 
@@ -302,7 +308,6 @@
   static const int kMaxSimultaneousProfiles = 100;
 
  private:
-  const char* GetName(int args_count);
   const char* GetFunctionName(String* name) {
     return function_and_resource_names_.GetFunctionName(name);
   }
@@ -317,8 +322,6 @@
   }
 
   StringsStorage function_and_resource_names_;
-  // Mapping from args_count (int) to char* strings.
-  List<char*> args_count_names_;
   List<CodeEntry*> code_entries_;
   List<List<CpuProfile*>* > profiles_by_token_;
   // Mapping from profiles' uids to indexes in the second nested list
@@ -502,7 +505,9 @@
     kString = v8::HeapGraphNode::kString,
     kObject = v8::HeapGraphNode::kObject,
     kCode = v8::HeapGraphNode::kCode,
-    kClosure = v8::HeapGraphNode::kClosure
+    kClosure = v8::HeapGraphNode::kClosure,
+    kRegExp = v8::HeapGraphNode::kRegExp,
+    kHeapNumber = v8::HeapGraphNode::kHeapNumber
   };
 
   HeapEntry() { }
@@ -662,7 +667,7 @@
   Type type() { return type_; }
   const char* title() { return title_; }
   unsigned uid() { return uid_; }
-  HeapEntry* root() { return entries_[root_entry_index_]; }
+  HeapEntry* root() { return root_entry_; }
 
   void AllocateEntries(
       int entries_count, int children_count, int retainers_count);
@@ -704,7 +709,7 @@
   Type type_;
   const char* title_;
   unsigned uid_;
-  int root_entry_index_;
+  HeapEntry* root_entry_;
   char* raw_entries_;
   List<HeapEntry*> entries_;
   bool entries_sorted_;
@@ -824,6 +829,7 @@
   HeapSnapshot* GetSnapshot(unsigned uid);
 
   const char* GetName(String* name) { return names_.GetName(name); }
+  const char* GetName(int index) { return names_.GetName(index); }
   const char* GetFunctionName(String* name) {
     return names_.GetFunctionName(name);
   }
@@ -948,6 +954,7 @@
   void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry);
   void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry);
   void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry);
+  void ExtractInternalReferences(JSObject* js_obj, HeapEntry* entry);
   void SetClosureReference(HeapObject* parent_obj,
                            HeapEntry* parent,
                            String* reference_name,
@@ -960,6 +967,10 @@
                             HeapEntry* parent,
                             const char* reference_name,
                             Object* child);
+  void SetInternalReference(HeapObject* parent_obj,
+                            HeapEntry* parent,
+                            int index,
+                            Object* child);
   void SetPropertyReference(HeapObject* parent_obj,
                             HeapEntry* parent,
                             String* reference_name,
diff --git a/src/regexp-macro-assembler-irregexp.cc b/src/regexp-macro-assembler-irregexp.cc
index 90abe91..6fbb14a 100644
--- a/src/regexp-macro-assembler-irregexp.cc
+++ b/src/regexp-macro-assembler-irregexp.cc
@@ -145,6 +145,12 @@
 }
 
 
+void RegExpMacroAssemblerIrregexp::SetCurrentPositionFromEnd(int by) {
+  ASSERT(is_uint24(by));
+  Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
+}
+
+
 void RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) {
   ASSERT(register_index >= 0);
   ASSERT(register_index <= kMaxRegister);
diff --git a/src/regexp-macro-assembler-irregexp.h b/src/regexp-macro-assembler-irregexp.h
index 3ddbc2f..6c9c2eb 100644
--- a/src/regexp-macro-assembler-irregexp.h
+++ b/src/regexp-macro-assembler-irregexp.h
@@ -65,6 +65,7 @@
   virtual void PushRegister(int register_index,
                             StackCheckFlag check_stack_limit);
   virtual void AdvanceRegister(int reg, int by);  // r[reg] += by.
+  virtual void SetCurrentPositionFromEnd(int by);
   virtual void SetRegister(int register_index, int to);
   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
   virtual void ClearRegisters(int reg_from, int reg_to);
diff --git a/src/regexp-macro-assembler-tracer.cc b/src/regexp-macro-assembler-tracer.cc
index c08602e..463c1a8 100644
--- a/src/regexp-macro-assembler-tracer.cc
+++ b/src/regexp-macro-assembler-tracer.cc
@@ -47,8 +47,15 @@
 }
 
 
+// This is used for printing out debugging information.  It makes an integer
+// that is closely related to the address of an object.
+static int LabelToInt(Label* label) {
+  return static_cast<int>(reinterpret_cast<intptr_t>(label));
+}
+
+
 void RegExpMacroAssemblerTracer::Bind(Label* label) {
-  PrintF("label[%08x]: (Bind)\n", label, label);
+  PrintF("label[%08x]: (Bind)\n", LabelToInt(label));
   assembler_->Bind(label);
 }
 
@@ -60,7 +67,7 @@
 
 
 void RegExpMacroAssemblerTracer::CheckGreedyLoop(Label* label) {
-  PrintF(" CheckGreedyLoop(label[%08x]);\n\n", label);
+  PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label));
   assembler_->CheckGreedyLoop(label);
 }
 
@@ -84,14 +91,13 @@
 
 
 void RegExpMacroAssemblerTracer::GoTo(Label* label) {
-  PrintF(" GoTo(label[%08x]);\n\n", label);
+  PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label));
   assembler_->GoTo(label);
 }
 
 
 void RegExpMacroAssemblerTracer::PushBacktrack(Label* label) {
-  PrintF(" PushBacktrack(label[%08x]);\n",
-         label);
+  PrintF(" PushBacktrack(label[%08x]);\n", LabelToInt(label));
   assembler_->PushBacktrack(label);
 }
 
@@ -130,6 +136,12 @@
 }
 
 
+void RegExpMacroAssemblerTracer::SetCurrentPositionFromEnd(int by) {
+  PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by);
+  assembler_->SetCurrentPositionFromEnd(by);
+}
+
+
 void RegExpMacroAssemblerTracer::SetRegister(int register_index, int to) {
   PrintF(" SetRegister(register=%d, to=%d);\n", register_index, to);
   assembler_->SetRegister(register_index, to);
@@ -176,7 +188,7 @@
   const char* check_msg = check_bounds ? "" : " (unchecked)";
   PrintF(" LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars));\n",
          cp_offset,
-         on_end_of_input,
+         LabelToInt(on_end_of_input),
          check_msg,
          characters);
   assembler_->LoadCurrentCharacter(cp_offset,
@@ -187,39 +199,43 @@
 
 
 void RegExpMacroAssemblerTracer::CheckCharacterLT(uc16 limit, Label* on_less) {
-  PrintF(" CheckCharacterLT(c='u%04x', label[%08x]);\n", limit, on_less);
+  PrintF(" CheckCharacterLT(c='u%04x', label[%08x]);\n",
+         limit, LabelToInt(on_less));
   assembler_->CheckCharacterLT(limit, on_less);
 }
 
 
 void RegExpMacroAssemblerTracer::CheckCharacterGT(uc16 limit,
                                                   Label* on_greater) {
-  PrintF(" CheckCharacterGT(c='u%04x', label[%08x]);\n", limit, on_greater);
+  PrintF(" CheckCharacterGT(c='u%04x', label[%08x]);\n",
+         limit, LabelToInt(on_greater));
   assembler_->CheckCharacterGT(limit, on_greater);
 }
 
 
 void RegExpMacroAssemblerTracer::CheckCharacter(uint32_t c, Label* on_equal) {
-  PrintF(" CheckCharacter(c='u%04x', label[%08x]);\n", c, on_equal);
+  PrintF(" CheckCharacter(c='u%04x', label[%08x]);\n",
+         c, LabelToInt(on_equal));
   assembler_->CheckCharacter(c, on_equal);
 }
 
 
 void RegExpMacroAssemblerTracer::CheckAtStart(Label* on_at_start) {
-  PrintF(" CheckAtStart(label[%08x]);\n", on_at_start);
+  PrintF(" CheckAtStart(label[%08x]);\n", LabelToInt(on_at_start));
   assembler_->CheckAtStart(on_at_start);
 }
 
 
 void RegExpMacroAssemblerTracer::CheckNotAtStart(Label* on_not_at_start) {
-  PrintF(" CheckNotAtStart(label[%08x]);\n", on_not_at_start);
+  PrintF(" CheckNotAtStart(label[%08x]);\n", LabelToInt(on_not_at_start));
   assembler_->CheckNotAtStart(on_not_at_start);
 }
 
 
 void RegExpMacroAssemblerTracer::CheckNotCharacter(uint32_t c,
                                                    Label* on_not_equal) {
-  PrintF(" CheckNotCharacter(c='u%04x', label[%08x]);\n", c, on_not_equal);
+  PrintF(" CheckNotCharacter(c='u%04x', label[%08x]);\n",
+         c, LabelToInt(on_not_equal));
   assembler_->CheckNotCharacter(c, on_not_equal);
 }
 
@@ -231,7 +247,7 @@
   PrintF(" CheckCharacterAfterAnd(c='u%04x', mask=0x%04x, label[%08x]);\n",
          c,
          mask,
-         on_equal);
+         LabelToInt(on_equal));
   assembler_->CheckCharacterAfterAnd(c, mask, on_equal);
 }
 
@@ -243,7 +259,7 @@
   PrintF(" CheckNotCharacterAfterAnd(c='u%04x', mask=0x%04x, label[%08x]);\n",
          c,
          mask,
-         on_not_equal);
+         LabelToInt(on_not_equal));
   assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal);
 }
 
@@ -258,7 +274,7 @@
          c,
          minus,
          mask,
-         on_not_equal);
+         LabelToInt(on_not_equal));
   assembler_->CheckNotCharacterAfterMinusAnd(c, minus, mask, on_not_equal);
 }
 
@@ -266,7 +282,7 @@
 void RegExpMacroAssemblerTracer::CheckNotBackReference(int start_reg,
                                                        Label* on_no_match) {
   PrintF(" CheckNotBackReference(register=%d, label[%08x]);\n", start_reg,
-         on_no_match);
+         LabelToInt(on_no_match));
   assembler_->CheckNotBackReference(start_reg, on_no_match);
 }
 
@@ -275,7 +291,7 @@
     int start_reg,
     Label* on_no_match) {
   PrintF(" CheckNotBackReferenceIgnoreCase(register=%d, label[%08x]);\n",
-         start_reg, on_no_match);
+         start_reg, LabelToInt(on_no_match));
   assembler_->CheckNotBackReferenceIgnoreCase(start_reg, on_no_match);
 }
 
@@ -286,7 +302,7 @@
   PrintF(" CheckNotRegistersEqual(reg1=%d, reg2=%d, label[%08x]);\n",
          reg1,
          reg2,
-         on_not_equal);
+         LabelToInt(on_not_equal));
   assembler_->CheckNotRegistersEqual(reg1, reg2, on_not_equal);
 }
 
@@ -300,7 +316,8 @@
   for (int i = 0; i < str.length(); i++) {
     PrintF("u%04x", str[i]);
   }
-  PrintF("\", cp_offset=%d, label[%08x])\n", cp_offset, on_failure);
+  PrintF("\", cp_offset=%d, label[%08x])\n",
+         cp_offset, LabelToInt(on_failure));
   assembler_->CheckCharacters(str, cp_offset, on_failure, check_end_of_string);
 }
 
@@ -312,7 +329,7 @@
                                                           on_no_match);
   PrintF(" CheckSpecialCharacterClass(type='%c', label[%08x]): %s;\n",
          type,
-         on_no_match,
+         LabelToInt(on_no_match),
          supported ? "true" : "false");
   return supported;
 }
@@ -321,7 +338,7 @@
 void RegExpMacroAssemblerTracer::IfRegisterLT(int register_index,
                                               int comparand, Label* if_lt) {
   PrintF(" IfRegisterLT(register=%d, number=%d, label[%08x]);\n",
-         register_index, comparand, if_lt);
+         register_index, comparand, LabelToInt(if_lt));
   assembler_->IfRegisterLT(register_index, comparand, if_lt);
 }
 
@@ -329,7 +346,7 @@
 void RegExpMacroAssemblerTracer::IfRegisterEqPos(int register_index,
                                                  Label* if_eq) {
   PrintF(" IfRegisterEqPos(register=%d, label[%08x]);\n",
-         register_index, if_eq);
+         register_index, LabelToInt(if_eq));
   assembler_->IfRegisterEqPos(register_index, if_eq);
 }
 
@@ -337,7 +354,7 @@
 void RegExpMacroAssemblerTracer::IfRegisterGE(int register_index,
                                               int comparand, Label* if_ge) {
   PrintF(" IfRegisterGE(register=%d, number=%d, label[%08x]);\n",
-         register_index, comparand, if_ge);
+         register_index, comparand, LabelToInt(if_ge));
   assembler_->IfRegisterGE(register_index, comparand, if_ge);
 }
 
diff --git a/src/regexp-macro-assembler-tracer.h b/src/regexp-macro-assembler-tracer.h
index 9608f9e..6a8f4d4 100644
--- a/src/regexp-macro-assembler-tracer.h
+++ b/src/regexp-macro-assembler-tracer.h
@@ -89,6 +89,7 @@
                             StackCheckFlag check_stack_limit);
   virtual void ReadCurrentPositionFromRegister(int reg);
   virtual void ReadStackPointerFromRegister(int reg);
+  virtual void SetCurrentPositionFromEnd(int by);
   virtual void SetRegister(int register_index, int to);
   virtual void Succeed();
   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
diff --git a/src/regexp-macro-assembler.h b/src/regexp-macro-assembler.h
index 652b690..dc3bd82 100644
--- a/src/regexp-macro-assembler.h
+++ b/src/regexp-macro-assembler.h
@@ -155,6 +155,7 @@
                             StackCheckFlag check_stack_limit) = 0;
   virtual void ReadCurrentPositionFromRegister(int reg) = 0;
   virtual void ReadStackPointerFromRegister(int reg) = 0;
+  virtual void SetCurrentPositionFromEnd(int by) = 0;
   virtual void SetRegister(int register_index, int to) = 0;
   virtual void Succeed() = 0;
   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset) = 0;
diff --git a/src/regexp.js b/src/regexp.js
index faa525d..51f4b09 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -126,11 +126,11 @@
   this.regExp = 0;
   this.subject = 0;
   this.replaceString = 0;
-  this.lastIndex = 0;  // Also used for splitLimit when type is "split"
   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".
 }
 
 
@@ -181,22 +181,30 @@
   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(cache.lastIndex, this.lastIndex) &&
+      %_ObjectEquals(0, lastIndex) &&
       %_IsRegExpEquivalent(cache.regExp, this) &&
       %_ObjectEquals(cache.subject, string)) {
     if (cache.answerSaved) {
-      // If this regexp is not global, cache.lastIndex is zero, so we only get 
-      // here if this.lastIndex is zero, and resulting this.lastIndex
-      // must be zero too, so no change is necessary.
-      if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1];
+      // 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) {
+  if (%_ArgumentsLength() === 0) {
     var regExpInput = LAST_INPUT(lastMatchInfo);
     if (IS_UNDEFINED(regExpInput)) {
       throw MakeError('no_input_to_regexp', [this]);
@@ -209,41 +217,48 @@
   } else {
     s = ToString(string);
   }
-  var lastIndex = this.lastIndex;
+  var global = this.global;
 
-  var i = this.global ? TO_INTEGER(lastIndex) : 0;
-
-  if (i < 0 || i > s.length) {
-    this.lastIndex = 0;
-    return null;
+  // 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);
+  if (global) {
+    if (i < 0 || i > s.length) {
+      this.lastIndex = 0;
+      return null;
+    }
+  } else {
+    i = 0;
   }
 
   %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
   // matchIndices is either null or the lastMatchInfo array.
   var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
 
-  if (matchIndices == null) {
-    if (this.global) {
+  if (matchIndices === null) {
+    if (global) {
+      // Cache negative result only if initial lastIndex was zero.
       this.lastIndex = 0;
-      if (lastIndex != 0) return matchIndices;
+      if (lastIndex !== 0) return matchIndices;
     }
-    cache.lastIndex = lastIndex;
     cache.regExp = this;
-    cache.subject = s;
-    cache.answer = matchIndices;  // Null.
+    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.
   }
+
+  // Successful match.
   lastMatchInfoOverride = null;
   var result = BuildResultFromMatchInfo(matchIndices, s);
 
-  if (this.global) {
+  if (global) {
+    // Don't cache positive results for global regexps.
     this.lastIndex = lastMatchInfo[CAPTURE1];
   } else {
     cache.regExp = this;
     cache.subject = s;
-    cache.lastIndex = lastIndex;
     if (saveAnswer) cache.answer = %_RegExpCloneResult(result);
     cache.answerSaved = saveAnswer;
     cache.type = 'exec';
@@ -273,32 +288,49 @@
     }
     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;
-  var cache = regExpCache;
-  if (%_ObjectEquals(cache.type, 'test') &&
-      %_IsRegExpEquivalent(cache.regExp, this) &&
-      %_ObjectEquals(cache.subject, string) &&
-      %_ObjectEquals(cache.lastIndex, lastIndex)) {
-    // If this regexp is not global, cache.lastIndex is zero, so we only get 
-    // here if this.lastIndex is zero, and resulting this.lastIndex
-    // must be zero too, so no change is necessary.
-    if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1];
-    return cache.answer;
+  // 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);
+  if (global) {
+    if (i < 0 || i > length) {
+      this.lastIndex = 0;
+      return false;
+    }
+  } else {
+    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 '?'
-  if (%_StringCharCodeAt(this.source,0) == 46 && // '.'
-      %_StringCharCodeAt(this.source,1) == 42 && // '*'
-      %_StringCharCodeAt(this.source,2) != 63) { // '?'
+  if (%_StringCharCodeAt(this.source, 0) == 46 &&  // '.'
+      %_StringCharCodeAt(this.source, 1) == 42 &&  // '*'
+      %_StringCharCodeAt(this.source, 2) != 63) {  // '?'
     if (!%_ObjectEquals(regexp_key, this)) {
       regexp_key = this;
       regexp_val = new $RegExp(this.source.substring(2, this.source.length),
@@ -309,33 +341,28 @@
     if (!regexp_val.test(s)) return false;
   }
 
-  var length = s.length;
-  var i = this.global ? TO_INTEGER(lastIndex) : 0;
-
-  cache.type = 'test';
-  cache.regExp = this;
-  cache.subject = s;
-  cache.lastIndex = i;
-
-  if (i < 0 || i > length) {
-    this.lastIndex = 0;
-    cache.answer = false;
-    return false;
-  }
-
   %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
   // matchIndices is either null or the lastMatchInfo array.
   var matchIndices = %_RegExpExec(this, s, i, lastMatchInfo);
 
-  if (matchIndices == null) {
-    if (this.global) this.lastIndex = 0;
-    cache.answer = false;
-    return false;
+  var result = (matchIndices !== null);
+  if (result) {
+    lastMatchInfoOverride = null;
   }
-  lastMatchInfoOverride = null;
-  if (this.global) this.lastIndex = lastMatchInfo[CAPTURE1];
-  cache.answer = true;
-  return true;
+  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;
 }
 
 
@@ -345,12 +372,9 @@
   // ecma_2/RegExp/properties-001.js.
   var src = this.source ? this.source : '(?:)';
   var result = '/' + src + '/';
-  if (this.global)
-    result += 'g';
-  if (this.ignoreCase)
-    result += 'i';
-  if (this.multiline)
-    result += 'm';
+  if (this.global) result += 'g';
+  if (this.ignoreCase) result += 'i';
+  if (this.multiline) result += 'm';
   return result;
 }
 
diff --git a/src/rewriter.cc b/src/rewriter.cc
index f253ec5..b6f8240 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -27,10 +27,12 @@
 
 #include "v8.h"
 
-#include "ast.h"
-#include "scopes.h"
 #include "rewriter.h"
 
+#include "ast.h"
+#include "compiler.h"
+#include "scopes.h"
+
 namespace v8 {
 namespace internal {
 
@@ -986,34 +988,40 @@
 }
 
 
-bool Rewriter::Process(FunctionLiteral* function) {
-  HistogramTimerScope timer(&Counters::rewriting);
+// Assumes code has been parsed and scopes hve been analyzed.  Mutates the
+// AST, so the AST should not continue to be used in the case of failure.
+bool Rewriter::Rewrite(CompilationInfo* info) {
+  FunctionLiteral* function = info->function();
+  ASSERT(function != NULL);
   Scope* scope = function->scope();
+  ASSERT(scope != NULL);
   if (scope->is_function_scope()) return true;
 
   ZoneList<Statement*>* body = function->body();
-  if (body->is_empty()) return true;
+  if (!body->is_empty()) {
+    VariableProxy* result = scope->NewTemporary(Factory::result_symbol());
+    Processor processor(result);
+    processor.Process(body);
+    if (processor.HasStackOverflow()) return false;
 
-  VariableProxy* result = scope->NewTemporary(Factory::result_symbol());
-  Processor processor(result);
-  processor.Process(body);
-  if (processor.HasStackOverflow()) return false;
+    if (processor.result_assigned()) body->Add(new ReturnStatement(result));
+  }
 
-  if (processor.result_assigned()) body->Add(new ReturnStatement(result));
   return true;
 }
 
 
-bool Rewriter::Optimize(FunctionLiteral* function) {
-  ZoneList<Statement*>* body = function->body();
+// Assumes code has been parsed and scopes have been analyzed.  Mutates the
+// AST, so the AST should not continue to be used in the case of failure.
+bool Rewriter::Analyze(CompilationInfo* info) {
+  FunctionLiteral* function = info->function();
+  ASSERT(function != NULL && function->scope() != NULL);
 
+  ZoneList<Statement*>* body = function->body();
   if (FLAG_optimize_ast && !body->is_empty()) {
-    HistogramTimerScope timer(&Counters::ast_optimization);
     AstOptimizer optimizer;
     optimizer.Optimize(body);
-    if (optimizer.HasStackOverflow()) {
-      return false;
-    }
+    if (optimizer.HasStackOverflow()) return false;
   }
   return true;
 }
diff --git a/src/rewriter.h b/src/rewriter.h
index 8943e75..62e1b7f 100644
--- a/src/rewriter.h
+++ b/src/rewriter.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -31,21 +31,26 @@
 namespace v8 {
 namespace internal {
 
-
-// Currently, the rewriter takes function literals (only top-level)
-// and rewrites them to return the value of the last expression in
-// them.
-//
-// The rewriter adds a (hidden) variable, called .result, to the
-// activation, and tries to figure out where it needs to store into
-// this variable. If the variable is ever used, we conclude by adding
-// a return statement that returns the variable to the body of the
-// given function.
+class CompilationInfo;
 
 class Rewriter {
  public:
-  static bool Process(FunctionLiteral* function);
-  static bool Optimize(FunctionLiteral* function);
+  // Rewrite top-level code (ECMA 262 "programs") so as to conservatively
+  // include an assignment of the value of the last statement in the code to
+  // a compiler-generated temporary variable wherever needed.
+  //
+  // Assumes code has been parsed and scopes have been analyzed.  Mutates the
+  // AST, so the AST should not continue to be used in the case of failure.
+  static bool Rewrite(CompilationInfo* info);
+
+  // Perform a suite of simple non-iterative analyses of the AST.  Mark
+  // expressions that are likely smis, expressions without side effects,
+  // expressions whose value will be converted to Int32, and expressions in a
+  // context where +0 and -0 are treated the same.
+  //
+  // Assumes code has been parsed and scopes have been analyzed.  Mutates the
+  // AST, so the AST should not continue to be used in the case of failure.
+  static bool Analyze(CompilationInfo* info);
 };
 
 
diff --git a/src/runtime.cc b/src/runtime.cc
index 8d58db7..9a604a0 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -2624,15 +2624,15 @@
   if (seq_pat->IsAsciiRepresentation()) {
     Vector<const char> pat_vector = seq_pat->ToAsciiVector();
     if (seq_sub->IsAsciiRepresentation()) {
-      return StringSearch(seq_sub->ToAsciiVector(), pat_vector, start_index);
+      return SearchString(seq_sub->ToAsciiVector(), pat_vector, start_index);
     }
-    return StringSearch(seq_sub->ToUC16Vector(), pat_vector, start_index);
+    return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index);
   }
   Vector<const uc16> pat_vector = seq_pat->ToUC16Vector();
   if (seq_sub->IsAsciiRepresentation()) {
-    return StringSearch(seq_sub->ToAsciiVector(), pat_vector, start_index);
+    return SearchString(seq_sub->ToAsciiVector(), pat_vector, start_index);
   }
-  return StringSearch(seq_sub->ToUC16Vector(), pat_vector, start_index);
+  return SearchString(seq_sub->ToUC16Vector(), pat_vector, start_index);
 }
 
 
@@ -2889,67 +2889,39 @@
 }
 
 
-template <typename schar, typename pchar>
-static bool SearchStringMultiple(Vector<schar> subject,
-                                 String* pattern,
-                                 Vector<pchar> pattern_string,
+template <typename SubjectChar, typename PatternChar>
+static bool SearchStringMultiple(Vector<const SubjectChar> subject,
+                                 Vector<const PatternChar> pattern,
+                                 String* pattern_string,
                                  FixedArrayBuilder* builder,
                                  int* match_pos) {
   int pos = *match_pos;
   int subject_length = subject.length();
-  int pattern_length = pattern_string.length();
+  int pattern_length = pattern.length();
   int max_search_start = subject_length - pattern_length;
-  bool is_ascii = (sizeof(schar) == 1);
-  StringSearchStrategy strategy =
-      InitializeStringSearch(pattern_string, is_ascii);
-  switch (strategy) {
-    case SEARCH_FAIL: break;
-    case SEARCH_SHORT:
-      while (pos <= max_search_start) {
-        if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
-          *match_pos = pos;
-          return false;
-        }
-        // Position of end of previous match.
-        int match_end = pos + pattern_length;
-        int new_pos = SimpleIndexOf(subject, pattern_string, match_end);
-        if (new_pos >= 0) {
-          // A match.
-          if (new_pos > match_end) {
-            ReplacementStringBuilder::AddSubjectSlice(builder,
-                                                      match_end,
-                                                      new_pos);
-          }
-          pos = new_pos;
-          builder->Add(pattern);
-        } else {
-          break;
-        }
+  StringSearch<PatternChar, SubjectChar> search(pattern);
+  while (pos <= max_search_start) {
+    if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
+      *match_pos = pos;
+      return false;
+    }
+    // Position of end of previous match.
+    int match_end = pos + pattern_length;
+    int new_pos = search.Search(subject, match_end);
+    if (new_pos >= 0) {
+      // A match.
+      if (new_pos > match_end) {
+        ReplacementStringBuilder::AddSubjectSlice(builder,
+            match_end,
+            new_pos);
       }
+      pos = new_pos;
+      builder->Add(pattern_string);
+    } else {
       break;
-    case SEARCH_LONG:
-      while (pos  <= max_search_start) {
-        if (!builder->HasCapacity(kMaxBuilderEntriesPerRegExpMatch)) {
-          *match_pos = pos;
-          return false;
-        }
-        int match_end = pos + pattern_length;
-        int new_pos = ComplexIndexOf(subject, pattern_string, match_end);
-        if (new_pos >= 0) {
-          // A match has been found.
-          if (new_pos > match_end) {
-            ReplacementStringBuilder::AddSubjectSlice(builder,
-                                                      match_end,
-                                                      new_pos);
-          }
-          pos = new_pos;
-          builder->Add(pattern);
-        } else {
-         break;
-        }
-      }
-      break;
+    }
   }
+
   if (pos < max_search_start) {
     ReplacementStringBuilder::AddSubjectSlice(builder,
                                               pos + pattern_length,
@@ -2977,14 +2949,14 @@
       Vector<const char> subject_vector = subject->ToAsciiVector();
       if (pattern->IsAsciiRepresentation()) {
         if (SearchStringMultiple(subject_vector,
-                                 *pattern,
                                  pattern->ToAsciiVector(),
+                                 *pattern,
                                  builder,
                                  &match_pos)) break;
       } else {
         if (SearchStringMultiple(subject_vector,
-                                 *pattern,
                                  pattern->ToUC16Vector(),
+                                 *pattern,
                                  builder,
                                  &match_pos)) break;
       }
@@ -2992,14 +2964,14 @@
       Vector<const uc16> subject_vector = subject->ToUC16Vector();
       if (pattern->IsAsciiRepresentation()) {
         if (SearchStringMultiple(subject_vector,
-                                 *pattern,
                                  pattern->ToAsciiVector(),
+                                 *pattern,
                                  builder,
                                  &match_pos)) break;
       } else {
         if (SearchStringMultiple(subject_vector,
-                                 *pattern,
                                  pattern->ToUC16Vector(),
+                                 *pattern,
                                  builder,
                                  &match_pos)) break;
       }
@@ -4781,51 +4753,23 @@
 }
 
 
-// Define storage for buffers declared in header file.
-// TODO(lrn): Remove these when rewriting search code.
-int BMBuffers::bad_char_occurrence[kBMAlphabetSize];
-BMGoodSuffixBuffers BMBuffers::bmgs_buffers;
-
-
-template <typename schar, typename pchar>
-void FindStringIndices(Vector<const schar> subject,
-                       Vector<const pchar> pattern,
+template <typename SubjectChar, typename PatternChar>
+void FindStringIndices(Vector<const SubjectChar> subject,
+                       Vector<const PatternChar> pattern,
                        ZoneList<int>* indices,
                        unsigned int limit) {
   ASSERT(limit > 0);
   // Collect indices of pattern in subject, and the end-of-string index.
   // Stop after finding at most limit values.
-  StringSearchStrategy strategy =
-      InitializeStringSearch(pattern, sizeof(schar) == 1);
-  switch (strategy) {
-    case SEARCH_FAIL: return;
-    case SEARCH_SHORT: {
-      int pattern_length = pattern.length();
-      int index = 0;
-      while (limit > 0) {
-        index = SimpleIndexOf(subject, pattern, index);
-        if (index < 0) return;
-        indices->Add(index);
-        index += pattern_length;
-        limit--;
-      }
-      return;
-    }
-    case SEARCH_LONG: {
-      int pattern_length = pattern.length();
-      int index = 0;
-      while (limit > 0) {
-        index = ComplexIndexOf(subject, pattern, index);
-        if (index < 0) return;
-        indices->Add(index);
-        index += pattern_length;
-        limit--;
-      }
-      return;
-    }
-    default:
-      UNREACHABLE();
-      return;
+  StringSearch<PatternChar, SubjectChar> search(pattern);
+  int pattern_length = pattern.length();
+  int index = 0;
+  while (limit > 0) {
+    index = search.Search(subject, index);
+    if (index < 0) return;
+    indices->Add(index);
+    index += pattern_length;
+    limit--;
   }
 }
 
@@ -6430,7 +6374,7 @@
   // this means that things called through constructors are never known to
   // be in loops.  We compile them as if they are in loops here just in case.
   ASSERT(!function->is_compiled());
-  if (!CompileLazyInLoop(function, Handle<Object>::null(), KEEP_EXCEPTION)) {
+  if (!CompileLazyInLoop(function, KEEP_EXCEPTION)) {
     return Failure::Exception();
   }
 
@@ -6759,7 +6703,7 @@
 
 
 static Object* Runtime_StackGuard(Arguments args) {
-  ASSERT(args.length() == 1);
+  ASSERT(args.length() == 0);
 
   // First check if this is a real stack overflow.
   if (StackGuard::IsStackOverflow()) {
@@ -6801,7 +6745,7 @@
   } else if (obj->IsFalse()) {
     PrintF("<false>");
   } else {
-    PrintF("%p", obj);
+    PrintF("%p", reinterpret_cast<void*>(obj));
   }
 }
 
@@ -7253,15 +7197,15 @@
             Handle<Smi> e(Smi::FromInt(static_cast<int>(val)));
             visitor->visit(j, e);
           } else {
-            Handle<Object> e(
-                Heap::AllocateHeapNumber(static_cast<ElementType>(val)));
+            Handle<Object> e =
+                Factory::NewNumber(static_cast<ElementType>(val));
             visitor->visit(j, e);
           }
         }
       }
     } else {
       for (uint32_t j = 0; j < len; j++) {
-        Handle<Object> e(Heap::AllocateHeapNumber(array->get(j)));
+        Handle<Object> e = Factory::NewNumber(array->get(j));
         visitor->visit(j, e);
       }
     }
@@ -10209,7 +10153,7 @@
   if (failure->IsRetryAfterGC()) {
     // Try to do a garbage collection; ignore it if it fails. The C
     // entry stub will throw an out-of-memory exception in that case.
-    Heap::CollectGarbage(failure->requested(), failure->allocation_space());
+    Heap::CollectGarbage(failure->allocation_space());
   } else {
     // Handle last resort GC and make sure to allow future allocations
     // to grow the heap without causing GCs (if possible).
diff --git a/src/runtime.h b/src/runtime.h
index 19f4144..2cd95c4 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -267,7 +267,7 @@
   F(Throw, 1, 1) \
   F(ReThrow, 1, 1) \
   F(ThrowReferenceError, 1, 1) \
-  F(StackGuard, 1, 1) \
+  F(StackGuard, 0, 1) \
   F(PromoteScheduledException, 0, 1) \
   \
   /* Contexts */ \
diff --git a/src/scopes.cc b/src/scopes.cc
index c4436fe..5ff250f 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -27,9 +27,12 @@
 
 #include "v8.h"
 
+#include "scopes.h"
+
+#include "bootstrapper.h"
+#include "compiler.h"
 #include "prettyprinter.h"
 #include "scopeinfo.h"
-#include "scopes.h"
 
 namespace v8 {
 namespace internal {
@@ -168,6 +171,25 @@
 }
 
 
+bool Scope::Analyze(CompilationInfo* info) {
+  ASSERT(info->function() != NULL);
+  Scope* top = info->function()->scope();
+  while (top->outer_scope() != NULL) top = top->outer_scope();
+  top->AllocateVariables(info->calling_context());
+
+#ifdef DEBUG
+  if (Bootstrapper::IsActive()
+          ? FLAG_print_builtin_scopes
+          : FLAG_print_scopes) {
+    info->function()->scope()->Print();
+  }
+#endif
+
+  info->SetScope(info->function()->scope());
+  return true;  // Can not fail.
+}
+
+
 void Scope::Initialize(bool inside_with) {
   // Add this scope as a new inner scope of the outer scope.
   if (outer_scope_ != NULL) {
@@ -201,7 +223,6 @@
 }
 
 
-
 Variable* Scope::LocalLookup(Handle<String> name) {
   return variables_.Lookup(name);
 }
diff --git a/src/scopes.h b/src/scopes.h
index 68cf5e5..526c3d3 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -34,6 +34,8 @@
 namespace v8 {
 namespace internal {
 
+class CompilationInfo;
+
 
 // A hash map to support fast variable declaration and lookup.
 class VariableMap: public HashMap {
@@ -97,11 +99,20 @@
 
   virtual ~Scope() { }
 
+  // Compute top scope and allocate variables. For lazy compilation the top
+  // scope only contains the single lazily compiled function, so this
+  // doesn't re-allocate variables repeatedly.
+  static bool Analyze(CompilationInfo* info);
+
   // The scope name is only used for printing/debugging.
   void SetScopeName(Handle<String> scope_name)  { scope_name_ = scope_name; }
 
-  void Initialize(bool inside_with);
+  virtual void Initialize(bool inside_with);
 
+  // Called just before leaving a scope.
+  virtual void Leave() {
+    // No cleanup or fixup necessary.
+  }
 
   // ---------------------------------------------------------------------------
   // Declarations
@@ -272,7 +283,7 @@
   bool AllowsLazyCompilation() const;
 
   // True if the outer context of this scope is always the global context.
-  bool HasTrivialOuterContext() const;
+  virtual bool HasTrivialOuterContext() const;
 
   // The number of contexts between this and scope; zero if this == scope.
   int ContextChainLength(Scope* scope);
@@ -378,20 +389,53 @@
 };
 
 
+// Scope used during pre-parsing.
 class DummyScope : public Scope {
  public:
-  DummyScope() : Scope(GLOBAL_SCOPE) {
+  DummyScope()
+      : Scope(GLOBAL_SCOPE),
+        nesting_level_(1),  // Allows us to Leave the initial scope.
+        inside_with_level_(kNotInsideWith) {
     outer_scope_ = this;
+    scope_inside_with_ = false;
+  }
+
+  virtual void Initialize(bool inside_with) {
+    nesting_level_++;
+    if (inside_with && inside_with_level_ == kNotInsideWith) {
+      inside_with_level_ = nesting_level_;
+    }
+    ASSERT(inside_with_level_ <= nesting_level_);
+  }
+
+  virtual void Leave() {
+    nesting_level_--;
+    ASSERT(nesting_level_ >= 0);
+    if (nesting_level_ < inside_with_level_) {
+      inside_with_level_ = kNotInsideWith;
+    }
+    ASSERT(inside_with_level_ <= nesting_level_);
   }
 
   virtual Variable* Lookup(Handle<String> name)  { return NULL; }
-  virtual Variable* Declare(Handle<String> name, Variable::Mode mode) {
-    return NULL;
-  }
+
   virtual VariableProxy* NewUnresolved(Handle<String> name, bool inside_with) {
     return NULL;
   }
+
   virtual VariableProxy* NewTemporary(Handle<String> name)  { return NULL; }
+
+  virtual bool HasTrivialOuterContext() const {
+    return (nesting_level_ == 0 || inside_with_level_ <= 0);
+  }
+
+ private:
+  static const int kNotInsideWith = -1;
+  // Number of surrounding scopes of the current scope.
+  int nesting_level_;
+  // Nesting level of outermost scope that is contained in a with statement,
+  // or kNotInsideWith if there are no with's around the current scope.
+  int inside_with_level_;
 };
 
 
diff --git a/src/serialize.cc b/src/serialize.cc
index cde7577..ccba737 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -500,7 +500,7 @@
 
 
 ExternalReferenceDecoder::ExternalReferenceDecoder()
-  : encodings_(NewArray<Address*>(kTypeCodeCount)) {
+    : encodings_(NewArray<Address*>(kTypeCodeCount)) {
   ExternalReferenceTable* external_references =
       ExternalReferenceTable::instance();
   for (int type = kFirstTypeCode; type < kTypeCodeCount; ++type) {
@@ -619,6 +619,8 @@
   external_reference_decoder_ = new ExternalReferenceDecoder();
   Heap::IterateStrongRoots(this, VISIT_ONLY_STRONG);
   Heap::IterateWeakRoots(this, VISIT_ALL);
+
+  Heap::set_global_contexts_list(Heap::undefined_value());
 }
 
 
diff --git a/src/spaces-inl.h b/src/spaces-inl.h
index fbb2673..8a0dd07 100644
--- a/src/spaces-inl.h
+++ b/src/spaces-inl.h
@@ -407,8 +407,7 @@
 
 bool PagedSpace::Contains(Address addr) {
   Page* p = Page::FromAddress(addr);
-  ASSERT(p->is_valid());
-
+  if (!p->is_valid()) return false;
   return MemoryAllocator::IsPageInSpace(p, this);
 }
 
@@ -440,7 +439,7 @@
   object = SlowAllocateRaw(size_in_bytes);
   if (object != NULL) return object;
 
-  return Failure::RetryAfterGC(size_in_bytes, identity());
+  return Failure::RetryAfterGC(identity());
 }
 
 
@@ -454,7 +453,7 @@
   object = SlowMCAllocateRaw(size_in_bytes);
   if (object != NULL) return object;
 
-  return Failure::RetryAfterGC(size_in_bytes, identity());
+  return Failure::RetryAfterGC(identity());
 }
 
 
@@ -475,7 +474,7 @@
 Object* NewSpace::AllocateRawInternal(int size_in_bytes,
                                       AllocationInfo* alloc_info) {
   Address new_top = alloc_info->top + size_in_bytes;
-  if (new_top > alloc_info->limit) return Failure::RetryAfterGC(size_in_bytes);
+  if (new_top > alloc_info->limit) return Failure::RetryAfterGC();
 
   Object* obj = HeapObject::FromAddress(alloc_info->top);
   alloc_info->top = new_top;
diff --git a/src/spaces.cc b/src/spaces.cc
index 3d2d42f..5bdbcc7 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -270,9 +270,9 @@
 // -----------------------------------------------------------------------------
 // MemoryAllocator
 //
-int MemoryAllocator::capacity_   = 0;
-int MemoryAllocator::size_       = 0;
-int MemoryAllocator::size_executable_ = 0;
+intptr_t MemoryAllocator::capacity_   = 0;
+intptr_t MemoryAllocator::size_       = 0;
+intptr_t MemoryAllocator::size_executable_ = 0;
 
 List<MemoryAllocator::MemoryAllocationCallbackRegistration>
   MemoryAllocator::memory_allocation_callbacks_;
@@ -302,7 +302,7 @@
 }
 
 
-bool MemoryAllocator::Setup(int capacity) {
+bool MemoryAllocator::Setup(intptr_t capacity) {
   capacity_ = RoundUp(capacity, Page::kPageSize);
 
   // Over-estimate the size of chunks_ array.  It assumes the expansion of old
@@ -314,7 +314,8 @@
   //
   // Reserve two chunk ids for semispaces, one for map space, one for old
   // space, and one for code space.
-  max_nof_chunks_ = (capacity_ / (kChunkSize - Page::kPageSize)) + 5;
+  max_nof_chunks_ =
+      static_cast<int>((capacity_ / (kChunkSize - Page::kPageSize))) + 5;
   if (max_nof_chunks_ > kMaxNofChunks) return false;
 
   size_ = 0;
@@ -691,7 +692,9 @@
 #ifdef DEBUG
 void MemoryAllocator::ReportStatistics() {
   float pct = static_cast<float>(capacity_ - size_) / capacity_;
-  PrintF("  capacity: %d, used: %d, available: %%%d\n\n",
+  PrintF("  capacity: %" V8_PTR_PREFIX "d"
+             ", used: %" V8_PTR_PREFIX "d"
+             ", available: %%%d\n\n",
          capacity_, size_, static_cast<int>(pct*100));
 }
 #endif
@@ -769,7 +772,7 @@
 // -----------------------------------------------------------------------------
 // PagedSpace implementation
 
-PagedSpace::PagedSpace(int max_capacity,
+PagedSpace::PagedSpace(intptr_t max_capacity,
                        AllocationSpace id,
                        Executability executable)
     : Space(id, executable) {
@@ -797,8 +800,9 @@
                                                Page::kPageSize * pages_in_chunk,
                                                this, &num_pages);
   } else {
-    int requested_pages = Min(MemoryAllocator::kPagesPerChunk,
-                              max_capacity_ / Page::kObjectAreaSize);
+    int requested_pages =
+        Min(MemoryAllocator::kPagesPerChunk,
+            static_cast<int>(max_capacity_ / Page::kObjectAreaSize));
     first_page_ =
         MemoryAllocator::AllocatePages(requested_pages, &num_pages, this);
     if (!first_page_->is_valid()) return false;
@@ -984,7 +988,8 @@
   // Last page must be valid and its next page is invalid.
   ASSERT(last_page->is_valid() && !last_page->next_page()->is_valid());
 
-  int available_pages = (max_capacity_ - Capacity()) / Page::kObjectAreaSize;
+  int available_pages =
+      static_cast<int>((max_capacity_ - Capacity()) / Page::kObjectAreaSize);
   if (available_pages <= 0) return false;
 
   int desired_pages = Min(available_pages, MemoryAllocator::kPagesPerChunk);
@@ -1264,7 +1269,7 @@
 
 
 void NewSpace::Shrink() {
-  int new_capacity = Max(InitialCapacity(), 2 * Size());
+  int new_capacity = Max(InitialCapacity(), 2 * SizeAsInt());
   int rounded_new_capacity =
       RoundUp(new_capacity, static_cast<int>(OS::AllocateAlignment()));
   if (rounded_new_capacity < Capacity() &&
@@ -1643,7 +1648,8 @@
 #ifdef DEBUG
   if (FLAG_heap_stats) {
     float pct = static_cast<float>(Available()) / Capacity();
-    PrintF("  capacity: %d, available: %d, %%%d\n",
+    PrintF("  capacity: %" V8_PTR_PREFIX "d"
+               ", available: %" V8_PTR_PREFIX "d, %%%d\n",
            Capacity(), Available(), static_cast<int>(pct*100));
     PrintF("\n  Object Histogram:\n");
     for (int i = 0; i <= LAST_TYPE; i++) {
@@ -1822,7 +1828,7 @@
   if (cur == kEnd) {
     // No large enough size in list.
     *wasted_bytes = 0;
-    return Failure::RetryAfterGC(size_in_bytes, owner_);
+    return Failure::RetryAfterGC(owner_);
   }
   ASSERT(!FLAG_always_compact);  // We only use the freelists with mark-sweep.
   int rem = cur - index;
@@ -1920,7 +1926,7 @@
 
 Object* FixedSizeFreeList::Allocate() {
   if (head_ == NULL) {
-    return Failure::RetryAfterGC(object_size_, owner_);
+    return Failure::RetryAfterGC(owner_);
   }
 
   ASSERT(!FLAG_always_compact);  // We only use the freelists with mark-sweep.
@@ -2401,8 +2407,10 @@
 
 
 void OldSpace::ReportStatistics() {
-  int pct = Available() * 100 / Capacity();
-  PrintF("  capacity: %d, waste: %d, available: %d, %%%d\n",
+  int pct = static_cast<int>(Available() * 100 / Capacity());
+  PrintF("  capacity: %" V8_PTR_PREFIX "d"
+             ", waste: %" V8_PTR_PREFIX "d"
+             ", available: %" V8_PTR_PREFIX "d, %%%d\n",
          Capacity(), Waste(), Available(), pct);
 
   ClearHistograms();
@@ -2558,8 +2566,10 @@
 
 #ifdef DEBUG
 void FixedSpace::ReportStatistics() {
-  int pct = Available() * 100 / Capacity();
-  PrintF("  capacity: %d, waste: %d, available: %d, %%%d\n",
+  int pct = static_cast<int>(Available() * 100 / Capacity());
+  PrintF("  capacity: %" V8_PTR_PREFIX "d"
+             ", waste: %" V8_PTR_PREFIX "d"
+             ", available: %" V8_PTR_PREFIX "d, %%%d\n",
          Capacity(), Waste(), Available(), pct);
 
   ClearHistograms();
@@ -2743,14 +2753,14 @@
   // Check if we want to force a GC before growing the old space further.
   // If so, fail the allocation.
   if (!Heap::always_allocate() && Heap::OldGenerationAllocationLimitReached()) {
-    return Failure::RetryAfterGC(requested_size, identity());
+    return Failure::RetryAfterGC(identity());
   }
 
   size_t chunk_size;
   LargeObjectChunk* chunk =
       LargeObjectChunk::New(requested_size, &chunk_size, executable);
   if (chunk == NULL) {
-    return Failure::RetryAfterGC(requested_size, identity());
+    return Failure::RetryAfterGC(identity());
   }
 
   size_ += static_cast<int>(chunk_size);
@@ -3011,7 +3021,7 @@
 
 
 void LargeObjectSpace::ReportStatistics() {
-  PrintF("  size: %d\n", size_);
+  PrintF("  size: %" V8_PTR_PREFIX "d\n", size_);
   int num_objects = 0;
   ClearHistograms();
   LargeObjectIterator it(this);
diff --git a/src/spaces.h b/src/spaces.h
index 94e0cd2..0e6a91e 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -371,7 +371,7 @@
   // Identity used in error reporting.
   AllocationSpace identity() { return id_; }
 
-  virtual int Size() = 0;
+  virtual intptr_t Size() = 0;
 
 #ifdef ENABLE_HEAP_PROTECTION
   // Protect/unprotect the space by marking it read-only/writable.
@@ -491,7 +491,7 @@
  public:
   // Initializes its internal bookkeeping structures.
   // Max capacity of the total space.
-  static bool Setup(int max_capacity);
+  static bool Setup(intptr_t max_capacity);
 
   // Deletes valid chunks.
   static void TearDown();
@@ -582,16 +582,18 @@
       MemoryAllocationCallback callback);
 
   // Returns the maximum available bytes of heaps.
-  static int Available() { return capacity_ < size_ ? 0 : capacity_ - size_; }
+  static intptr_t Available() {
+    return capacity_ < size_ ? 0 : capacity_ - size_;
+  }
 
   // Returns allocated spaces in bytes.
-  static int Size() { return size_; }
+  static intptr_t Size() { return size_; }
 
   // Returns allocated executable spaces in bytes.
-  static int SizeExecutable() { return size_executable_; }
+  static intptr_t SizeExecutable() { return size_executable_; }
 
   // Returns maximum available bytes that the old space can have.
-  static int MaxAvailable() {
+  static intptr_t MaxAvailable() {
     return (Available() / Page::kPageSize) * Page::kObjectAreaSize;
   }
 
@@ -649,12 +651,12 @@
 
  private:
   // Maximum space size in bytes.
-  static int capacity_;
+  static intptr_t capacity_;
 
   // Allocated space size in bytes.
-  static int size_;
+  static intptr_t size_;
   // Allocated executable space size in bytes.
-  static int size_executable_;
+  static intptr_t size_executable_;
 
   struct MemoryAllocationCallbackRegistration {
     MemoryAllocationCallbackRegistration(MemoryAllocationCallback callback,
@@ -927,10 +929,10 @@
   }
 
   // Accessors for the allocation statistics.
-  int Capacity() { return capacity_; }
-  int Available() { return available_; }
-  int Size() { return size_; }
-  int Waste() { return waste_; }
+  intptr_t Capacity() { return capacity_; }
+  intptr_t Available() { return available_; }
+  intptr_t Size() { return size_; }
+  intptr_t Waste() { return waste_; }
 
   // Grow the space by adding available bytes.
   void ExpandSpace(int size_in_bytes) {
@@ -945,13 +947,13 @@
   }
 
   // Allocate from available bytes (available -> size).
-  void AllocateBytes(int size_in_bytes) {
+  void AllocateBytes(intptr_t size_in_bytes) {
     available_ -= size_in_bytes;
     size_ += size_in_bytes;
   }
 
   // Free allocated bytes, making them available (size -> available).
-  void DeallocateBytes(int size_in_bytes) {
+  void DeallocateBytes(intptr_t size_in_bytes) {
     size_ -= size_in_bytes;
     available_ += size_in_bytes;
   }
@@ -964,23 +966,25 @@
 
   // Consider the wasted bytes to be allocated, as they contain filler
   // objects (waste -> size).
-  void FillWastedBytes(int size_in_bytes) {
+  void FillWastedBytes(intptr_t size_in_bytes) {
     waste_ -= size_in_bytes;
     size_ += size_in_bytes;
   }
 
  private:
-  int capacity_;
-  int available_;
-  int size_;
-  int waste_;
+  intptr_t capacity_;
+  intptr_t available_;
+  intptr_t size_;
+  intptr_t waste_;
 };
 
 
 class PagedSpace : public Space {
  public:
   // Creates a space with a maximum capacity, and an id.
-  PagedSpace(int max_capacity, AllocationSpace id, Executability executable);
+  PagedSpace(intptr_t max_capacity,
+             AllocationSpace id,
+             Executability executable);
 
   virtual ~PagedSpace() {}
 
@@ -1031,21 +1035,21 @@
   }
 
   // Current capacity without growing (Size() + Available() + Waste()).
-  int Capacity() { return accounting_stats_.Capacity(); }
+  intptr_t Capacity() { return accounting_stats_.Capacity(); }
 
   // Total amount of memory committed for this space.  For paged
   // spaces this equals the capacity.
-  int CommittedMemory() { return Capacity(); }
+  intptr_t CommittedMemory() { return Capacity(); }
 
   // Available bytes without growing.
-  int Available() { return accounting_stats_.Available(); }
+  intptr_t Available() { return accounting_stats_.Available(); }
 
   // Allocated bytes in this space.
-  virtual int Size() { return accounting_stats_.Size(); }
+  virtual intptr_t Size() { return accounting_stats_.Size(); }
 
   // Wasted bytes due to fragmentation and not recoverable until the
   // next GC of this space.
-  int Waste() { return accounting_stats_.Waste(); }
+  intptr_t Waste() { return accounting_stats_.Waste(); }
 
   // Returns the address of the first object in this space.
   Address bottom() { return first_page_->ObjectAreaStart(); }
@@ -1137,7 +1141,7 @@
 
  protected:
   // Maximum capacity of this space.
-  int max_capacity_;
+  intptr_t max_capacity_;
 
   // Accounting information for this space.
   AllocationStats accounting_stats_;
@@ -1328,7 +1332,7 @@
 
   // If we don't have these here then SemiSpace will be abstract.  However
   // they should never be called.
-  virtual int Size() {
+  virtual intptr_t Size() {
     UNREACHABLE();
     return 0;
   }
@@ -1471,22 +1475,26 @@
   }
 
   // Return the allocated bytes in the active semispace.
-  virtual int Size() { return static_cast<int>(top() - bottom()); }
+  virtual intptr_t Size() { return static_cast<int>(top() - bottom()); }
+  // The same, but returning an int.  We have to have the one that returns
+  // intptr_t because it is inherited, but if we know we are dealing with the
+  // new space, which can't get as big as the other spaces then this is useful:
+  int SizeAsInt() { return static_cast<int>(Size()); }
 
   // Return the current capacity of a semispace.
-  int Capacity() {
+  intptr_t Capacity() {
     ASSERT(to_space_.Capacity() == from_space_.Capacity());
     return to_space_.Capacity();
   }
 
   // Return the total amount of memory committed for new space.
-  int CommittedMemory() {
+  intptr_t CommittedMemory() {
     if (from_space_.is_committed()) return 2 * Capacity();
     return Capacity();
   }
 
   // Return the available bytes without growing in the active semispace.
-  int Available() { return Capacity() - Size(); }
+  intptr_t Available() { return Capacity() - Size(); }
 
   // Return the maximum capacity of a semispace.
   int MaximumCapacity() {
@@ -1681,7 +1689,7 @@
   void Reset();
 
   // Return the number of bytes available on the free list.
-  int available() { return available_; }
+  intptr_t available() { return available_; }
 
   // Place a node on the free list.  The block of size 'size_in_bytes'
   // starting at 'start' is placed on the free list.  The return value is the
@@ -1783,7 +1791,7 @@
   void Reset();
 
   // Return the number of bytes available on the free list.
-  int available() { return available_; }
+  intptr_t available() { return available_; }
 
   // Place a node on the free list.  The block starting at 'start' (assumed to
   // have size object_size_) is placed on the free list.  Bookkeeping
@@ -1797,7 +1805,7 @@
 
  private:
   // Available bytes on the free list.
-  int available_;
+  intptr_t available_;
 
   // The head of the free list.
   Address head_;
@@ -1823,7 +1831,7 @@
  public:
   // Creates an old space object with a given maximum capacity.
   // The constructor does not allocate pages from OS.
-  explicit OldSpace(int max_capacity,
+  explicit OldSpace(intptr_t max_capacity,
                     AllocationSpace id,
                     Executability executable)
       : PagedSpace(max_capacity, id, executable), free_list_(id) {
@@ -1832,7 +1840,7 @@
 
   // The bytes available on the free list (ie, not above the linear allocation
   // pointer).
-  int AvailableFree() { return free_list_.available(); }
+  intptr_t AvailableFree() { return free_list_.available(); }
 
   // The limit of allocation for a page in this space.
   virtual Address PageAllocationLimit(Page* page) {
@@ -1893,7 +1901,7 @@
 
 class FixedSpace : public PagedSpace {
  public:
-  FixedSpace(int max_capacity,
+  FixedSpace(intptr_t max_capacity,
              AllocationSpace id,
              int object_size_in_bytes,
              const char* name)
@@ -1968,7 +1976,7 @@
 class MapSpace : public FixedSpace {
  public:
   // Creates a map space object with a maximum capacity.
-  MapSpace(int max_capacity, int max_map_space_pages, AllocationSpace id)
+  MapSpace(intptr_t max_capacity, int max_map_space_pages, AllocationSpace id)
       : FixedSpace(max_capacity, id, Map::kSize, "map"),
         max_map_space_pages_(max_map_space_pages) {
     ASSERT(max_map_space_pages < kMaxMapPageIndex);
@@ -2073,7 +2081,7 @@
 class CellSpace : public FixedSpace {
  public:
   // Creates a property cell space object with a maximum capacity.
-  CellSpace(int max_capacity, AllocationSpace id)
+  CellSpace(intptr_t max_capacity, AllocationSpace id)
       : FixedSpace(max_capacity, id, JSGlobalPropertyCell::kSize, "cell") {}
 
  protected:
@@ -2129,7 +2137,7 @@
 
   // Given a chunk size, returns the object size it can accommodate.  Used by
   // LargeObjectSpace::Available.
-  static int ObjectSizeFor(int chunk_size) {
+  static intptr_t ObjectSizeFor(intptr_t chunk_size) {
     if (chunk_size <= (Page::kPageSize + Page::kObjectStartOffset)) return 0;
     return chunk_size - Page::kPageSize - Page::kObjectStartOffset;
   }
@@ -2165,11 +2173,11 @@
   Object* AllocateRawFixedArray(int size_in_bytes);
 
   // Available bytes for objects in this space.
-  int Available() {
+  intptr_t Available() {
     return LargeObjectChunk::ObjectSizeFor(MemoryAllocator::Available());
   }
 
-  virtual int Size() {
+  virtual intptr_t Size() {
     return size_;
   }
 
@@ -2186,7 +2194,6 @@
   // if such a page doesn't exist.
   LargeObjectChunk* FindChunkContainingPc(Address pc);
 
-
   // Iterates objects covered by dirty regions.
   void IterateDirtyRegions(ObjectSlotCallback func);
 
@@ -2223,7 +2230,7 @@
  private:
   // The head of the linked list of large object chunks.
   LargeObjectChunk* first_chunk_;
-  int size_;  // allocated bytes
+  intptr_t size_;  // allocated bytes
   int page_count_;  // number of chunks
 
 
diff --git a/src/vm-state.cc b/src/string-search.cc
similarity index 85%
copy from src/vm-state.cc
copy to src/string-search.cc
index 6bd737d..5687443 100644
--- a/src/vm-state.cc
+++ b/src/string-search.cc
@@ -26,14 +26,15 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "v8.h"
-
-#include "vm-state.h"
+#include "string-search.h"
 
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_VMSTATE_TRACKING
-AtomicWord VMState::current_state_ = 0;
-#endif
+// Storage for constants used by string-search.
 
-} }  // namespace v8::internal
+int StringSearchBase::kBadCharShiftTable[kUC16AlphabetSize];
+int StringSearchBase::kGoodSuffixShiftTable[kBMMaxShift + 1];
+int StringSearchBase::kSuffixTable[kBMMaxShift + 1];
+
+}}  // namespace v8::internal
diff --git a/src/string-search.h b/src/string-search.h
index d7959c0..eac8475 100644
--- a/src/string-search.h
+++ b/src/string-search.h
@@ -32,259 +32,320 @@
 namespace internal {
 
 
-// Cap on the maximal shift in the Boyer-Moore implementation. By setting a
-// limit, we can fix the size of tables. For a needle longer than this limit,
-// search will not be optimal, since we only build tables for a smaller suffix
-// of the string, which is a safe approximation.
-static const int kBMMaxShift = 250;
-// Reduce alphabet to this size.
-// One of the tables used by Boyer-Moore and Boyer-Moore-Horspool has size
-// proportional to the input alphabet. We reduce the alphabet size by
-// equating input characters modulo a smaller alphabet size. This gives
-// a potentially less efficient searching, but is a safe approximation.
-// For needles using only characters in the same Unicode 256-code point page,
-// there is no search speed degradation.
-static const int kBMAlphabetSize = 256;
-// For patterns below this length, the skip length of Boyer-Moore is too short
-// to compensate for the algorithmic overhead compared to simple brute force.
-static const int kBMMinPatternLength = 7;
+//---------------------------------------------------------------------
+// String Search object.
+//---------------------------------------------------------------------
 
-// Holds the two buffers used by Boyer-Moore string search's Good Suffix
-// shift. Only allows the last kBMMaxShift characters of the needle
-// to be indexed.
-class BMGoodSuffixBuffers {
+// Class holding constants and methods that apply to all string search variants,
+// independently of subject and pattern char size.
+class StringSearchBase {
+ protected:
+  // Cap on the maximal shift in the Boyer-Moore implementation. By setting a
+  // limit, we can fix the size of tables. For a needle longer than this limit,
+  // search will not be optimal, since we only build tables for a suffix
+  // of the string, but it is a safe approximation.
+  static const int kBMMaxShift = 250;
+
+  // Reduce alphabet to this size.
+  // One of the tables used by Boyer-Moore and Boyer-Moore-Horspool has size
+  // proportional to the input alphabet. We reduce the alphabet size by
+  // equating input characters modulo a smaller alphabet size. This gives
+  // a potentially less efficient searching, but is a safe approximation.
+  // For needles using only characters in the same Unicode 256-code point page,
+  // there is no search speed degradation.
+  static const int kAsciiAlphabetSize = 128;
+  static const int kUC16AlphabetSize = 256;
+
+  // Bad-char shift table stored in the state. It's length is the alphabet size.
+  // For patterns below this length, the skip length of Boyer-Moore is too short
+  // to compensate for the algorithmic overhead compared to simple brute force.
+  static const int kBMMinPatternLength = 7;
+
+  static inline bool IsAsciiString(Vector<const char>) {
+    return true;
+  }
+
+  static inline bool IsAsciiString(Vector<const uc16> string) {
+    for (int i = 0, n = string.length(); i < n; i++) {
+      if (static_cast<unsigned>(string[i]) > String::kMaxAsciiCharCodeU) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  // The following tables are shared by all searches.
+  // TODO(lrn): Introduce a way for a pattern to keep its tables
+  // between searches (e.g., for an Atom RegExp).
+
+  // Store for the BoyerMoore(Horspool) bad char shift table.
+  static int kBadCharShiftTable[kUC16AlphabetSize];
+  // Store for the BoyerMoore good suffix shift table.
+  static int kGoodSuffixShiftTable[kBMMaxShift + 1];
+  // Table used temporarily while building the BoyerMoore good suffix
+  // shift table.
+  static int kSuffixTable[kBMMaxShift + 1];
+};
+
+
+template <typename PatternChar, typename SubjectChar>
+class StringSearch : private StringSearchBase {
  public:
-  BMGoodSuffixBuffers() {}
-  inline void Initialize(int needle_length) {
-    ASSERT(needle_length > 1);
-    int start = needle_length < kBMMaxShift ? 0 : needle_length - kBMMaxShift;
-    int len = needle_length - start;
-    biased_suffixes_ = suffixes_ - start;
-    biased_good_suffix_shift_ = good_suffix_shift_ - start;
-    for (int i = 0; i <= len; i++) {
-      good_suffix_shift_[i] = len;
+  explicit StringSearch(Vector<const PatternChar> pattern)
+      : pattern_(pattern),
+        start_(Max(0, pattern.length() - kBMMaxShift)) {
+    if (sizeof(PatternChar) > sizeof(SubjectChar)) {
+      if (!IsAsciiString(pattern_)) {
+        strategy_ = &FailSearch;
+        return;
+      }
+    }
+    int pattern_length = pattern_.length();
+    if (pattern_length < kBMMinPatternLength) {
+      if (pattern_length == 1) {
+        strategy_ = &SingleCharSearch;
+        return;
+      }
+      strategy_ = &LinearSearch;
+      return;
+    }
+    strategy_ = &InitialSearch;
+  }
+
+  int Search(Vector<const SubjectChar> subject, int index) {
+    return strategy_(this, subject, index);
+  }
+
+  static inline int AlphabetSize() {
+    if (sizeof(PatternChar) == 1) {
+      // ASCII needle.
+      return kAsciiAlphabetSize;
+    } else {
+      ASSERT(sizeof(PatternChar) == 2);
+      // UC16 needle.
+      return kUC16AlphabetSize;
     }
   }
-  inline int& suffix(int index) {
-    ASSERT(biased_suffixes_ + index >= suffixes_);
-    return biased_suffixes_[index];
-  }
-  inline int& shift(int index) {
-    ASSERT(biased_good_suffix_shift_ + index >= good_suffix_shift_);
-    return biased_good_suffix_shift_[index];
-  }
+
  private:
-  int suffixes_[kBMMaxShift + 1];
-  int good_suffix_shift_[kBMMaxShift + 1];
-  int* biased_suffixes_;
-  int* biased_good_suffix_shift_;
-  DISALLOW_COPY_AND_ASSIGN(BMGoodSuffixBuffers);
+  typedef int (*SearchFunction)(  // NOLINT - it's not a cast!
+      StringSearch<PatternChar, SubjectChar>*,
+      Vector<const SubjectChar>,
+      int);
+
+  static int FailSearch(StringSearch<PatternChar, SubjectChar>*,
+                        Vector<const SubjectChar>,
+                        int) {
+    return -1;
+  }
+
+  static int SingleCharSearch(StringSearch<PatternChar, SubjectChar>* search,
+                              Vector<const SubjectChar> subject,
+                              int start_index);
+
+  static int LinearSearch(StringSearch<PatternChar, SubjectChar>* search,
+                          Vector<const SubjectChar> subject,
+                          int start_index);
+
+  static int InitialSearch(StringSearch<PatternChar, SubjectChar>* search,
+                           Vector<const SubjectChar> subject,
+                           int start_index);
+
+  static int BoyerMooreHorspoolSearch(
+      StringSearch<PatternChar, SubjectChar>* search,
+      Vector<const SubjectChar> subject,
+      int start_index);
+
+  static int BoyerMooreSearch(StringSearch<PatternChar, SubjectChar>* search,
+                              Vector<const SubjectChar> subject,
+                              int start_index);
+
+  void PopulateBoyerMooreHorspoolTable();
+
+  void PopulateBoyerMooreTable();
+
+  static inline int CharOccurrence(int* bad_char_occurrence,
+                                   SubjectChar char_code) {
+    if (sizeof(SubjectChar) == 1) {
+      return bad_char_occurrence[static_cast<int>(char_code)];
+    }
+    if (sizeof(PatternChar) == 1) {
+      if (static_cast<unsigned int>(char_code) > String::kMaxAsciiCharCodeU) {
+        return -1;
+      }
+      return bad_char_occurrence[static_cast<unsigned int>(char_code)];
+    }
+    // Both pattern and subject are UC16. Reduce character to equivalence class.
+    int equiv_class = char_code % kUC16AlphabetSize;
+    return bad_char_occurrence[equiv_class];
+  }
+
+  // Return a table covering the last kBMMaxShift+1 positions of
+  // pattern.
+  int* bad_char_table() {
+    return kBadCharShiftTable;
+  }
+
+  int* good_suffix_shift_table() {
+    // Return biased pointer that maps the range  [start_..pattern_.length()
+    // to the kGoodSuffixShiftTable array.
+    return kGoodSuffixShiftTable - start_;
+  }
+
+  int* suffix_table() {
+    // Return biased pointer that maps the range  [start_..pattern_.length()
+    // to the kSuffixTable array.
+    return kSuffixTable - start_;
+  }
+
+  // The pattern to search for.
+  Vector<const PatternChar> pattern_;
+  // Pointer to implementation of the search.
+  SearchFunction strategy_;
+  // Cache value of Max(0, pattern_length() - kBMMaxShift)
+  int start_;
 };
 
-// buffers reused by BoyerMoore
-struct BMBuffers {
- public:
-  static int bad_char_occurrence[kBMAlphabetSize];
-  static BMGoodSuffixBuffers bmgs_buffers;
-};
 
-// State of the string match tables.
-// SIMPLE: No usable content in the buffers.
-// BOYER_MOORE_HORSPOOL: The bad_char_occurence table has been populated.
-// BOYER_MOORE: The bmgs_buffers tables have also been populated.
-// Whenever starting with a new needle, one should call InitializeStringSearch
-// to determine which search strategy to use, and in the case of a long-needle
-// strategy, the call also initializes the algorithm to SIMPLE.
-enum StringSearchAlgorithm { SIMPLE_SEARCH, BOYER_MOORE_HORSPOOL, BOYER_MOORE };
-static StringSearchAlgorithm algorithm;
+//---------------------------------------------------------------------
+// Single Character Pattern Search Strategy
+//---------------------------------------------------------------------
 
-
-// Compute the bad-char table for Boyer-Moore in the static buffer.
-template <typename PatternChar>
-static void BoyerMoorePopulateBadCharTable(Vector<const PatternChar> pattern) {
-  // Only preprocess at most kBMMaxShift last characters of pattern.
-  int start = Max(pattern.length() - kBMMaxShift, 0);
-  // Run forwards to populate bad_char_table, so that *last* instance
-  // of character equivalence class is the one registered.
-  // Notice: Doesn't include the last character.
-  int table_size = (sizeof(PatternChar) == 1) ? String::kMaxAsciiCharCode + 1
-                                        : kBMAlphabetSize;
-  if (start == 0) {  // All patterns less than kBMMaxShift in length.
-    memset(BMBuffers::bad_char_occurrence,
-           -1,
-           table_size * sizeof(*BMBuffers::bad_char_occurrence));
+template <typename PatternChar, typename SubjectChar>
+int StringSearch<PatternChar, SubjectChar>::SingleCharSearch(
+    StringSearch<PatternChar, SubjectChar>* search,
+    Vector<const SubjectChar> subject,
+    int index) {
+  ASSERT_EQ(1, search->pattern_.length());
+  PatternChar pattern_first_char = search->pattern_[0];
+  int i = index;
+  if (sizeof(SubjectChar) == 1 && sizeof(PatternChar) == 1) {
+    const SubjectChar* pos = reinterpret_cast<const SubjectChar*>(
+        memchr(subject.start() + i,
+               pattern_first_char,
+               subject.length() - i));
+    if (pos == NULL) return -1;
+    return static_cast<int>(pos - subject.start());
   } else {
-    for (int i = 0; i < table_size; i++) {
-      BMBuffers::bad_char_occurrence[i] = start - 1;
-    }
-  }
-  for (int i = start; i < pattern.length() - 1; i++) {
-    PatternChar c = pattern[i];
-    int bucket = (sizeof(PatternChar) ==1) ? c : c % kBMAlphabetSize;
-    BMBuffers::bad_char_occurrence[bucket] = i;
-  }
-}
-
-
-template <typename PatternChar>
-static void BoyerMoorePopulateGoodSuffixTable(
-    Vector<const PatternChar> pattern) {
-  int m = pattern.length();
-  int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
-  int len = m - start;
-  // Compute Good Suffix tables.
-  BMBuffers::bmgs_buffers.Initialize(m);
-
-  BMBuffers::bmgs_buffers.shift(m-1) = 1;
-  BMBuffers::bmgs_buffers.suffix(m) = m + 1;
-  PatternChar last_char = pattern[m - 1];
-  int suffix = m + 1;
-  {
-    int i = m;
-    while (i > start) {
-      PatternChar c = pattern[i - 1];
-      while (suffix <= m && c != pattern[suffix - 1]) {
-        if (BMBuffers::bmgs_buffers.shift(suffix) == len) {
-          BMBuffers::bmgs_buffers.shift(suffix) = suffix - i;
-        }
-        suffix = BMBuffers::bmgs_buffers.suffix(suffix);
-      }
-      BMBuffers::bmgs_buffers.suffix(--i) = --suffix;
-      if (suffix == m) {
-        // No suffix to extend, so we check against last_char only.
-        while ((i > start) && (pattern[i - 1] != last_char)) {
-          if (BMBuffers::bmgs_buffers.shift(m) == len) {
-            BMBuffers::bmgs_buffers.shift(m) = m - i;
-          }
-          BMBuffers::bmgs_buffers.suffix(--i) = m;
-        }
-        if (i > start) {
-          BMBuffers::bmgs_buffers.suffix(--i) = --suffix;
-        }
-      }
-    }
-  }
-  if (suffix < m) {
-    for (int i = start; i <= m; i++) {
-      if (BMBuffers::bmgs_buffers.shift(i) == len) {
-        BMBuffers::bmgs_buffers.shift(i) = suffix - start;
-      }
-      if (i == suffix) {
-        suffix = BMBuffers::bmgs_buffers.suffix(suffix);
-      }
-    }
-  }
-}
-
-
-template <typename SubjectChar, typename PatternChar>
-static inline int CharOccurrence(int char_code) {
-  if (sizeof(SubjectChar) == 1) {
-    return BMBuffers::bad_char_occurrence[char_code];
-  }
-  if (sizeof(PatternChar) == 1) {
-    if (char_code > String::kMaxAsciiCharCode) {
-      return -1;
-    }
-    return BMBuffers::bad_char_occurrence[char_code];
-  }
-  return BMBuffers::bad_char_occurrence[char_code % kBMAlphabetSize];
-}
-
-
-// Restricted simplified Boyer-Moore string matching.
-// Uses only the bad-shift table of Boyer-Moore and only uses it
-// for the character compared to the last character of the needle.
-template <typename SubjectChar, typename PatternChar>
-static int BoyerMooreHorspool(Vector<const SubjectChar> subject,
-                              Vector<const PatternChar> pattern,
-                              int start_index,
-                              bool* complete) {
-  ASSERT(algorithm <= BOYER_MOORE_HORSPOOL);
-  int n = subject.length();
-  int m = pattern.length();
-
-  int badness = -m;
-
-  // How bad we are doing without a good-suffix table.
-  int idx;  // No matches found prior to this index.
-  PatternChar last_char = pattern[m - 1];
-  int last_char_shift =
-      m - 1 - CharOccurrence<SubjectChar, PatternChar>(last_char);
-  // Perform search
-  for (idx = start_index; idx <= n - m;) {
-    int j = m - 1;
-    int c;
-    while (last_char != (c = subject[idx + j])) {
-      int bc_occ = CharOccurrence<SubjectChar, PatternChar>(c);
-      int shift = j - bc_occ;
-      idx += shift;
-      badness += 1 - shift;  // at most zero, so badness cannot increase.
-      if (idx > n - m) {
-        *complete = true;
+    if (sizeof(PatternChar) > sizeof(SubjectChar)) {
+      if (static_cast<uc16>(pattern_first_char) > String::kMaxAsciiCharCodeU) {
         return -1;
       }
     }
-    j--;
-    while (j >= 0 && pattern[j] == (subject[idx + j])) j--;
-    if (j < 0) {
-      *complete = true;
-      return idx;
+    SubjectChar search_char = static_cast<SubjectChar>(pattern_first_char);
+    int n = subject.length();
+    while (i < n) {
+      if (subject[i++] == search_char) return i - 1;
+    }
+    return -1;
+  }
+}
+
+//---------------------------------------------------------------------
+// Linear Search Strategy
+//---------------------------------------------------------------------
+
+
+template <typename PatternChar, typename SubjectChar>
+static inline bool CharCompare(const PatternChar* pattern,
+                               const SubjectChar* subject,
+                               int length) {
+  ASSERT(length > 0);
+  int pos = 0;
+  do {
+    if (pattern[pos] != subject[pos]) {
+      return false;
+    }
+    pos++;
+  } while (pos < length);
+  return true;
+}
+
+
+// Simple linear search for short patterns. Never bails out.
+template <typename PatternChar, typename SubjectChar>
+int StringSearch<PatternChar, SubjectChar>::LinearSearch(
+    StringSearch<PatternChar, SubjectChar>* search,
+    Vector<const SubjectChar> subject,
+    int index) {
+  Vector<const PatternChar> pattern = search->pattern_;
+  ASSERT(pattern.length() > 1);
+  int pattern_length = pattern.length();
+  PatternChar pattern_first_char = pattern[0];
+  int i = index;
+  int n = subject.length() - pattern_length;
+  while (i <= n) {
+    if (sizeof(SubjectChar) == 1 && sizeof(PatternChar) == 1) {
+      const SubjectChar* pos = reinterpret_cast<const SubjectChar*>(
+          memchr(subject.start() + i,
+                 pattern_first_char,
+                 n - i + 1));
+      if (pos == NULL) return -1;
+      i = static_cast<int>(pos - subject.start()) + 1;
     } else {
-      idx += last_char_shift;
-      // Badness increases by the number of characters we have
-      // checked, and decreases by the number of characters we
-      // can skip by shifting. It's a measure of how we are doing
-      // compared to reading each character exactly once.
-      badness += (m - j) - last_char_shift;
-      if (badness > 0) {
-        *complete = false;
-        return idx;
-      }
+      if (subject[i++] != pattern_first_char) continue;
+    }
+    // Loop extracted to separate function to allow using return to do
+    // a deeper break.
+    if (CharCompare(pattern.start() + 1,
+                    subject.start() + i,
+                    pattern_length - 1)) {
+      return i - 1;
     }
   }
-  *complete = true;
   return -1;
 }
 
+//---------------------------------------------------------------------
+// Boyer-Moore string search
+//---------------------------------------------------------------------
 
-template <typename SubjectChar, typename PatternChar>
-static int BoyerMooreIndexOf(Vector<const SubjectChar> subject,
-                             Vector<const PatternChar> pattern,
-                             int idx) {
-  ASSERT(algorithm <= BOYER_MOORE);
-  int n = subject.length();
-  int m = pattern.length();
+template <typename PatternChar, typename SubjectChar>
+int StringSearch<PatternChar, SubjectChar>::BoyerMooreSearch(
+    StringSearch<PatternChar, SubjectChar>* search,
+    Vector<const SubjectChar> subject,
+    int start_index) {
+  Vector<const PatternChar> pattern = search->pattern_;
+  int subject_length = subject.length();
+  int pattern_length = pattern.length();
   // Only preprocess at most kBMMaxShift last characters of pattern.
-  int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
+  int start = search->start_;
 
-  PatternChar last_char = pattern[m - 1];
+  int* bad_char_occurence = search->bad_char_table();
+  int* good_suffix_shift = search->good_suffix_shift_table();
+
+  PatternChar last_char = pattern[pattern_length - 1];
+  int index = start_index;
   // Continue search from i.
-  while (idx <= n - m) {
-    int j = m - 1;
-    SubjectChar c;
-    while (last_char != (c = subject[idx + j])) {
-      int shift = j - CharOccurrence<SubjectChar, PatternChar>(c);
-      idx += shift;
-      if (idx > n - m) {
+  while (index <= subject_length - pattern_length) {
+    int j = pattern_length - 1;
+    int c;
+    while (last_char != (c = subject[index + j])) {
+      int shift =
+          j - CharOccurrence(bad_char_occurence, c);
+      index += shift;
+      if (index > subject_length - pattern_length) {
         return -1;
       }
     }
-    while (j >= 0 && pattern[j] == (c = subject[idx + j])) j--;
+    while (j >= 0 && pattern[j] == (c = subject[index + j])) j--;
     if (j < 0) {
-      return idx;
+      return index;
     } else if (j < start) {
       // we have matched more than our tables allow us to be smart about.
       // Fall back on BMH shift.
-      idx += m - 1 - CharOccurrence<SubjectChar, PatternChar>(last_char);
+      index += pattern_length - 1
+          - CharOccurrence(bad_char_occurence,
+                           static_cast<SubjectChar>(last_char));
     } else {
-      int gs_shift = BMBuffers::bmgs_buffers.shift(j + 1);
-      int bc_occ = CharOccurrence<SubjectChar, PatternChar>(c);
+      int gs_shift = good_suffix_shift[j + 1];
+      int bc_occ =
+          CharOccurrence(bad_char_occurence, c);
       int shift = j - bc_occ;
       if (gs_shift > shift) {
         shift = gs_shift;
       }
-      idx += shift;
+      index += shift;
     }
   }
 
@@ -292,18 +353,163 @@
 }
 
 
-// Trivial string search for shorter strings.
-// On return, if "complete" is set to true, the return value is the
-// final result of searching for the patter in the subject.
-// If "complete" is set to false, the return value is the index where
-// further checking should start, i.e., it's guaranteed that the pattern
-// does not occur at a position prior to the returned index.
 template <typename PatternChar, typename SubjectChar>
-static int SimpleIndexOf(Vector<const SubjectChar> subject,
-                         Vector<const PatternChar> pattern,
-                         int idx,
-                         bool* complete) {
-  ASSERT(pattern.length() > 1);
+void StringSearch<PatternChar, SubjectChar>::PopulateBoyerMooreTable() {
+  int pattern_length = pattern_.length();
+  const PatternChar* pattern = pattern_.start();
+  // Only look at the last kBMMaxShift characters of pattern (from start_
+  // to pattern_length).
+  int start = start_;
+  int length = pattern_length - start;
+
+  // Biased tables so that we can use pattern indices as table indices,
+  // even if we only cover the part of the pattern from offset start.
+  int* shift_table = good_suffix_shift_table();
+  int* suffix_table = this->suffix_table();
+
+  // Initialize table.
+  for (int i = start; i < pattern_length; i++) {
+    shift_table[i] = length;
+  }
+  shift_table[pattern_length] = 1;
+  suffix_table[pattern_length] = pattern_length + 1;
+
+  // Find suffixes.
+  PatternChar last_char = pattern[pattern_length - 1];
+  int suffix = pattern_length + 1;
+  {
+    int i = pattern_length;
+    while (i > start) {
+      PatternChar c = pattern[i - 1];
+      while (suffix <= pattern_length && c != pattern[suffix - 1]) {
+        if (shift_table[suffix] == length) {
+          shift_table[suffix] = suffix - i;
+        }
+        suffix = suffix_table[suffix];
+      }
+      suffix_table[--i] = --suffix;
+      if (suffix == pattern_length) {
+        // No suffix to extend, so we check against last_char only.
+        while ((i > start) && (pattern[i - 1] != last_char)) {
+          if (shift_table[pattern_length] == length) {
+            shift_table[pattern_length] = pattern_length - i;
+          }
+          suffix_table[--i] = pattern_length;
+        }
+        if (i > start) {
+          suffix_table[--i] = --suffix;
+        }
+      }
+    }
+  }
+  // Build shift table using suffixes.
+  if (suffix < pattern_length) {
+    for (int i = start; i <= pattern_length; i++) {
+      if (shift_table[i] == length) {
+        shift_table[i] = suffix - start;
+      }
+      if (i == suffix) {
+        suffix = suffix_table[suffix];
+      }
+    }
+  }
+}
+
+//---------------------------------------------------------------------
+// Boyer-Moore-Horspool string search.
+//---------------------------------------------------------------------
+
+template <typename PatternChar, typename SubjectChar>
+int StringSearch<PatternChar, SubjectChar>::BoyerMooreHorspoolSearch(
+    StringSearch<PatternChar, SubjectChar>* search,
+    Vector<const SubjectChar> subject,
+    int start_index) {
+  Vector<const PatternChar> pattern = search->pattern_;
+  int subject_length = subject.length();
+  int pattern_length = pattern.length();
+  int* char_occurrences = search->bad_char_table();
+  int badness = -pattern_length;
+
+  // How bad we are doing without a good-suffix table.
+  PatternChar last_char = pattern[pattern_length - 1];
+  int last_char_shift = pattern_length - 1 -
+      CharOccurrence(char_occurrences, static_cast<SubjectChar>(last_char));
+  // Perform search
+  int index = start_index;  // No matches found prior to this index.
+  while (index <= subject_length - pattern_length) {
+    int j = pattern_length - 1;
+    int subject_char;
+    while (last_char != (subject_char = subject[index + j])) {
+      int bc_occ = CharOccurrence(char_occurrences, subject_char);
+      int shift = j - bc_occ;
+      index += shift;
+      badness += 1 - shift;  // at most zero, so badness cannot increase.
+      if (index > subject_length - pattern_length) {
+        return -1;
+      }
+    }
+    j--;
+    while (j >= 0 && pattern[j] == (subject[index + j])) j--;
+    if (j < 0) {
+      return index;
+    } else {
+      index += last_char_shift;
+      // Badness increases by the number of characters we have
+      // checked, and decreases by the number of characters we
+      // can skip by shifting. It's a measure of how we are doing
+      // compared to reading each character exactly once.
+      badness += (pattern_length - j) - last_char_shift;
+      if (badness > 0) {
+        search->PopulateBoyerMooreTable();
+        search->strategy_ = &BoyerMooreSearch;
+        return BoyerMooreSearch(search, subject, index);
+      }
+    }
+  }
+  return -1;
+}
+
+
+template <typename PatternChar, typename SubjectChar>
+void StringSearch<PatternChar, SubjectChar>::PopulateBoyerMooreHorspoolTable() {
+  int pattern_length = pattern_.length();
+
+  int* bad_char_occurrence = bad_char_table();
+
+  // Only preprocess at most kBMMaxShift last characters of pattern.
+  int start = start_;
+  // Run forwards to populate bad_char_table, so that *last* instance
+  // of character equivalence class is the one registered.
+  // Notice: Doesn't include the last character.
+  int table_size = AlphabetSize();
+  if (start == 0) {  // All patterns less than kBMMaxShift in length.
+    memset(bad_char_occurrence,
+           -1,
+           table_size * sizeof(*bad_char_occurrence));
+  } else {
+    for (int i = 0; i < table_size; i++) {
+      bad_char_occurrence[i] = start - 1;
+    }
+  }
+  for (int i = start; i < pattern_length - 1; i++) {
+    PatternChar c = pattern_[i];
+    int bucket = (sizeof(PatternChar) == 1) ? c : c % AlphabetSize();
+    bad_char_occurrence[bucket] = i;
+  }
+}
+
+//---------------------------------------------------------------------
+// Linear string search with bailout to BMH.
+//---------------------------------------------------------------------
+
+// Simple linear search for short patterns, which bails out if the string
+// isn't found very early in the subject. Upgrades to BoyerMooreHorspool.
+template <typename PatternChar, typename SubjectChar>
+int StringSearch<PatternChar, SubjectChar>::InitialSearch(
+    StringSearch<PatternChar, SubjectChar>* search,
+    Vector<const SubjectChar> subject,
+    int index) {
+  Vector<const PatternChar> pattern = search->pattern_;
   int pattern_length = pattern.length();
   // Badness is a count of how much work we have done.  When we have
   // done enough work we decide it's probably worth switching to a better
@@ -313,149 +519,52 @@
   // We know our pattern is at least 2 characters, we cache the first so
   // the common case of the first character not matching is faster.
   PatternChar pattern_first_char = pattern[0];
-  for (int i = idx, n = subject.length() - pattern_length; i <= n; i++) {
+  for (int i = index, n = subject.length() - pattern_length; i <= n; i++) {
     badness++;
-    if (badness > 0) {
-      *complete = false;
-      return i;
-    }
-    if (sizeof(SubjectChar) == 1 && sizeof(PatternChar) == 1) {
-      const SubjectChar* pos = reinterpret_cast<const SubjectChar*>(
-          memchr(subject.start() + i,
-                 pattern_first_char,
-                 n - i + 1));
-      if (pos == NULL) {
-        *complete = true;
-        return -1;
+    if (badness <= 0) {
+      if (sizeof(SubjectChar) == 1 && sizeof(PatternChar) == 1) {
+        const SubjectChar* pos = reinterpret_cast<const SubjectChar*>(
+            memchr(subject.start() + i,
+                   pattern_first_char,
+                   n - i + 1));
+        if (pos == NULL) {
+          return -1;
+        }
+        i = static_cast<int>(pos - subject.start());
+      } else {
+        if (subject[i] != pattern_first_char) continue;
       }
-      i = static_cast<int>(pos - subject.start());
+      int j = 1;
+      do {
+        if (pattern[j] != subject[i + j]) {
+          break;
+        }
+        j++;
+      } while (j < pattern_length);
+      if (j == pattern_length) {
+        return i;
+      }
+      badness += j;
     } else {
-      if (subject[i] != pattern_first_char) continue;
-    }
-    int j = 1;
-    do {
-      if (pattern[j] != subject[i+j]) {
-        break;
-      }
-      j++;
-    } while (j < pattern_length);
-    if (j == pattern_length) {
-      *complete = true;
-      return i;
-    }
-    badness += j;
-  }
-  *complete = true;
-  return -1;
-}
-
-// Simple indexOf that never bails out. For short patterns only.
-template <typename PatternChar, typename SubjectChar>
-static int SimpleIndexOf(Vector<const SubjectChar> subject,
-                         Vector<const PatternChar> pattern,
-                         int idx) {
-  int pattern_length = pattern.length();
-  PatternChar pattern_first_char = pattern[0];
-  for (int i = idx, n = subject.length() - pattern_length; i <= n; i++) {
-    if (sizeof(SubjectChar) == 1 && sizeof(PatternChar) == 1) {
-      const SubjectChar* pos = reinterpret_cast<const SubjectChar*>(
-          memchr(subject.start() + i,
-                 pattern_first_char,
-                 n - i + 1));
-      if (pos == NULL) return -1;
-      i = static_cast<int>(pos - subject.start());
-    } else {
-      if (subject[i] != pattern_first_char) continue;
-    }
-    int j = 1;
-    while (j < pattern_length) {
-      if (pattern[j] != subject[i+j]) {
-        break;
-      }
-      j++;
-    }
-    if (j == pattern_length) {
-      return i;
+      search->PopulateBoyerMooreHorspoolTable();
+      search->strategy_ = &BoyerMooreHorspoolSearch;
+      return BoyerMooreHorspoolSearch(search, subject, i);
     }
   }
   return -1;
 }
 
 
-// Strategy for searching for a string in another string.
-enum StringSearchStrategy { SEARCH_FAIL, SEARCH_SHORT, SEARCH_LONG };
-
-
-template <typename PatternChar>
-static inline StringSearchStrategy InitializeStringSearch(
-    Vector<const PatternChar> pat, bool ascii_subject) {
-  // We have an ASCII haystack and a non-ASCII needle. Check if there
-  // really is a non-ASCII character in the needle and bail out if there
-  // is.
-  if (ascii_subject && sizeof(PatternChar) > 1) {
-    for (int i = 0; i < pat.length(); i++) {
-      uc16 c = pat[i];
-      if (c > String::kMaxAsciiCharCode) {
-        return SEARCH_FAIL;
-      }
-    }
-  }
-  if (pat.length() < kBMMinPatternLength) {
-    return SEARCH_SHORT;
-  }
-  algorithm = SIMPLE_SEARCH;
-  return SEARCH_LONG;
-}
-
-
-// Dispatch long needle searches to different algorithms.
+// Perform a a single stand-alone search.
+// If searching multiple times for the same pattern, a search
+// object should be constructed once and the Search function then called
+// for each search.
 template <typename SubjectChar, typename PatternChar>
-static int ComplexIndexOf(Vector<const SubjectChar> sub,
-                          Vector<const PatternChar> pat,
-                          int start_index) {
-  ASSERT(pat.length() >= kBMMinPatternLength);
-  // Try algorithms in order of increasing setup cost and expected performance.
-  bool complete;
-  int idx = start_index;
-  switch (algorithm) {
-    case SIMPLE_SEARCH:
-      idx = SimpleIndexOf(sub, pat, idx, &complete);
-      if (complete) return idx;
-      BoyerMoorePopulateBadCharTable(pat);
-      algorithm = BOYER_MOORE_HORSPOOL;
-      // FALLTHROUGH.
-    case BOYER_MOORE_HORSPOOL:
-      idx = BoyerMooreHorspool(sub, pat, idx, &complete);
-      if (complete) return idx;
-      // Build the Good Suffix table and continue searching.
-      BoyerMoorePopulateGoodSuffixTable(pat);
-      algorithm = BOYER_MOORE;
-      // FALLTHROUGH.
-    case BOYER_MOORE:
-      return BoyerMooreIndexOf(sub, pat, idx);
-  }
-  UNREACHABLE();
-  return -1;
-}
-
-
-// Dispatch to different search strategies for a single search.
-// If searching multiple times on the same needle, the search
-// strategy should only be computed once and then dispatch to different
-// loops.
-template <typename SubjectChar, typename PatternChar>
-static int StringSearch(Vector<const SubjectChar> sub,
-                        Vector<const PatternChar> pat,
+static int SearchString(Vector<const SubjectChar> subject,
+                        Vector<const PatternChar> pattern,
                         int start_index) {
-  bool ascii_subject = (sizeof(SubjectChar) == 1);
-  StringSearchStrategy strategy = InitializeStringSearch(pat, ascii_subject);
-  switch (strategy) {
-    case SEARCH_FAIL: return -1;
-    case SEARCH_SHORT: return SimpleIndexOf(sub, pat, start_index);
-    case SEARCH_LONG: return ComplexIndexOf(sub, pat, start_index);
-  }
-  UNREACHABLE();
-  return -1;
+  StringSearch<PatternChar, SubjectChar> search(pattern);
+  return search.Search(subject, start_index);
 }
 
 }}  // namespace v8::internal
diff --git a/src/string.js b/src/string.js
index 30eedb3..d97f632 100644
--- a/src/string.js
+++ b/src/string.js
@@ -611,7 +611,7 @@
   if (%_ObjectEquals(cache.type, 'split') &&
       %_IsRegExpEquivalent(cache.regExp, separator) &&
       %_ObjectEquals(cache.subject, subject) &&
-      %_ObjectEquals(cache.lastIndex, limit)) {
+      %_ObjectEquals(cache.splitLimit, limit)) {
     if (cache.answerSaved) {
       return CloneDenseArray(cache.answer);
     } else {
@@ -622,8 +622,7 @@
   cache.type = 'split';
   cache.regExp = separator;
   cache.subject = subject;
-  // Reuse lastIndex field for split limit when type is "split".
-  cache.lastIndex = limit;
+  cache.splitLimit = limit;
 
   %_Log('regexp', 'regexp-split,%0S,%1r', [subject, separator]);
 
diff --git a/src/strtod.cc b/src/strtod.cc
new file mode 100644
index 0000000..ae278bd
--- /dev/null
+++ b/src/strtod.cc
@@ -0,0 +1,214 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdarg.h>
+#include <limits.h>
+
+#include "v8.h"
+
+#include "strtod.h"
+// #include "cached-powers.h"
+
+namespace v8 {
+namespace internal {
+
+// 2^53 = 9007199254740992.
+// Any integer with at most 15 decimal digits will hence fit into a double
+// (which has a 53bit significand) without loss of precision.
+static const int kMaxExactDoubleIntegerDecimalDigits = 15;
+// 2^64 = 18446744073709551616
+// Any integer with at most 19 digits will hence fit into a 64bit datatype.
+static const int kMaxUint64DecimalDigits = 19;
+// Max double: 1.7976931348623157 x 10^308
+// Min non-zero double: 4.9406564584124654 x 10^-324
+// Any x >= 10^309 is interpreted as +infinity.
+// Any x <= 10^-324 is interpreted as 0.
+// Note that 2.5e-324 (despite being smaller than the min double) will be read
+// as non-zero (equal to the min non-zero double).
+static const int kMaxDecimalPower = 309;
+static const int kMinDecimalPower = -324;
+
+static const double exact_powers_of_ten[] = {
+  1.0,  // 10^0
+  10.0,
+  100.0,
+  1000.0,
+  10000.0,
+  100000.0,
+  1000000.0,
+  10000000.0,
+  100000000.0,
+  1000000000.0,
+  10000000000.0,  // 10^10
+  100000000000.0,
+  1000000000000.0,
+  10000000000000.0,
+  100000000000000.0,
+  1000000000000000.0,
+  10000000000000000.0,
+  100000000000000000.0,
+  1000000000000000000.0,
+  10000000000000000000.0,
+  100000000000000000000.0,  // 10^20
+  1000000000000000000000.0,
+  // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
+  10000000000000000000000.0
+};
+
+static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);
+
+
+extern "C" double gay_strtod(const char* s00, const char** se);
+
+static double old_strtod(Vector<const char> buffer, int exponent) {
+  // gay_strtod is broken on Linux,x86. For numbers with few decimal digits
+  // the computation is done using floating-point operations which (on Linux)
+  // are prone to double-rounding errors.
+  // By adding several zeroes to the buffer gay_strtod falls back to a slower
+  // (but correct) algorithm.
+  const int kInsertedZeroesCount = 20;
+  char gay_buffer[1024];
+  Vector<char> gay_buffer_vector(gay_buffer, sizeof(gay_buffer));
+  int pos = 0;
+  for (int i = 0; i < buffer.length(); ++i) {
+    gay_buffer_vector[pos++] = buffer[i];
+  }
+  for (int i = 0; i < kInsertedZeroesCount; ++i) {
+    gay_buffer_vector[pos++] = '0';
+  }
+  exponent -= kInsertedZeroesCount;
+  gay_buffer_vector[pos++] = 'e';
+  if (exponent < 0) {
+    gay_buffer_vector[pos++] = '-';
+    exponent = -exponent;
+  }
+  const int kNumberOfExponentDigits = 5;
+  for (int i = kNumberOfExponentDigits - 1; i >= 0; i--) {
+    gay_buffer_vector[pos + i] = exponent % 10 + '0';
+    exponent /= 10;
+  }
+  pos += kNumberOfExponentDigits;
+  gay_buffer_vector[pos] = '\0';
+  return gay_strtod(gay_buffer, NULL);
+}
+
+
+static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
+  for (int i = 0; i < buffer.length(); i++) {
+    if (buffer[i] != '0') {
+      return Vector<const char>(buffer.start() + i, buffer.length() - i);
+    }
+  }
+  return Vector<const char>(buffer.start(), 0);
+}
+
+
+static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
+  for (int i = buffer.length() - 1; i >= 0; --i) {
+    if (buffer[i] != '0') {
+      return Vector<const char>(buffer.start(), i + 1);
+    }
+  }
+  return Vector<const char>(buffer.start(), 0);
+}
+
+
+uint64_t ReadUint64(Vector<const char> buffer) {
+  ASSERT(buffer.length() <= kMaxUint64DecimalDigits);
+  uint64_t result = 0;
+  for (int i = 0; i < buffer.length(); ++i) {
+    int digit = buffer[i] - '0';
+    ASSERT(0 <= digit && digit <= 9);
+    result = 10 * result + digit;
+  }
+  return result;
+}
+
+
+static bool DoubleStrtod(Vector<const char> trimmed,
+                         int exponent,
+                         double* result) {
+#if (defined(V8_TARGET_ARCH_IA32) || defined(USE_SIMULATOR)) && !defined(WIN32)
+  // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
+  // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
+  // result is not accurate.
+  // We know that Windows32 uses 64 bits and is therefore accurate.
+  // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
+  // the same problem.
+  return false;
+#endif
+  if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
+    // The trimmed input fits into a double.
+    // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
+    // can compute the result-double simply by multiplying (resp. dividing) the
+    // two numbers.
+    // This is possible because IEEE guarantees that floating-point operations
+    // return the best possible approximation.
+    if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
+      // 10^-exponent fits into a double.
+      *result = static_cast<double>(ReadUint64(trimmed));
+      *result /= exact_powers_of_ten[-exponent];
+      return true;
+    }
+    if (0 <= exponent && exponent < kExactPowersOfTenSize) {
+      // 10^exponent fits into a double.
+      *result = static_cast<double>(ReadUint64(trimmed));
+      *result *= exact_powers_of_ten[exponent];
+      return true;
+    }
+    int remaining_digits =
+        kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
+    if ((0 <= exponent) &&
+        (exponent - remaining_digits < kExactPowersOfTenSize)) {
+      // The trimmed string was short and we can multiply it with
+      // 10^remaining_digits. As a result the remaining exponent now fits
+      // into a double too.
+      *result = static_cast<double>(ReadUint64(trimmed));
+      *result *= exact_powers_of_ten[remaining_digits];
+      *result *= exact_powers_of_ten[exponent - remaining_digits];
+      return true;
+    }
+  }
+  return false;
+}
+
+
+double Strtod(Vector<const char> buffer, int exponent) {
+  Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
+  Vector<const char> trimmed = TrimTrailingZeros(left_trimmed);
+  exponent += left_trimmed.length() - trimmed.length();
+  if (trimmed.length() == 0) return 0.0;
+  if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) return V8_INFINITY;
+  if (exponent + trimmed.length() <= kMinDecimalPower) return 0.0;
+  double result;
+  if (DoubleStrtod(trimmed, exponent, &result)) {
+    return result;
+  }
+  return old_strtod(trimmed, exponent);
+}
+
+} }  // namespace v8::internal
diff --git a/src/vm-state.cc b/src/strtod.h
similarity index 85%
copy from src/vm-state.cc
copy to src/strtod.h
index 6bd737d..1a5a96c 100644
--- a/src/vm-state.cc
+++ b/src/strtod.h
@@ -25,15 +25,16 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "v8.h"
-
-#include "vm-state.h"
+#ifndef V8_STRTOD_H_
+#define V8_STRTOD_H_
 
 namespace v8 {
 namespace internal {
 
-#ifdef ENABLE_VMSTATE_TRACKING
-AtomicWord VMState::current_state_ = 0;
-#endif
+// The buffer must only contain digits in the range [0-9]. It must not
+// contain a dot or a sign. It must not start with '0', and must not be empty.
+double Strtod(Vector<const char> buffer, int exponent);
 
 } }  // namespace v8::internal
+
+#endif  // V8_STRTOD_H_
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 6b41577..e6df1b4 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -988,6 +988,7 @@
 
 Object* KeyedLoadPropertyWithInterceptor(Arguments args) {
   JSObject* receiver = JSObject::cast(args[0]);
+  ASSERT(Smi::cast(args[1])->value() >= 0);
   uint32_t index = Smi::cast(args[1])->value();
   return receiver->GetElementWithInterceptor(receiver, index);
 }
diff --git a/src/stub-cache.h b/src/stub-cache.h
index c47cab7..e4a9e95 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -626,7 +626,8 @@
   V(String.prototype, charCodeAt, StringCharCodeAt) \
   V(String.prototype, charAt, StringCharAt)         \
   V(String, fromCharCode, StringFromCharCode)       \
-  V(Math, floor, MathFloor)
+  V(Math, floor, MathFloor)                         \
+  V(Math, abs, MathAbs)
 
 
 class CallStubCompiler: public StubCompiler {
diff --git a/src/top.cc b/src/top.cc
index e172cb8..9ce6542 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -69,6 +69,9 @@
 #ifdef ENABLE_LOGGING_AND_PROFILING
   js_entry_sp_ = 0;
 #endif
+#ifdef ENABLE_VMSTATE_TRACKING
+  current_vm_state_ = NULL;
+#endif
   try_catch_handler_address_ = NULL;
   context_ = NULL;
   int id = ThreadManager::CurrentId();
@@ -344,6 +347,10 @@
   Handle<String> column_key =  Factory::LookupAsciiSymbol("column");
   Handle<String> line_key =  Factory::LookupAsciiSymbol("lineNumber");
   Handle<String> script_key =  Factory::LookupAsciiSymbol("scriptName");
+  Handle<String> name_or_source_url_key =
+      Factory::LookupAsciiSymbol("nameOrSourceURL");
+  Handle<String> script_name_or_source_url_key =
+      Factory::LookupAsciiSymbol("scriptNameOrSourceURL");
   Handle<String> function_key =  Factory::LookupAsciiSymbol("functionName");
   Handle<String> eval_key =  Factory::LookupAsciiSymbol("isEval");
   Handle<String> constructor_key =  Factory::LookupAsciiSymbol("isConstructor");
@@ -355,13 +362,13 @@
     Handle<JSObject> stackFrame = Factory::NewJSObject(object_function());
 
     JavaScriptFrame* frame = it.frame();
-    JSFunction* fun(JSFunction::cast(frame->function()));
-    Script* script = Script::cast(fun->shared()->script());
+    Handle<JSFunction> fun(JSFunction::cast(frame->function()));
+    Handle<Script> script(Script::cast(fun->shared()->script()));
 
     if (options & StackTrace::kLineNumber) {
       int script_line_offset = script->line_offset()->value();
       int position = frame->code()->SourcePosition(frame->pc());
-      int line_number = GetScriptLineNumber(Handle<Script>(script), position);
+      int line_number = GetScriptLineNumber(script, position);
       // line_number is already shifted by the script_line_offset.
       int relative_line_number = line_number - script_line_offset;
       if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
@@ -385,6 +392,22 @@
       SetProperty(stackFrame, script_key, script_name, NONE);
     }
 
+    if (options & StackTrace::kScriptNameOrSourceURL) {
+      Handle<Object> script_name(script->name());
+      Handle<JSValue> script_wrapper = GetScriptWrapper(script);
+      Handle<Object> property = GetProperty(script_wrapper,
+                                            name_or_source_url_key);
+      ASSERT(property->IsJSFunction());
+      Handle<JSFunction> method = Handle<JSFunction>::cast(property);
+      bool caught_exception;
+      Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
+                                                 NULL, &caught_exception);
+      if (caught_exception) {
+        result = Factory::undefined_value();
+      }
+      SetProperty(stackFrame, script_name_or_source_url_key, result, NONE);
+    }
+
     if (options & StackTrace::kFunctionName) {
       Handle<Object> fun_name(fun->shared()->name());
       if (fun_name->ToBoolean()->IsFalse()) {
diff --git a/src/top.h b/src/top.h
index 776c43e..a2ba3dd 100644
--- a/src/top.h
+++ b/src/top.h
@@ -41,6 +41,7 @@
 
 class SaveContext;  // Forward declaration.
 class ThreadVisitor;  // Defined in v8threads.h
+class VMState;  // Defined in vm-state.h
 
 class ThreadLocalTop BASE_EMBEDDED {
  public:
@@ -101,10 +102,15 @@
   // Stack.
   Address c_entry_fp_;  // the frame pointer of the top c entry frame
   Address handler_;   // try-blocks are chained through the stack
+
 #ifdef ENABLE_LOGGING_AND_PROFILING
   Address js_entry_sp_;  // the stack pointer of the bottom js entry frame
 #endif
 
+#ifdef ENABLE_VMSTATE_TRACKING
+  VMState* current_vm_state_;
+#endif
+
   // Generated code scratch locations.
   int32_t formal_count_;
 
@@ -254,6 +260,16 @@
   }
 #endif
 
+#ifdef ENABLE_VMSTATE_TRACKING
+  static VMState* current_vm_state() {
+    return thread_local_.current_vm_state_;
+  }
+
+  static void set_current_vm_state(VMState* state) {
+    thread_local_.current_vm_state_ = state;
+  }
+#endif
+
   // Generated code scratch locations.
   static void* formal_count_address() { return &thread_local_.formal_count_; }
 
diff --git a/src/utils.h b/src/utils.h
index fefbfe9..ffdb639 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -222,11 +222,21 @@
 // ----------------------------------------------------------------------------
 // I/O support.
 
-// Our version of printf(). Avoids compilation errors that we get
-// with standard printf when attempting to print pointers, etc.
-// (the errors are due to the extra compilation flags, which we
-// want elsewhere).
-void PrintF(const char* format, ...);
+#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();
diff --git a/src/v8-counters.h b/src/v8-counters.h
index a8eb9d2..60e8741 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -45,14 +45,7 @@
   /* Total compilation times. */                                      \
   HT(compile, V8.Compile)                                             \
   HT(compile_eval, V8.CompileEval)                                    \
-  HT(compile_lazy, V8.CompileLazy)                                    \
-  /* Individual compiler passes. */                                   \
-  HT(rewriting, V8.Rewriting)                                         \
-  HT(usage_analysis, V8.UsageAnalysis)                                \
-  HT(variable_allocation, V8.VariableAllocation)                      \
-  HT(ast_optimization, V8.ASTOptimization)                            \
-  HT(code_generation, V8.CodeGeneration)                              \
-  HT(deferred_code_generation, V8.DeferredCodeGeneration)
+  HT(compile_lazy, V8.CompileLazy)
 
 
 // WARNING: STATS_COUNTER_LIST_* is a very large macro that is causing MSVC
@@ -161,6 +154,8 @@
   SC(named_load_inline_miss, V8.NamedLoadInlineMiss)                  \
   SC(named_load_global_inline, V8.NamedLoadGlobalInline)              \
   SC(named_load_global_inline_miss, V8.NamedLoadGlobalInlineMiss)     \
+  SC(dont_delete_hint_hit, V8.DontDeleteHintHit)                      \
+  SC(dont_delete_hint_miss, V8.DontDeleteHintMiss)                    \
   SC(named_load_global_stub, V8.NamedLoadGlobalStub)                  \
   SC(named_load_global_stub_miss, V8.NamedLoadGlobalStubMiss)         \
   SC(keyed_store_field, V8.KeyedStoreField)                           \
diff --git a/src/v8.cc b/src/v8.cc
index 2313967..b30564a 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -68,7 +68,7 @@
   OS::Setup();
 
   // Initialize other runtime facilities
-#if !V8_HOST_ARCH_ARM && V8_TARGET_ARCH_ARM
+#if (defined(USE_SIMULATOR) || !V8_HOST_ARCH_ARM) && V8_TARGET_ARCH_ARM
   ::assembler::arm::Simulator::Initialize();
 #endif
 
diff --git a/src/v8natives.js b/src/v8natives.js
index ca1c99d..88aea9c 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -547,11 +547,11 @@
 
   if (!IS_UNDEFINED(current) && !current.isConfigurable()) {
     // Step 5 and 6
-    if ((!desc.hasEnumerable() || 
+    if ((!desc.hasEnumerable() ||
          SameValue(desc.isEnumerable() && current.isEnumerable())) &&
-        (!desc.hasConfigurable() || 
+        (!desc.hasConfigurable() ||
          SameValue(desc.isConfigurable(), current.isConfigurable())) &&
-        (!desc.hasWritable() || 
+        (!desc.hasWritable() ||
          SameValue(desc.isWritable(), current.isWritable())) &&
         (!desc.hasValue() ||
          SameValue(desc.getValue(), current.getValue())) &&
@@ -755,7 +755,7 @@
     var desc = GetOwnProperty(obj, name);
     if (desc.isConfigurable()) desc.setConfigurable(false);
     DefineOwnProperty(obj, name, desc, true);
-  }  
+  }
   return ObjectPreventExtension(obj);
 }
 
@@ -772,7 +772,7 @@
     if (IsDataDescriptor(desc)) desc.setWritable(false);
     if (desc.isConfigurable()) desc.setConfigurable(false);
     DefineOwnProperty(obj, name, desc, true);
-  }  
+  }
   return ObjectPreventExtension(obj);
 }
 
@@ -1118,12 +1118,12 @@
     var bound_args = new $Array(argc_bound);
     for(var i = 0; i < argc_bound; i++) {
       bound_args[i] = %_Arguments(i+1);
-    }  
+    }
   }
   var fn = this;
   var result = function() {
     // Combine the args we got from the bind call with the args
-    // given as argument to the invocation. 
+    // given as argument to the invocation.
     var argc = %_ArgumentsLength();
     var args = new $Array(argc + argc_bound);
     // Add bound arguments.
@@ -1132,7 +1132,7 @@
     }
     // Add arguments from call.
     for (var i = 0; i < argc; i++) {
-      args[argc_bound + i] = %_Arguments(i); 
+      args[argc_bound + i] = %_Arguments(i);
     }
     // If this is a construct call we use a special runtime method
     // to generate the actual object using the bound function.
@@ -1147,7 +1147,7 @@
   // try to redefine these as defined by the spec. The spec says
   // that bind should make these throw a TypeError if get or set
   // is called and make them non-enumerable and non-configurable.
-  // To be consistent with our normal functions we leave this as it is. 
+  // To be consistent with our normal functions we leave this as it is.
 
   // Set the correct length.
   var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0;
diff --git a/src/version.cc b/src/version.cc
index 5be1e82..6d98b04 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -33,10 +33,10 @@
 // NOTE these macros are used by the SCons build script so their names
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     2
-#define MINOR_VERSION     4
-#define BUILD_NUMBER      7
+#define MINOR_VERSION     5
+#define BUILD_NUMBER      1
 #define PATCH_LEVEL       0
-#define CANDIDATE_VERSION true
+#define CANDIDATE_VERSION false
 
 // Define SONAME to have the SCons build the put a specific SONAME into the
 // shared library instead the generic SONAME generated from the V8 version
diff --git a/src/vm-state-inl.h b/src/vm-state-inl.h
index aa4cedb..74f4a6a 100644
--- a/src/vm-state-inl.h
+++ b/src/vm-state-inl.h
@@ -75,9 +75,9 @@
 #endif
   state_ = state;
   // Save the previous state.
-  previous_ = reinterpret_cast<VMState*>(current_state_);
+  previous_ = Top::current_vm_state();
   // Install the new state.
-  OS::ReleaseStore(&current_state_, reinterpret_cast<AtomicWord>(this));
+  Top::set_current_vm_state(this);
 
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_state_changes) {
@@ -106,7 +106,7 @@
 VMState::~VMState() {
   if (disabled_) return;
   // Return to the previous state.
-  OS::ReleaseStore(&current_state_, reinterpret_cast<AtomicWord>(previous_));
+  Top::set_current_vm_state(previous_);
 
 #ifdef ENABLE_LOGGING_AND_PROFILING
   if (FLAG_log_state_changes) {
diff --git a/src/vm-state.h b/src/vm-state.h
index 080eb8d..cc91e83 100644
--- a/src/vm-state.h
+++ b/src/vm-state.h
@@ -28,6 +28,8 @@
 #ifndef V8_VM_STATE_H_
 #define V8_VM_STATE_H_
 
+#include "top.h"
+
 namespace v8 {
 namespace internal {
 
@@ -44,16 +46,16 @@
 
   // Used for debug asserts.
   static bool is_outermost_external() {
-    return current_state_ == 0;
+    return Top::current_vm_state() == 0;
   }
 
   static StateTag current_state() {
-    VMState* state = reinterpret_cast<VMState*>(current_state_);
+    VMState* state = Top::current_vm_state();
     return state ? state->state() : EXTERNAL;
   }
 
   static Address external_callback() {
-    VMState* state = reinterpret_cast<VMState*>(current_state_);
+    VMState* state = Top::current_vm_state();
     return state ? state->external_callback_ : NULL;
   }
 
@@ -63,8 +65,6 @@
   VMState* previous_;
   Address external_callback_;
 
-  // A stack of VM states.
-  static AtomicWord current_state_;
 #else
  public:
   explicit VMState(StateTag state) {}
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 08c19ba..0dead6b 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -715,7 +715,7 @@
   __ cmpq(rax, Immediate(1));
   __ j(not_equal, &argc_two_or_more);
   __ movq(rdx, Operand(rsp, kPointerSize));  // Get the argument from the stack.
-  __ JumpIfNotPositiveSmi(rdx, call_generic_code);
+  __ JumpUnlessNonNegativeSmi(rdx, call_generic_code);
 
   // Handle construction of an empty array of a certain size. Bail out if size
   // is to large to actually allocate an elements array.
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 9d82e0e..2d87667 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -1413,20 +1413,8 @@
         __ j(equal, &done);
       }
       __ SmiNeg(rax, rax, &done);
+      __ jmp(&slow);  // zero, if not handled above, and Smi::kMinValue.
 
-      // Either zero or Smi::kMinValue, neither of which become a smi when
-      // negated. We handle negative zero here if required. We always enter
-      // the runtime system if we have Smi::kMinValue.
-      if (negative_zero_ == kStrictNegativeZero) {
-        __ SmiCompare(rax, Smi::FromInt(0));
-        __ j(not_equal, &slow);
-        __ Move(rax, Factory::minus_zero_value());
-        __ jmp(&done);
-      } else  {
-        __ SmiCompare(rax, Smi::FromInt(Smi::kMinValue));
-        __ j(equal, &slow);
-        __ jmp(&done);
-      }
       // Try floating point case.
       __ bind(&try_float);
     } else if (FLAG_debug_code) {
@@ -2135,7 +2123,7 @@
     __ JumpIfNotBothSmi(rax, rdx, &non_smi);
     __ subq(rdx, rax);
     __ j(no_overflow, &smi_done);
-    __ neg(rdx);  // Correct sign in case of overflow.
+    __ not_(rdx);  // Correct sign in case of overflow. rdx cannot be 0 here.
     __ bind(&smi_done);
     __ movq(rax, rdx);
     __ ret(0);
@@ -2406,16 +2394,7 @@
 
 
 void StackCheckStub::Generate(MacroAssembler* masm) {
-  // Because builtins always remove the receiver from the stack, we
-  // have to fake one to avoid underflowing the stack. The receiver
-  // must be inserted below the return address on the stack so we
-  // temporarily store that in a register.
-  __ pop(rax);
-  __ Push(Smi::FromInt(0));
-  __ push(rax);
-
-  // Do tail-call to runtime routine.
-  __ TailCallRuntime(Runtime::kStackGuard, 1, 1);
+  __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
 }
 
 
@@ -3801,7 +3780,7 @@
   Label result_longer_than_two;
   __ movq(rcx, Operand(rsp, kToOffset));
   __ movq(rdx, Operand(rsp, kFromOffset));
-  __ JumpIfNotBothPositiveSmi(rcx, rdx, &runtime);
+  __ JumpUnlessBothNonNegativeSmi(rcx, rdx, &runtime);
 
   __ SmiSub(rcx, rcx, rdx);  // Overflow doesn't happen.
   __ cmpq(FieldOperand(rax, String::kLengthOffset), rcx);
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 0d8b827..9e6ef3b 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -178,22 +178,12 @@
 
   // Adjust for function-level loop nesting.
   ASSERT_EQ(0, loop_nesting_);
-  loop_nesting_ = info->loop_nesting();
+  loop_nesting_ = info->is_in_loop() ? 1 : 0;
 
   JumpTarget::set_compiling_deferred_code(false);
 
-#ifdef DEBUG
-  if (strlen(FLAG_stop_at) > 0 &&
-      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
-    frame_->SpillAll();
-    __ int3();
-  }
-#endif
-
-  // New scope to get automatic timing calculation.
-  { HistogramTimerScope codegen_timer(&Counters::code_generation);
+  {
     CodeGenState state(this);
-
     // Entry:
     // Stack: receiver, arguments, return address.
     // rbp: caller's frame pointer
@@ -202,6 +192,14 @@
     // rsi: callee's context
     allocator_->Initialize();
 
+#ifdef DEBUG
+    if (strlen(FLAG_stop_at) > 0 &&
+        info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+      frame_->SpillAll();
+      __ int3();
+    }
+#endif
+
     frame_->Enter();
 
     // Allocate space for locals and initialize them.
@@ -356,7 +354,7 @@
   }
 
   // Adjust for function-level loop nesting.
-  ASSERT_EQ(loop_nesting_, info->loop_nesting());
+  ASSERT_EQ(loop_nesting_, info->is_in_loop() ? 1 : 0);
   loop_nesting_ = 0;
 
   // Code generation state must be reset.
@@ -367,7 +365,6 @@
 
   // Process any deferred code using the register allocator.
   if (!HasStackOverflow()) {
-    HistogramTimerScope deferred_timer(&Counters::deferred_code_generation);
     JumpTarget::set_compiling_deferred_code(true);
     ProcessDeferred();
     JumpTarget::set_compiling_deferred_code(false);
@@ -1884,8 +1881,7 @@
                                            operand->reg(),
                                            smi_value,
                                            overwrite_mode);
-        // Check for negative or non-Smi left hand side.
-        __ JumpIfNotPositiveSmi(operand->reg(), deferred->entry_label());
+        __ JumpUnlessNonNegativeSmi(operand->reg(), deferred->entry_label());
         if (int_value < 0) int_value = -int_value;
         if (int_value == 1) {
           __ Move(operand->reg(), Smi::FromInt(0));
@@ -4277,9 +4273,12 @@
 
   // Build the function info and instantiate it.
   Handle<SharedFunctionInfo> function_info =
-      Compiler::BuildFunctionInfo(node, script(), this);
+      Compiler::BuildFunctionInfo(node, script());
   // Check for stack-overflow exception.
-  if (HasStackOverflow()) return;
+  if (function_info.is_null()) {
+    SetStackOverflow();
+    return;
+  }
   InstantiateFunction(function_info);
 }
 
@@ -5684,9 +5683,9 @@
   Result value = frame_->Pop();
   value.ToRegister();
   ASSERT(value.is_valid());
-  Condition positive_smi = masm_->CheckPositiveSmi(value.reg());
+  Condition non_negative_smi = masm_->CheckNonNegativeSmi(value.reg());
   value.Unuse();
-  destination()->Split(positive_smi);
+  destination()->Split(non_negative_smi);
 }
 
 
@@ -6911,7 +6910,7 @@
   deferred->Branch(not_equal);
 
   // Check that both indices are smis.
-  Condition both_smi = __ CheckBothSmi(index1.reg(), index2.reg());
+  Condition both_smi = masm()->CheckBothSmi(index1.reg(), index2.reg());
   deferred->Branch(NegateCondition(both_smi));
 
   // Bring addresses into index1 and index2.
@@ -8377,7 +8376,7 @@
     }
 
     // Check that the receiver is a heap object.
-    Condition is_smi = __ CheckSmi(receiver.reg());
+    Condition is_smi = masm()->CheckSmi(receiver.reg());
     slow.Branch(is_smi, &value, &receiver);
 
     // This is the map check instruction that will be patched.
@@ -8506,8 +8505,7 @@
                 kScratchRegister);
     deferred->Branch(not_equal);
 
-    // Check that the key is a non-negative smi.
-    __ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label());
+    __ JumpUnlessNonNegativeSmi(key.reg(), deferred->entry_label());
 
     // Get the elements array from the receiver.
     __ movq(elements.reg(),
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 6e1dd72..7957324 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -298,9 +298,7 @@
 
 class CodeGenerator: public AstVisitor {
  public:
-  // Takes a function literal, generates code for it. This function should only
-  // be called by compiler.cc.
-  static Handle<Code> MakeCode(CompilationInfo* info);
+  static bool MakeCode(CompilationInfo* info);
 
   // Printing of AST, etc. as requested by flags.
   static void MakeCodePrologue(CompilationInfo* info);
@@ -586,9 +584,6 @@
 
   void CheckStack();
 
-  static InlineFunctionGenerator FindInlineFunctionGenerator(
-      Runtime::FunctionId function_id);
-
   bool CheckForInlineRuntimeCall(CallRuntime* node);
 
   void ProcessDeclarations(ZoneList<Declaration*>* declarations);
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index c15860c..32d6242 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -61,6 +61,12 @@
   SetFunctionPosition(function());
   Comment cmnt(masm_, "[ function compiled by full code generator");
 
+#ifdef DEBUG
+  if (strlen(FLAG_stop_at) > 0 &&
+      info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+    __ int3();
+  }
+#endif
   __ push(rbp);  // Caller's frame pointer.
   __ movq(rbp, rsp);
   __ push(rsi);  // Callee's context.
@@ -767,7 +773,7 @@
 
   // Get the current entry of the array into register rbx.
   __ movq(rbx, Operand(rsp, 2 * kPointerSize));
-  SmiIndex index = __ SmiToIndex(rax, rax, kPointerSizeLog2);
+  SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2);
   __ movq(rbx, FieldOperand(rbx,
                             index.reg,
                             index.scale,
@@ -1407,7 +1413,7 @@
   Label done, stub_call, smi_case;
   __ pop(rdx);
   __ movq(rcx, rax);
-  Condition smi = __ CheckBothSmi(rdx, rax);
+  Condition smi = masm()->CheckBothSmi(rdx, rax);
   __ j(smi, &smi_case);
 
   __ bind(&stub_call);
@@ -1965,8 +1971,8 @@
   context()->PrepareTest(&materialize_true, &materialize_false,
                          &if_true, &if_false, &fall_through);
 
-  Condition positive_smi = __ CheckPositiveSmi(rax);
-  Split(positive_smi, if_true, if_false, fall_through);
+  Condition non_negative_smi = masm()->CheckNonNegativeSmi(rax);
+  Split(non_negative_smi, if_true, if_false, fall_through);
 
   context()->Plug(if_true, if_false);
 }
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 62e7691..1d95b7f 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -893,8 +893,9 @@
   // Check that the receiver isn't a smi.
   __ JumpIfSmi(rdx, &slow);
 
-  // Check that the key is a smi.
-  __ JumpIfNotSmi(rax, &slow);
+  // Check that the key is an array index, that is Uint32.
+  STATIC_ASSERT(kSmiValueSize <= 32);
+  __ JumpUnlessNonNegativeSmi(rax, &slow);
 
   // Get the map of the receiver.
   __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
@@ -1728,7 +1729,8 @@
 
 bool LoadIC::PatchInlinedContextualLoad(Address address,
                                         Object* map,
-                                        Object* cell) {
+                                        Object* cell,
+                                        bool is_dont_delete) {
   // TODO(<bug#>): implement this.
   return false;
 }
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 869986e..2c946f5 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -825,7 +825,7 @@
 }
 
 
-Condition MacroAssembler::CheckPositiveSmi(Register src) {
+Condition MacroAssembler::CheckNonNegativeSmi(Register src) {
   ASSERT_EQ(0, kSmiTag);
   // Make mask 0x8000000000000001 and test that both bits are zero.
   movq(kScratchRegister, src);
@@ -846,15 +846,15 @@
 }
 
 
-Condition MacroAssembler::CheckBothPositiveSmi(Register first,
-                                               Register second) {
+Condition MacroAssembler::CheckBothNonNegativeSmi(Register first,
+                                                  Register second) {
   if (first.is(second)) {
-    return CheckPositiveSmi(first);
+    return CheckNonNegativeSmi(first);
   }
   movq(kScratchRegister, first);
   or_(kScratchRegister, second);
   rol(kScratchRegister, Immediate(1));
-  testl(kScratchRegister, Immediate(0x03));
+  testl(kScratchRegister, Immediate(3));
   return zero;
 }
 
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index a8ffca9..cb91067 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -101,9 +101,9 @@
   // dirty. |object| is the object being stored into, |value| is the
   // object being stored. If |offset| is zero, then the |scratch|
   // register contains the array index into the elements array
-  // represented as a Smi. All registers are clobbered by the
-  // operation. RecordWrite filters out smis so it does not update the
-  // write barrier if the value is a smi.
+  // represented as an untagged 32-bit integer. All registers are
+  // clobbered by the operation. RecordWrite filters out smis so it
+  // does not update the write barrier if the value is a smi.
   void RecordWrite(Register object,
                    int offset,
                    Register value,
@@ -122,7 +122,7 @@
   // The value is known to not be a smi.
   // object is the object being stored into, value is the object being stored.
   // If offset is zero, then the scratch register contains the array index into
-  // the elements array represented as a Smi.
+  // the elements array represented as an untagged 32-bit integer.
   // All registers are clobbered by the operation.
   void RecordWriteNonSmi(Register object,
                          int offset,
@@ -265,14 +265,14 @@
   // Is the value a tagged smi.
   Condition CheckSmi(Register src);
 
-  // Is the value a positive tagged smi.
-  Condition CheckPositiveSmi(Register src);
+  // Is the value a non-negative tagged smi.
+  Condition CheckNonNegativeSmi(Register src);
 
   // Are both values tagged smis.
   Condition CheckBothSmi(Register first, Register second);
 
-  // Are both values tagged smis.
-  Condition CheckBothPositiveSmi(Register first, Register second);
+  // Are both values non-negative tagged smis.
+  Condition CheckBothNonNegativeSmi(Register first, Register second);
 
   // Are either value a tagged smi.
   Condition CheckEitherSmi(Register first,
@@ -311,9 +311,9 @@
   template <typename LabelType>
   void JumpIfNotSmi(Register src, LabelType* on_not_smi);
 
-  // Jump to label if the value is not a positive tagged smi.
+  // Jump to label if the value is not a non-negative tagged smi.
   template <typename LabelType>
-  void JumpIfNotPositiveSmi(Register src, LabelType* on_not_smi);
+  void JumpUnlessNonNegativeSmi(Register src, LabelType* on_not_smi);
 
   // Jump to label if the value, which must be a tagged smi, has value equal
   // to the constant.
@@ -328,10 +328,10 @@
                         Register src2,
                         LabelType* on_not_both_smi);
 
-  // Jump if either or both register are not positive smi values.
+  // Jump if either or both register are not non-negative smi values.
   template <typename LabelType>
-  void JumpIfNotBothPositiveSmi(Register src1, Register src2,
-                                LabelType* on_not_both_smi);
+  void JumpUnlessBothNonNegativeSmi(Register src1, Register src2,
+                                    LabelType* on_not_both_smi);
 
   // Operations on tagged smi values.
 
@@ -1463,10 +1463,10 @@
 
 
 template <typename LabelType>
-void MacroAssembler::JumpIfNotPositiveSmi(Register src,
-                                          LabelType* on_not_positive_smi) {
-  Condition positive_smi = CheckPositiveSmi(src);
-  j(NegateCondition(positive_smi), on_not_positive_smi);
+void MacroAssembler::JumpUnlessNonNegativeSmi(
+    Register src, LabelType* on_not_smi_or_negative) {
+  Condition non_negative_smi = CheckNonNegativeSmi(src);
+  j(NegateCondition(non_negative_smi), on_not_smi_or_negative);
 }
 
 
@@ -1505,10 +1505,10 @@
 
 
 template <typename LabelType>
-void MacroAssembler::JumpIfNotBothPositiveSmi(Register src1,
-                                              Register src2,
-                                              LabelType* on_not_both_smi) {
-  Condition both_smi = CheckBothPositiveSmi(src1, src2);
+void MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1,
+                                                  Register src2,
+                                                  LabelType* on_not_both_smi) {
+  Condition both_smi = CheckBothNonNegativeSmi(src1, src2);
   j(NegateCondition(both_smi), on_not_both_smi);
 }
 
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 91e2b44..47c19c7 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -145,7 +145,6 @@
 
 void RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) {
   if (by != 0) {
-    Label inside_string;
     __ addq(rdi, Immediate(by * char_size()));
   }
 }
@@ -1053,6 +1052,19 @@
 }
 
 
+void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) {
+  NearLabel after_position;
+  __ cmpq(rdi, Immediate(-by * char_size()));
+  __ j(greater_equal, &after_position);
+  __ movq(rdi, Immediate(-by * char_size()));
+  // On RegExp code entry (where this operation is used), the character before
+  // the current position is expected to be already loaded.
+  // We have advanced the position, so it's safe to read backwards.
+  LoadCurrentCharacterUnchecked(-1, 1);
+  __ bind(&after_position);
+}
+
+
 void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) {
   ASSERT(register_index >= num_saved_registers_);  // Reserved for positions!
   __ movq(register_location(register_index), Immediate(to));
diff --git a/src/x64/regexp-macro-assembler-x64.h b/src/x64/regexp-macro-assembler-x64.h
index 3bcc3ac..182bc55 100644
--- a/src/x64/regexp-macro-assembler-x64.h
+++ b/src/x64/regexp-macro-assembler-x64.h
@@ -93,6 +93,7 @@
                             StackCheckFlag check_stack_limit);
   virtual void ReadCurrentPositionFromRegister(int reg);
   virtual void ReadStackPointerFromRegister(int reg);
+  virtual void SetCurrentPositionFromEnd(int by);
   virtual void SetRegister(int register_index, int to);
   virtual void Succeed();
   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 68b18a2..eb48da9 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -1558,6 +1558,109 @@
 }
 
 
+Object* CallStubCompiler::CompileMathAbsCall(Object* object,
+                                             JSObject* holder,
+                                             JSGlobalPropertyCell* cell,
+                                             JSFunction* function,
+                                             String* name) {
+  // ----------- S t a t e -------------
+  //  -- rcx                 : function name
+  //  -- rsp[0]              : return address
+  //  -- rsp[(argc - n) * 8] : arg[n] (zero-based)
+  //  -- ...
+  //  -- rsp[(argc + 1) * 8] : receiver
+  // -----------------------------------
+
+  const int argc = arguments().immediate();
+
+  // If the object is not a JSObject or we got an unexpected number of
+  // arguments, bail out to the regular call.
+  if (!object->IsJSObject() || argc != 1) return Heap::undefined_value();
+
+  Label miss;
+  GenerateNameCheck(name, &miss);
+
+  if (cell == NULL) {
+    __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+
+    __ JumpIfSmi(rdx, &miss);
+
+    CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name,
+                    &miss);
+  } else {
+    ASSERT(cell->value() == function);
+    GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
+    GenerateLoadFunctionFromCell(cell, function, &miss);
+  }
+
+  // Load the (only) argument into rax.
+  __ movq(rax, Operand(rsp, 1 * kPointerSize));
+
+  // Check if the argument is a smi.
+  Label not_smi;
+  STATIC_ASSERT(kSmiTag == 0);
+  __ JumpIfNotSmi(rax, &not_smi);
+  __ SmiToInteger32(rax, rax);
+
+  // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
+  // otherwise.
+  __ movl(rbx, rax);
+  __ sarl(rbx, Immediate(kBitsPerInt - 1));
+
+  // Do bitwise not or do nothing depending on ebx.
+  __ xorl(rax, rbx);
+
+  // Add 1 or do nothing depending on ebx.
+  __ subl(rax, rbx);
+
+  // If the result is still negative, go to the slow case.
+  // This only happens for the most negative smi.
+  Label slow;
+  __ j(negative, &slow);
+
+  // Smi case done.
+  __ Integer32ToSmi(rax, rax);
+  __ ret(2 * kPointerSize);
+
+  // Check if the argument is a heap number and load its value.
+  __ bind(&not_smi);
+  __ CheckMap(rax, Factory::heap_number_map(), &slow, true);
+  __ movq(rbx, FieldOperand(rax, HeapNumber::kValueOffset));
+
+  // Check the sign of the argument. If the argument is positive,
+  // just return it.
+  Label negative_sign;
+  const int sign_mask_shift =
+      (HeapNumber::kExponentOffset - HeapNumber::kValueOffset) * kBitsPerByte;
+  __ movq(rdi, static_cast<int64_t>(HeapNumber::kSignMask) << sign_mask_shift,
+          RelocInfo::NONE);
+  __ testq(rbx, rdi);
+  __ j(not_zero, &negative_sign);
+  __ ret(2 * kPointerSize);
+
+  // If the argument is negative, clear the sign, and return a new
+  // number. We still have the sign mask in rdi.
+  __ bind(&negative_sign);
+  __ xor_(rbx, rdi);
+  __ AllocateHeapNumber(rax, rdx, &slow);
+  __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
+  __ ret(2 * kPointerSize);
+
+  // Tail call the full function. We do not have to patch the receiver
+  // because the function makes no use of it.
+  __ bind(&slow);
+  __ InvokeFunction(function, arguments(), JUMP_FUNCTION);
+
+  __ bind(&miss);
+  // rcx: function name.
+  Object* obj = GenerateMissBranch();
+  if (obj->IsFailure()) return obj;
+
+  // Return the generated code.
+  return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
+}
+
+
 Object* CallStubCompiler::CompileCallInterceptor(JSObject* object,
                                                  JSObject* holder,
                                                  String* name) {
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index 3ec621e..006653c 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -70,6 +70,7 @@
     'test-sockets.cc',
     'test-spaces.cc',
     'test-strings.cc',
+    'test-strtod.cc',
     'test-thread-termination.cc',
     'test-threads.cc',
     'test-type-info.cc',
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index d03f5f7..895e245 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -35,11 +35,6 @@
 # BUG(382): Weird test. Can't guarantee that it never times out.
 test-api/ApplyInterruption: PASS || TIMEOUT
 
-# Bug (484): This test which we thought was originally corrected in r5236
-# is reappering. Disabled until bug in test is fixed. This only fails
-# when snapshot is on, so I am marking it PASS || FAIL
-test-heap-profiler/HeapSnapshotsDiff: PASS || FAIL
-
 # These tests always fail.  They are here to test test.py.  If
 # they don't fail then test.py has failed.
 test-serialize/TestThatAlwaysFails: FAIL
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index 315a34e..2936d6e 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -37,13 +37,13 @@
 
 static Object* AllocateAfterFailures() {
   static int attempts = 0;
-  if (++attempts < 3) return Failure::RetryAfterGC(0);
+  if (++attempts < 3) return Failure::RetryAfterGC();
 
   // New space.
   NewSpace* new_space = Heap::new_space();
   static const int kNewSpaceFillerSize = ByteArray::SizeFor(0);
   while (new_space->Available() > kNewSpaceFillerSize) {
-    int available_before = new_space->Available();
+    int available_before = static_cast<int>(new_space->Available());
     CHECK(!Heap::AllocateByteArray(0)->IsFailure());
     if (available_before == new_space->Available()) {
       // It seems that we are avoiding new space allocations when
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 1b6359b..fd44aec 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -431,8 +431,8 @@
     LocalContext env;
     Local<String> source = String::New(two_byte_source);
     // Trigger GCs so that the newly allocated string moves to old gen.
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in old gen now
     bool success = source->MakeExternal(new TestResource(two_byte_source));
     CHECK(success);
     Local<Script> script = Script::Compile(source);
@@ -456,8 +456,8 @@
     LocalContext env;
     Local<String> source = v8_str(c_source);
     // Trigger GCs so that the newly allocated string moves to old gen.
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in old gen now
     bool success = source->MakeExternal(
         new TestAsciiResource(i::StrDup(c_source)));
     CHECK(success);
@@ -479,8 +479,8 @@
   LocalContext env;
 
   // Free some space in the new space so that we can check freshness.
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+  i::Heap::CollectGarbage(i::NEW_SPACE);
+  i::Heap::CollectGarbage(i::NEW_SPACE);
 
   uint16_t* two_byte_string = AsciiToTwoByteString("small");
   Local<String> small_string = String::New(two_byte_string);
@@ -489,8 +489,8 @@
   // We should refuse to externalize newly created small string.
   CHECK(!small_string->CanMakeExternal());
   // Trigger GCs so that the newly allocated string moves to old gen.
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+  i::Heap::CollectGarbage(i::NEW_SPACE);  // in survivor space now
+  i::Heap::CollectGarbage(i::NEW_SPACE);  // in old gen now
   // Old space strings should be accepted.
   CHECK(small_string->CanMakeExternal());
 
@@ -525,15 +525,15 @@
   LocalContext env;
 
   // Free some space in the new space so that we can check freshness.
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);
+  i::Heap::CollectGarbage(i::NEW_SPACE);
+  i::Heap::CollectGarbage(i::NEW_SPACE);
 
   Local<String> small_string = String::New("small");
   // We should refuse to externalize newly created small string.
   CHECK(!small_string->CanMakeExternal());
   // Trigger GCs so that the newly allocated string moves to old gen.
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
-  i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+  i::Heap::CollectGarbage(i::NEW_SPACE);  // in survivor space now
+  i::Heap::CollectGarbage(i::NEW_SPACE);  // in old gen now
   // Old space strings should be accepted.
   CHECK(small_string->CanMakeExternal());
 
@@ -565,8 +565,8 @@
         String::NewExternal(new TestResource(two_byte_string));
     i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
     // Trigger GCs so that the newly allocated string moves to old gen.
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in old gen now
     i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring);
     CHECK(isymbol->IsSymbol());
   }
@@ -583,8 +583,8 @@
         new TestAsciiResource(i::StrDup(one_byte_string)));
     i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
     // Trigger GCs so that the newly allocated string moves to old gen.
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in survivor space now
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);  // in old gen now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in survivor space now
+    i::Heap::CollectGarbage(i::NEW_SPACE);  // in old gen now
     i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring);
     CHECK(isymbol->IsSymbol());
   }
@@ -602,12 +602,12 @@
     Local<String> string =
         String::NewExternal(new TestResource(two_byte_string));
     i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);
+    i::Heap::CollectGarbage(i::NEW_SPACE);
     in_new_space = i::Heap::InNewSpace(*istring);
     CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring));
     CHECK_EQ(0, TestResource::dispose_count);
   }
-  i::Heap::CollectGarbage(0, in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
+  i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
   CHECK_EQ(1, TestResource::dispose_count);
 }
 
@@ -621,12 +621,12 @@
     Local<String> string = String::NewExternal(
         new TestAsciiResource(i::StrDup(one_byte_string)));
     i::Handle<i::String> istring = v8::Utils::OpenHandle(*string);
-    i::Heap::CollectGarbage(0, i::NEW_SPACE);
+    i::Heap::CollectGarbage(i::NEW_SPACE);
     in_new_space = i::Heap::InNewSpace(*istring);
     CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring));
     CHECK_EQ(0, TestAsciiResource::dispose_count);
   }
-  i::Heap::CollectGarbage(0, in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
+  i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE);
   CHECK_EQ(1, TestAsciiResource::dispose_count);
 }
 
@@ -766,6 +766,12 @@
   return args.This();
 }
 
+static v8::Handle<Value> Return239(Local<String> name, const AccessorInfo&) {
+  ApiTestFuzzer::Fuzz();
+  return v8_num(239);
+}
+
+
 THREADED_TEST(FunctionTemplate) {
   v8::HandleScope scope;
   LocalContext env;
@@ -792,6 +798,7 @@
     Local<v8::FunctionTemplate> fun_templ =
         v8::FunctionTemplate::New(construct_call);
     fun_templ->SetClassName(v8_str("funky"));
+    fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), Return239);
     Local<Function> fun = fun_templ->GetFunction();
     env->Global()->Set(v8_str("obj"), fun);
     Local<Script> script = v8_compile("var s = new obj(); s.x");
@@ -799,6 +806,9 @@
 
     Local<Value> result = v8_compile("(new obj()).toString()")->Run();
     CHECK_EQ(v8_str("[object funky]"), result);
+
+    result = v8_compile("(new obj()).m")->Run();
+    CHECK_EQ(239, result->Int32Value());
   }
 }
 
@@ -1485,9 +1495,9 @@
   char* data = new char[100];
 
   void* aligned = data;
-  CHECK_EQ(0, reinterpret_cast<uintptr_t>(aligned) & 0x1);
+  CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1));
   void* unaligned = data + 1;
-  CHECK_EQ(1, reinterpret_cast<uintptr_t>(unaligned) & 0x1);
+  CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1));
 
   // Check reading and writing aligned pointers.
   obj->SetPointerInInternalField(0, aligned);
@@ -1517,9 +1527,9 @@
   char* data = new char[100];
 
   void* aligned = data;
-  CHECK_EQ(0, reinterpret_cast<uintptr_t>(aligned) & 0x1);
+  CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1));
   void* unaligned = data + 1;
-  CHECK_EQ(1, reinterpret_cast<uintptr_t>(unaligned) & 0x1);
+  CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1));
 
   obj->SetPointerInInternalField(0, aligned);
   i::Heap::CollectAllGarbage(false);
@@ -3061,7 +3071,7 @@
 static v8::Handle<Value> IdentityIndexedPropertyGetter(
     uint32_t index,
     const AccessorInfo& info) {
-  return v8::Integer::New(index);
+  return v8::Integer::NewFromUnsigned(index);
 }
 
 
@@ -3186,6 +3196,45 @@
 }
 
 
+THREADED_TEST(IndexedInterceptorWithNegativeIndices) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+
+  LocalContext context;
+  Local<v8::Object> obj = templ->NewInstance();
+  context->Global()->Set(v8_str("obj"), obj);
+
+  const char* code =
+      "try {"
+      "  for (var i = 0; i < 100; i++) {"
+      "    var expected = i;"
+      "    var key = i;"
+      "    if (i == 25) {"
+      "       key = -1;"
+      "       expected = undefined;"
+      "    }"
+      "    if (i == 50) {"
+      "       /* probe minimal Smi number on 32-bit platforms */"
+      "       key = -(1 << 30);"
+      "       expected = undefined;"
+      "    }"
+      "    if (i == 75) {"
+      "       /* probe minimal Smi number on 64-bit platforms */"
+      "       key = 1 << 31;"
+      "       expected = undefined;"
+      "    }"
+      "    var v = obj[key];"
+      "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
+      "  }"
+      "  'PASSED'"
+      "} catch(e) {"
+      "  e"
+      "}";
+  ExpectString(code, "PASSED");
+}
+
+
 THREADED_TEST(IndexedInterceptorWithNotSmiLookup) {
   v8::HandleScope scope;
   Local<ObjectTemplate> templ = ObjectTemplate::New();
@@ -3199,11 +3248,12 @@
       "try {"
       "  for (var i = 0; i < 100; i++) {"
       "    var expected = i;"
+      "    var key = i;"
       "    if (i == 50) {"
-      "       i = 'foobar';"
+      "       key = 'foobar';"
       "       expected = undefined;"
       "    }"
-      "    var v = obj[i];"
+      "    var v = obj[key];"
       "    if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;"
       "  }"
       "  'PASSED'"
@@ -6469,12 +6519,6 @@
 }
 
 
-static v8::Handle<Value> Return239(Local<String> name, const AccessorInfo&) {
-  ApiTestFuzzer::Fuzz();
-  return v8_num(239);
-}
-
-
 static void SetOnThis(Local<String> name,
                       Local<Value> value,
                       const AccessorInfo& info) {
@@ -8059,7 +8103,7 @@
 }
 
 
-static int GetSurvivingGlobalObjectsCount() {
+static void CheckSurvivingGlobalObjectsCount(int expected) {
   // We need to collect all garbage twice to be sure that everything
   // has been collected.  This is because inline caches are cleared in
   // the first garbage collection but some of the maps have already
@@ -8069,9 +8113,9 @@
   i::Heap::CollectAllGarbage(false);
   int count = GetGlobalObjectsCount();
 #ifdef DEBUG
-  if (count > 0) i::Heap::TracePathToGlobal();
+  if (count != expected) i::Heap::TracePathToGlobal();
 #endif
-  return count;
+  CHECK_EQ(expected, count);
 }
 
 
@@ -8080,25 +8124,23 @@
 
   v8::V8::Initialize();
 
-  int count = GetSurvivingGlobalObjectsCount();
-
   for (int i = 0; i < 5; i++) {
     { v8::HandleScope scope;
       LocalContext context;
     }
-    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
+    CheckSurvivingGlobalObjectsCount(0);
 
     { v8::HandleScope scope;
       LocalContext context;
       v8_compile("Date")->Run();
     }
-    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
+    CheckSurvivingGlobalObjectsCount(0);
 
     { v8::HandleScope scope;
       LocalContext context;
       v8_compile("/aaa/")->Run();
     }
-    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
+    CheckSurvivingGlobalObjectsCount(0);
 
     { v8::HandleScope scope;
       const char* extension_list[] = { "v8/gc" };
@@ -8106,7 +8148,7 @@
       LocalContext context(&extensions);
       v8_compile("gc();")->Run();
     }
-    CHECK_EQ(count, GetSurvivingGlobalObjectsCount());
+    CheckSurvivingGlobalObjectsCount(0);
   }
 }
 
@@ -10517,6 +10559,45 @@
 }
 
 
+v8::Handle<Value> AnalyzeStackOfEvalWithSourceURL(const v8::Arguments& args) {
+  v8::HandleScope scope;
+  v8::Handle<v8::StackTrace> stackTrace =
+      v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+  CHECK_EQ(5, stackTrace->GetFrameCount());
+  v8::Handle<v8::String> url = v8_str("eval_url");
+  for (int i = 0; i < 3; i++) {
+    v8::Handle<v8::String> name =
+        stackTrace->GetFrame(i)->GetScriptNameOrSourceURL();
+    CHECK(!name.IsEmpty());
+    CHECK_EQ(url, name);
+  }
+  return v8::Undefined();
+}
+
+
+TEST(SourceURLInStackTrace) {
+  v8::HandleScope scope;
+  Local<ObjectTemplate> templ = ObjectTemplate::New();
+  templ->Set(v8_str("AnalyzeStackOfEvalWithSourceURL"),
+             v8::FunctionTemplate::New(AnalyzeStackOfEvalWithSourceURL));
+  LocalContext context(0, templ);
+
+  const char *source =
+    "function outer() {\n"
+    "function bar() {\n"
+    "  AnalyzeStackOfEvalWithSourceURL();\n"
+    "}\n"
+    "function foo() {\n"
+    "\n"
+    "  bar();\n"
+    "}\n"
+    "foo();\n"
+    "}\n"
+    "eval('(' + outer +')()//@ sourceURL=eval_url');";
+  CHECK(CompileRun(source)->IsUndefined());
+}
+
+
 // Test that idle notification can be handled and eventually returns true.
 THREADED_TEST(IdleNotification) {
   bool rv = false;
@@ -11443,3 +11524,234 @@
     ExpectString(code, "");
   }
 }
+
+
+TEST(DontDeleteCellLoadIC) {
+  const char* function_code =
+      "function readCell() { while (true) { return cell; } }";
+
+  {
+    // Run the code twice in the first context to initialize the load
+    // IC for a don't delete cell.
+    v8::HandleScope scope;
+    LocalContext context1;
+    CompileRun("var cell = \"first\";");
+    ExpectBoolean("delete cell", false);
+    CompileRun(function_code);
+    ExpectString("readCell()", "first");
+    ExpectString("readCell()", "first");
+  }
+
+  {
+    // Use a deletable cell in the second context.
+    v8::HandleScope scope;
+    LocalContext context2;
+    CompileRun("cell = \"second\";");
+    CompileRun(function_code);
+    ExpectString("readCell()", "second");
+    ExpectBoolean("delete cell", true);
+    ExpectString("(function() {"
+                 "  try {"
+                 "    return readCell();"
+                 "  } catch(e) {"
+                 "    return e.toString();"
+                 "  }"
+                 "})()",
+                 "ReferenceError: cell is not defined");
+    CompileRun("cell = \"new_second\";");
+    i::Heap::CollectAllGarbage(true);
+    ExpectString("readCell()", "new_second");
+    ExpectString("readCell()", "new_second");
+  }
+}
+
+
+TEST(DontDeleteCellLoadICForceDelete) {
+  const char* function_code =
+      "function readCell() { while (true) { return cell; } }";
+
+  // Run the code twice to initialize the load IC for a don't delete
+  // cell.
+  v8::HandleScope scope;
+  LocalContext context;
+  CompileRun("var cell = \"value\";");
+  ExpectBoolean("delete cell", false);
+  CompileRun(function_code);
+  ExpectString("readCell()", "value");
+  ExpectString("readCell()", "value");
+
+  // Delete the cell using the API and check the inlined code works
+  // correctly.
+  CHECK(context->Global()->ForceDelete(v8_str("cell")));
+  ExpectString("(function() {"
+               "  try {"
+               "    return readCell();"
+               "  } catch(e) {"
+               "    return e.toString();"
+               "  }"
+               "})()",
+               "ReferenceError: cell is not defined");
+}
+
+
+TEST(DontDeleteCellLoadICAPI) {
+  const char* function_code =
+      "function readCell() { while (true) { return cell; } }";
+
+  // Run the code twice to initialize the load IC for a don't delete
+  // cell created using the API.
+  v8::HandleScope scope;
+  LocalContext context;
+  context->Global()->Set(v8_str("cell"), v8_str("value"), v8::DontDelete);
+  ExpectBoolean("delete cell", false);
+  CompileRun(function_code);
+  ExpectString("readCell()", "value");
+  ExpectString("readCell()", "value");
+
+  // Delete the cell using the API and check the inlined code works
+  // correctly.
+  CHECK(context->Global()->ForceDelete(v8_str("cell")));
+  ExpectString("(function() {"
+               "  try {"
+               "    return readCell();"
+               "  } catch(e) {"
+               "    return e.toString();"
+               "  }"
+               "})()",
+               "ReferenceError: cell is not defined");
+}
+
+
+TEST(GlobalLoadICGC) {
+  const char* function_code =
+      "function readCell() { while (true) { return cell; } }";
+
+  // Check inline load code for a don't delete cell is cleared during
+  // GC.
+  {
+    v8::HandleScope scope;
+    LocalContext context;
+    CompileRun("var cell = \"value\";");
+    ExpectBoolean("delete cell", false);
+    CompileRun(function_code);
+    ExpectString("readCell()", "value");
+    ExpectString("readCell()", "value");
+  }
+  {
+    v8::HandleScope scope;
+    LocalContext context2;
+    // Hold the code object in the second context.
+    CompileRun(function_code);
+    CheckSurvivingGlobalObjectsCount(1);
+  }
+
+  // Check inline load code for a deletable cell is cleared during GC.
+  {
+    v8::HandleScope scope;
+    LocalContext context;
+    CompileRun("cell = \"value\";");
+    CompileRun(function_code);
+    ExpectString("readCell()", "value");
+    ExpectString("readCell()", "value");
+  }
+  {
+    v8::HandleScope scope;
+    LocalContext context2;
+    // Hold the code object in the second context.
+    CompileRun(function_code);
+    CheckSurvivingGlobalObjectsCount(1);
+  }
+}
+
+
+TEST(RegExp) {
+  v8::HandleScope scope;
+  LocalContext context;
+
+  v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone);
+  CHECK(re->IsRegExp());
+  CHECK(re->GetSource()->Equals(v8_str("foo")));
+  CHECK_EQ(re->GetFlags(), v8::RegExp::kNone);
+
+  re = v8::RegExp::New(v8_str("bar"),
+                       static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase |
+                                                      v8::RegExp::kGlobal));
+  CHECK(re->IsRegExp());
+  CHECK(re->GetSource()->Equals(v8_str("bar")));
+  CHECK_EQ(static_cast<int>(re->GetFlags()),
+           v8::RegExp::kIgnoreCase | v8::RegExp::kGlobal);
+
+  re = v8::RegExp::New(v8_str("baz"),
+                       static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase |
+                                                      v8::RegExp::kMultiline));
+  CHECK(re->IsRegExp());
+  CHECK(re->GetSource()->Equals(v8_str("baz")));
+  CHECK_EQ(static_cast<int>(re->GetFlags()),
+           v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline);
+
+  re = CompileRun("/quux/").As<v8::RegExp>();
+  CHECK(re->IsRegExp());
+  CHECK(re->GetSource()->Equals(v8_str("quux")));
+  CHECK_EQ(re->GetFlags(), v8::RegExp::kNone);
+
+  re = CompileRun("/quux/gm").As<v8::RegExp>();
+  CHECK(re->IsRegExp());
+  CHECK(re->GetSource()->Equals(v8_str("quux")));
+  CHECK_EQ(static_cast<int>(re->GetFlags()),
+           v8::RegExp::kGlobal | v8::RegExp::kMultiline);
+
+  // Override the RegExp constructor and check the API constructor
+  // still works.
+  CompileRun("RegExp = function() {}");
+
+  re = v8::RegExp::New(v8_str("foobar"), v8::RegExp::kNone);
+  CHECK(re->IsRegExp());
+  CHECK(re->GetSource()->Equals(v8_str("foobar")));
+  CHECK_EQ(re->GetFlags(), v8::RegExp::kNone);
+
+  re = v8::RegExp::New(v8_str("foobarbaz"),
+                       static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase |
+                                                      v8::RegExp::kMultiline));
+  CHECK(re->IsRegExp());
+  CHECK(re->GetSource()->Equals(v8_str("foobarbaz")));
+  CHECK_EQ(static_cast<int>(re->GetFlags()),
+           v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline);
+
+  context->Global()->Set(v8_str("re"), re);
+  ExpectTrue("re.test('FoobarbaZ')");
+
+  v8::TryCatch try_catch;
+  re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone);
+  CHECK(re.IsEmpty());
+  CHECK(try_catch.HasCaught());
+  context->Global()->Set(v8_str("ex"), try_catch.Exception());
+  ExpectTrue("ex instanceof SyntaxError");
+}
+
+
+static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
+                                    const v8::AccessorInfo& info ) {
+  return v8_str("42!");
+}
+
+
+static v8::Handle<v8::Array> Enumerator(const v8::AccessorInfo& info) {
+  v8::Handle<v8::Array> result = v8::Array::New();
+  result->Set(0, v8_str("universalAnswer"));
+  return result;
+}
+
+
+TEST(NamedEnumeratorAndForIn) {
+  v8::HandleScope handle_scope;
+  LocalContext context;
+  v8::Context::Scope context_scope(context.local());
+
+  v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New();
+  tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator);
+  context->Global()->Set(v8_str("o"), tmpl->NewInstance());
+  v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun(
+        "var result = []; for (var k in o) result.push(k); result"));
+  CHECK_EQ(1, result->Length());
+  CHECK_EQ(v8_str("universalAnswer"), result->Get(0));
+}
diff --git a/test/cctest/test-conversions.cc b/test/cctest/test-conversions.cc
index abcd426..c62bbaa 100644
--- a/test/cctest/test-conversions.cc
+++ b/test/cctest/test-conversions.cc
@@ -168,6 +168,38 @@
   CHECK_EQ(gay_strtod(num, NULL), StringToDouble(num, NO_FLAGS));
 }
 
+TEST(MinimumExponent) {
+  // Same test but with different point-position.
+  char num[] =
+  "445014771701440202508199667279499186358524265859260511351695091"
+  "228726223124931264069530541271189424317838013700808305231545782"
+  "515453032382772695923684574304409936197089118747150815050941806"
+  "048037511737832041185193533879641611520514874130831632725201246"
+  "060231058690536206311752656217652146466431814205051640436322226"
+  "680064743260560117135282915796422274554896821334728738317548403"
+  "413978098469341510556195293821919814730032341053661708792231510"
+  "873354131880491105553390278848567812190177545006298062245710295"
+  "816371174594568773301103242116891776567137054973871082078224775"
+  "842509670618916870627821633352993761380751142008862499795052791"
+  "018709663463944015644907297315659352441231715398102212132212018"
+  "470035807616260163568645811358486831521563686919762403704226016"
+  "998291015625000000000000000000000000000000000e-1108";
+
+  CHECK_EQ(gay_strtod(num, NULL), StringToDouble(num, NO_FLAGS));
+
+  // Changes the result of strtod (at least in glibc implementation).
+  num[sizeof(num) - 8] = '1';
+
+  CHECK_EQ(gay_strtod(num, NULL), StringToDouble(num, NO_FLAGS));
+}
+
+
+TEST(MaximumExponent) {
+  char num[] = "0.16e309";
+
+  CHECK_EQ(gay_strtod(num, NULL), StringToDouble(num, NO_FLAGS));
+}
+
 
 TEST(ExponentNumberStr) {
   CHECK_EQ(1e1, StringToDouble("1e1", NO_FLAGS));
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index f5526ce..d59e2f5 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -867,7 +867,7 @@
     break_point_hit_count++;
     if (break_point_hit_count % 2 == 0) {
       // Scavenge.
-      Heap::CollectGarbage(0, v8::internal::NEW_SPACE);
+      Heap::CollectGarbage(v8::internal::NEW_SPACE);
     } else {
       // Mark sweep compact.
       Heap::CollectAllGarbage(true);
@@ -891,7 +891,7 @@
 
     // Run the garbage collector to enforce heap verification if option
     // --verify-heap is set.
-    Heap::CollectGarbage(0, v8::internal::NEW_SPACE);
+    Heap::CollectGarbage(v8::internal::NEW_SPACE);
 
     // Set the break flag again to come back here as soon as possible.
     v8::Debug::DebugBreak();
@@ -1322,7 +1322,7 @@
     CHECK_EQ(1 + i * 3, break_point_hit_count);
 
     // Scavenge and call function.
-    Heap::CollectGarbage(0, v8::internal::NEW_SPACE);
+    Heap::CollectGarbage(v8::internal::NEW_SPACE);
     f->Call(recv, 0, NULL);
     CHECK_EQ(2 + i * 3, break_point_hit_count);
 
diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc
index 7587da8..88fa79b 100644
--- a/test/cctest/test-decls.cc
+++ b/test/cctest/test-decls.cc
@@ -130,7 +130,7 @@
   InitializeIfNeeded();
   // A retry after a GC may pollute the counts, so perform gc now
   // to avoid that.
-  v8::internal::Heap::CollectGarbage(0, v8::internal::NEW_SPACE);
+  v8::internal::Heap::CollectGarbage(v8::internal::NEW_SPACE);
   HandleScope scope;
   TryCatch catcher;
   catcher.SetVerbose(true);
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index 5e570f3..b86a336 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -20,11 +20,6 @@
 using i::RetainerHeapProfile;
 
 
-static void CompileAndRunScript(const char *src) {
-  v8::Script::Compile(v8::String::New(src))->Run();
-}
-
-
 namespace {
 
 class ConstructorHeapProfileTestHelper : public i::ConstructorHeapProfile {
@@ -58,7 +53,7 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  CompileAndRunScript(
+  CompileRun(
       "function F() {}  // A constructor\n"
       "var f1 = new F();\n"
       "var f2 = new F();\n");
@@ -359,7 +354,7 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  CompileAndRunScript(
+  CompileRun(
       "function A() {}\n"
       "function B(x) { this.x = x; }\n"
       "function C(x) { this.x1 = x; this.x2 = x; }\n"
@@ -473,7 +468,7 @@
   LocalContext env1;
   env1->SetSecurityToken(token1);
 
-  CompileAndRunScript(
+  CompileRun(
       "function A1() {}\n"
       "function B1(x) { this.x = x; }\n"
       "function C1(x) { this.x1 = x; this.x2 = x; }\n"
@@ -485,7 +480,7 @@
   LocalContext env2;
   env2->SetSecurityToken(token2);
 
-  CompileAndRunScript(
+  CompileRun(
       "function A2() {}\n"
       "function B2(x) { return function() { return typeof x; }; }\n"
       "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n"
@@ -583,7 +578,7 @@
 
   //   -a-> X1 --a
   // x -b-> X2 <-|
-  CompileAndRunScript(
+  CompileRun(
       "function X(a, b) { this.a = a; this.b = b; }\n"
       "x = new X(new X(), new X());\n"
       "x.a.a = x.b;");
@@ -594,7 +589,7 @@
       GetProperty(global, v8::HeapGraphEdge::kProperty, "x");
   CHECK_NE(NULL, x);
   const v8::HeapGraphNode* x_prototype =
-      GetProperty(x, v8::HeapGraphEdge::kProperty, "prototype");
+      GetProperty(x, v8::HeapGraphEdge::kProperty, "__proto__");
   CHECK_NE(NULL, x_prototype);
   const v8::HeapGraphNode* x1 =
       GetProperty(x, v8::HeapGraphEdge::kProperty, "a");
@@ -606,7 +601,7 @@
       x->GetSelfSize() * 3,
       x->GetReachableSize() - x_prototype->GetReachableSize());
   CHECK_EQ(
-      x->GetSelfSize() * 3 + x_prototype->GetSelfSize(), x->GetRetainedSize());
+      x->GetSelfSize() * 3, x->GetRetainedSize());
   CHECK_EQ(
       x1->GetSelfSize() * 2,
       x1->GetReachableSize() - x_prototype->GetReachableSize());
@@ -624,7 +619,7 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  CompileAndRunScript(
+  CompileRun(
       "function A() { }\n"
       "a = new A;");
   const v8::HeapSnapshot* snapshot =
@@ -648,10 +643,9 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  CompileAndRunScript(
+  CompileRun(
       "function lazy(x) { return x - 1; }\n"
       "function compiled(x) { return x + 1; }\n"
-      "var inferred = function(x) { return x; }\n"
       "var anonymous = (function() { return function() { return 0; } })();\n"
       "compiled(1)");
   const v8::HeapSnapshot* snapshot =
@@ -666,18 +660,12 @@
       GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
   CHECK_NE(NULL, lazy);
   CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
-  const v8::HeapGraphNode* inferred =
-      GetProperty(global, v8::HeapGraphEdge::kProperty, "inferred");
-  CHECK_NE(NULL, inferred);
-  CHECK_EQ(v8::HeapGraphNode::kClosure, inferred->GetType());
-  v8::String::AsciiValue inferred_name(inferred->GetName());
-  CHECK_EQ("inferred", *inferred_name);
   const v8::HeapGraphNode* anonymous =
       GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous");
   CHECK_NE(NULL, anonymous);
   CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType());
   v8::String::AsciiValue anonymous_name(anonymous->GetName());
-  CHECK_EQ("(anonymous function)", *anonymous_name);
+  CHECK_EQ("", *anonymous_name);
 
   // Find references to code.
   const v8::HeapGraphNode* compiled_code =
@@ -716,6 +704,44 @@
 }
 
 
+TEST(HeapSnapshotHeapNumbers) {
+  v8::HandleScope scope;
+  LocalContext env;
+  CompileRun(
+      "a = 1;    // a is Smi\n"
+      "b = 2.5;  // b is HeapNumber");
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("numbers"));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a"));
+  const v8::HeapGraphNode* b =
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "b");
+  CHECK_NE(NULL, b);
+  CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType());
+}
+
+
+TEST(HeapSnapshotInternalReferences) {
+  v8::HandleScope scope;
+  v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+  global_template->SetInternalFieldCount(2);
+  LocalContext env(NULL, global_template);
+  v8::Handle<v8::Object> global_proxy = env->Global();
+  v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>();
+  CHECK_EQ(2, global->InternalFieldCount());
+  v8::Local<v8::Object> obj = v8::Object::New();
+  global->SetInternalField(0, v8_num(17));
+  global->SetInternalField(1, obj);
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("internals"));
+  const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot);
+  // The first reference will not present, because it's a Smi.
+  CHECK_EQ(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0"));
+  // The second reference is to an object.
+  CHECK_NE(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "1"));
+}
+
+
 // Trying to introduce a check helper for uint64_t causes many
 // overloading ambiguities, so it seems easier just to cast
 // them to a signed type.
@@ -728,7 +754,7 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  CompileAndRunScript(
+  CompileRun(
       "function A() {}\n"
       "function B(x) { this.x = x; }\n"
       "var a = new A();\n"
@@ -784,18 +810,19 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  CompileAndRunScript(
+  CompileRun(
       "function A() {}\n"
       "function B(x) { this.x = x; }\n"
+      "function A2(a) { for (var i = 0; i < a; ++i) this[i] = i; }\n"
       "var a = new A();\n"
       "var b = new B(a);");
   const v8::HeapSnapshot* snapshot1 =
       v8::HeapProfiler::TakeSnapshot(v8::String::New("s1"));
 
-  CompileAndRunScript(
+  CompileRun(
       "delete a;\n"
       "b.x = null;\n"
-      "var a = new A();\n"
+      "var a = new A2(20);\n"
       "var b2 = new B(a);");
   const v8::HeapSnapshot* snapshot2 =
       v8::HeapProfiler::TakeSnapshot(v8::String::New("s2"));
@@ -811,7 +838,7 @@
     const v8::HeapGraphNode* node = prop->GetToNode();
     if (node->GetType() == v8::HeapGraphNode::kObject) {
       v8::String::AsciiValue node_name(node->GetName());
-      if (strcmp(*node_name, "A") == 0) {
+      if (strcmp(*node_name, "A2") == 0) {
         CHECK(IsNodeRetainedAs(node, v8::HeapGraphEdge::kProperty, "a"));
         CHECK(!found_A);
         found_A = true;
@@ -849,6 +876,19 @@
 }
 
 
+TEST(HeapSnapshotRootPreservedAfterSorting) {
+  v8::HandleScope scope;
+  LocalContext env;
+  const v8::HeapSnapshot* snapshot =
+      v8::HeapProfiler::TakeSnapshot(v8::String::New("s"));
+  const v8::HeapGraphNode* root1 = snapshot->GetRoot();
+  const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>(
+      snapshot))->GetSortedEntriesList();
+  const v8::HeapGraphNode* root2 = snapshot->GetRoot();
+  CHECK_EQ(root1, root2);
+}
+
+
 namespace v8 {
 namespace internal {
 
@@ -914,7 +954,7 @@
   v8::HandleScope scope;
   LocalContext env;
 
-  CompileAndRunScript(
+  CompileRun(
       "function A() {}\n"
       "function B(x) { this.x = x; }\n"
       "var a = new A();\n"
@@ -1035,7 +1075,7 @@
 
 #define STRING_LITERAL_FOR_TEST \
   "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\""
-  CompileAndRunScript(
+  CompileRun(
       "function A(s) { this.s = s; }\n"
       "function B(x) { this.x = x; }\n"
       "var a = new A(" STRING_LITERAL_FOR_TEST ");\n"
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index eec024f..126ac21 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -177,13 +177,11 @@
   int request = 24;
   CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request)));
   CHECK(Smi::FromInt(42)->IsSmi());
-  CHECK(Failure::RetryAfterGC(request, NEW_SPACE)->IsFailure());
-  CHECK_EQ(request, Failure::RetryAfterGC(request, NEW_SPACE)->requested());
+  CHECK(Failure::RetryAfterGC(NEW_SPACE)->IsFailure());
   CHECK_EQ(NEW_SPACE,
-           Failure::RetryAfterGC(request, NEW_SPACE)->allocation_space());
+           Failure::RetryAfterGC(NEW_SPACE)->allocation_space());
   CHECK_EQ(OLD_POINTER_SPACE,
-           Failure::RetryAfterGC(request,
-                                 OLD_POINTER_SPACE)->allocation_space());
+           Failure::RetryAfterGC(OLD_POINTER_SPACE)->allocation_space());
   CHECK(Failure::Exception()->IsFailure());
   CHECK(Smi::FromInt(Smi::kMinValue)->IsSmi());
   CHECK(Smi::FromInt(Smi::kMaxValue)->IsSmi());
@@ -195,8 +193,7 @@
 
   v8::HandleScope sc;
   // Check GC.
-  int free_bytes = Heap::MaxObjectSizeInPagedSpace();
-  CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+  Heap::CollectGarbage(NEW_SPACE);
 
   Handle<String> name = Factory::LookupAsciiSymbol("theFunction");
   Handle<String> prop_name = Factory::LookupAsciiSymbol("theSlot");
@@ -221,7 +218,7 @@
     CHECK_EQ(Smi::FromInt(24), obj->GetProperty(*prop_namex));
   }
 
-  CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+  Heap::CollectGarbage(NEW_SPACE);
 
   // Function should be alive.
   CHECK(Top::context()->global()->HasLocalProperty(*name));
@@ -239,7 +236,7 @@
   }
 
   // After gc, it should survive.
-  CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+  Heap::CollectGarbage(NEW_SPACE);
 
   CHECK(Top::context()->global()->HasLocalProperty(*obj_name));
   CHECK(Top::context()->global()->GetProperty(*obj_name)->IsJSObject());
@@ -301,7 +298,7 @@
   }
 
   // after gc, it should survive
-  CHECK(Heap::CollectGarbage(0, NEW_SPACE));
+  Heap::CollectGarbage(NEW_SPACE);
 
   CHECK((*h1)->IsString());
   CHECK((*h2)->IsHeapNumber());
@@ -382,8 +379,8 @@
     h2 = GlobalHandles::Create(*u);
   }
 
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
-  CHECK(Heap::CollectGarbage(0, NEW_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
+  Heap::CollectGarbage(NEW_SPACE);
   // Make sure the object is promoted.
 
   GlobalHandles::MakeWeak(h2.location(),
@@ -392,7 +389,7 @@
   CHECK(!GlobalHandles::IsNearDeath(h1.location()));
   CHECK(!GlobalHandles::IsNearDeath(h2.location()));
 
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   CHECK((*h1)->IsString());
 
@@ -426,7 +423,7 @@
   CHECK(!WeakPointerCleared);
 
   // Mark-compact treats weak reference properly.
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   CHECK(WeakPointerCleared);
 }
@@ -814,8 +811,7 @@
 TEST(LargeObjectSpaceContains) {
   InitializeVM();
 
-  int free_bytes = Heap::MaxObjectSizeInPagedSpace();
-  CHECK(Heap::CollectGarbage(free_bytes, NEW_SPACE));
+  Heap::CollectGarbage(NEW_SPACE);
 
   Address current_top = Heap::new_space()->top();
   Page* page = Page::FromAddress(current_top);
@@ -958,6 +954,7 @@
   CHECK(page->IsRegionDirty(clone_addr + (object_size - kPointerSize)));
 }
 
+
 TEST(TestCodeFlushing) {
   i::FLAG_allow_natives_syntax = true;
   // If we do not flush code this test is invalid.
@@ -1001,3 +998,91 @@
   CHECK(function->shared()->is_compiled());
   CHECK(function->is_compiled());
 }
+
+
+// Count the number of global contexts in the weak list of global contexts.
+static int CountGlobalContexts() {
+  int count = 0;
+  Object* object = Heap::global_contexts_list();
+  while (!object->IsUndefined()) {
+    count++;
+    object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK);
+  }
+  return count;
+}
+
+
+TEST(TestInternalWeakLists) {
+  static const int kNumTestContexts = 10;
+
+  v8::HandleScope scope;
+  v8::Persistent<v8::Context> ctx[kNumTestContexts];
+
+  CHECK_EQ(0, CountGlobalContexts());
+
+  // Create a number of global contests which gets linked together.
+  for (int i = 0; i < kNumTestContexts; i++) {
+    ctx[i] = v8::Context::New();
+    CHECK_EQ(i + 1, CountGlobalContexts());
+
+    ctx[i]->Enter();
+    ctx[i]->Exit();
+  }
+
+  // Force compilation cache cleanup.
+  Heap::CollectAllGarbage(true);
+
+  // Dispose the global contexts one by one.
+  for (int i = 0; i < kNumTestContexts; i++) {
+    ctx[i].Dispose();
+    ctx[i].Clear();
+
+    // Scavenge treats these references as strong.
+    for (int j = 0; j < 10; j++) {
+      Heap::PerformScavenge();
+      CHECK_EQ(kNumTestContexts - i, CountGlobalContexts());
+    }
+
+    // Mark compact handles the weak references.
+    Heap::CollectAllGarbage(true);
+    CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
+  }
+
+  CHECK_EQ(0, CountGlobalContexts());
+}
+
+
+// Count the number of global contexts in the weak list of global contexts
+// causing a GC after the specified number of elements.
+static int CountGlobalContextsWithGC(int n) {
+  int count = 0;
+  Handle<Object> object(Heap::global_contexts_list());
+  while (!object->IsUndefined()) {
+    count++;
+    if (count == n) Heap::CollectAllGarbage(true);
+    object =
+        Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK));
+  }
+  return count;
+}
+
+
+TEST(TestInternalWeakListsTraverseWithGC) {
+  static const int kNumTestContexts = 10;
+
+  v8::HandleScope scope;
+  v8::Persistent<v8::Context> ctx[kNumTestContexts];
+
+  CHECK_EQ(0, CountGlobalContexts());
+
+  // Create an number of contexts and check the length of the weak list both
+  // with and without GCs while iterating the list.
+  for (int i = 0; i < kNumTestContexts; i++) {
+    ctx[i] = v8::Context::New();
+    CHECK_EQ(i + 1, CountGlobalContexts());
+    CHECK_EQ(i + 1, CountGlobalContextsWithGC(i / 2 + 1));
+
+    ctx[i]->Enter();
+    ctx[i]->Exit();
+  }
+}
diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc
index 9162ffd..7d7bd40 100644
--- a/test/cctest/test-log-stack-tracer.cc
+++ b/test/cctest/test-log-stack-tracer.cc
@@ -245,8 +245,8 @@
   args.This()->Set(v8_str("low_bits"), v8_num(low_bits >> 1));
 #elif defined(V8_HOST_ARCH_64_BIT)
   uint64_t fp = reinterpret_cast<uint64_t>(calling_frame->fp());
-  int32_t low_bits = fp & 0xffffffff;
-  int32_t high_bits = fp >> 32;
+  int32_t low_bits = static_cast<int32_t>(fp & 0xffffffff);
+  int32_t high_bits = static_cast<int32_t>(fp >> 32);
   args.This()->Set(v8_str("low_bits"), v8_num(low_bits));
   args.This()->Set(v8_str("high_bits"), v8_num(high_bits));
 #else
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index b364ae3..16d0f00 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -469,7 +469,7 @@
   CHECK(!sampler.WasSampleStackCalled());
   nonJsThread.WaitForRunning();
   nonJsThread.SendSigProf();
-  CHECK(sampler.WaitForTick());
+  CHECK(!sampler.WaitForTick());
   CHECK(!sampler.WasSampleStackCalled());
   sampler.Stop();
 
diff --git a/test/cctest/test-macro-assembler-x64.cc b/test/cctest/test-macro-assembler-x64.cc
index 3d2b91b..9b1fc46 100755
--- a/test/cctest/test-macro-assembler-x64.cc
+++ b/test/cctest/test-macro-assembler-x64.cc
@@ -519,40 +519,40 @@
   __ incq(rax);
   __ movl(rcx, Immediate(0));
   __ Integer32ToSmi(rcx, rcx);
-  cond = masm->CheckPositiveSmi(rcx);  // Zero counts as positive.
+  cond = masm->CheckNonNegativeSmi(rcx);
   __ j(NegateCondition(cond), &exit);
 
   __ incq(rax);
   __ xor_(rcx, Immediate(kSmiTagMask));
-  cond = masm->CheckPositiveSmi(rcx);  // "zero" non-smi.
+  cond = masm->CheckNonNegativeSmi(rcx);  // "zero" non-smi.
   __ j(cond, &exit);
 
   __ incq(rax);
   __ movq(rcx, Immediate(-1));
   __ Integer32ToSmi(rcx, rcx);
-  cond = masm->CheckPositiveSmi(rcx);  // Negative smis are not positive.
+  cond = masm->CheckNonNegativeSmi(rcx);  // Negative smis are not positive.
   __ j(cond, &exit);
 
   __ incq(rax);
   __ movq(rcx, Immediate(Smi::kMinValue));
   __ Integer32ToSmi(rcx, rcx);
-  cond = masm->CheckPositiveSmi(rcx);  // Most negative smi is not positive.
+  cond = masm->CheckNonNegativeSmi(rcx);  // Most negative smi is not positive.
   __ j(cond, &exit);
 
   __ incq(rax);
   __ xor_(rcx, Immediate(kSmiTagMask));
-  cond = masm->CheckPositiveSmi(rcx);  // "Negative" non-smi.
+  cond = masm->CheckNonNegativeSmi(rcx);  // "Negative" non-smi.
   __ j(cond, &exit);
 
   __ incq(rax);
   __ movq(rcx, Immediate(Smi::kMaxValue));
   __ Integer32ToSmi(rcx, rcx);
-  cond = masm->CheckPositiveSmi(rcx);  // Most positive smi is positive.
+  cond = masm->CheckNonNegativeSmi(rcx);  // Most positive smi is positive.
   __ j(NegateCondition(cond), &exit);
 
   __ incq(rax);
   __ xor_(rcx, Immediate(kSmiTagMask));
-  cond = masm->CheckPositiveSmi(rcx);  // "Positive" non-smi.
+  cond = masm->CheckNonNegativeSmi(rcx);  // "Positive" non-smi.
   __ j(cond, &exit);
 
   // CheckIsMinSmi
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index e4ac1b7..531b1f7 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -94,7 +94,7 @@
   CHECK(Heap::InSpace(*array, NEW_SPACE));
 
   // Call the m-c collector, so array becomes an old object.
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   // Array now sits in the old space
   CHECK(Heap::InSpace(*array, OLD_POINTER_SPACE));
@@ -111,7 +111,7 @@
   v8::HandleScope sc;
 
   // Do a mark compact GC to shrink the heap.
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   // Allocate a big Fixed array in the new space.
   int size = (Heap::MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) /
@@ -134,7 +134,7 @@
   }
 
   // Call mark compact GC, and it should pass.
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   // array should not be promoted because the old space is full.
   CHECK(Heap::InSpace(*array, NEW_SPACE));
@@ -146,7 +146,7 @@
 
   v8::HandleScope sc;
   // call mark-compact when heap is empty
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   // keep allocating garbage in new space until it fails
   const int ARRAY_SIZE = 100;
@@ -154,7 +154,7 @@
   do {
     array = Heap::AllocateFixedArray(ARRAY_SIZE);
   } while (!array->IsFailure());
-  CHECK(Heap::CollectGarbage(0, NEW_SPACE));
+  Heap::CollectGarbage(NEW_SPACE);
 
   array = Heap::AllocateFixedArray(ARRAY_SIZE);
   CHECK(!array->IsFailure());
@@ -164,7 +164,7 @@
   do {
     mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   } while (!mapp->IsFailure());
-  CHECK(Heap::CollectGarbage(0, MAP_SPACE));
+  Heap::CollectGarbage(MAP_SPACE);
   mapp = Heap::AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   CHECK(!mapp->IsFailure());
 
@@ -182,7 +182,7 @@
   Top::context()->global()->SetProperty(func_name, function, NONE);
 
   JSObject* obj = JSObject::cast(Heap::AllocateJSObject(function));
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   func_name = String::cast(Heap::LookupAsciiSymbol("theFunction"));
   CHECK(Top::context()->global()->HasLocalProperty(func_name));
@@ -196,7 +196,7 @@
   String* prop_name = String::cast(Heap::LookupAsciiSymbol("theSlot"));
   obj->SetProperty(prop_name, Smi::FromInt(23), NONE);
 
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   obj_name = String::cast(Heap::LookupAsciiSymbol("theObject"));
   CHECK(Top::context()->global()->HasLocalProperty(obj_name));
@@ -264,7 +264,7 @@
   CHECK_EQ(0, gc_starts);
   CHECK_EQ(gc_ends, gc_starts);
 
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
   CHECK_EQ(1, gc_starts);
   CHECK_EQ(gc_ends, gc_starts);
 }
@@ -317,7 +317,7 @@
     GlobalHandles::AddGroup(g2_objects, 2);
   }
   // Do a full GC
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   // All object should be alive.
   CHECK_EQ(0, NumberOfWeakCalls);
@@ -335,7 +335,7 @@
     GlobalHandles::AddGroup(g2_objects, 2);
   }
 
-  CHECK(Heap::CollectGarbage(0, OLD_POINTER_SPACE));
+  Heap::CollectGarbage(OLD_POINTER_SPACE);
 
   // All objects should be gone. 5 global handles in total.
   CHECK_EQ(5, NumberOfWeakCalls);
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 186350b..11a808e 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::ParseRegExp(&reader, false, &result);
+  return v8::internal::Parser::ParseRegExp(&reader, false, &result);
 }
 
 
@@ -74,7 +74,7 @@
   ZoneScope zone_scope(DELETE_ON_EXIT);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData result;
-  CHECK(v8::internal::ParseRegExp(&reader, false, &result));
+  CHECK(v8::internal::Parser::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::ParseRegExp(&reader, false, &result));
+  CHECK(v8::internal::Parser::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::ParseRegExp(&reader, false, &result));
+  CHECK(v8::internal::Parser::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::ParseRegExp(&reader, false, &result));
+  CHECK_EQ(false, v8::internal::Parser::ParseRegExp(&reader, false, &result));
   CHECK(result.tree == NULL);
   CHECK(!result.error.is_null());
   SmartPointer<char> str = result.error->ToCString(ALLOW_NULLS);
@@ -473,7 +473,7 @@
   V8::Initialize(NULL);
   FlatStringReader reader(CStrVector(input));
   RegExpCompileData compile_data;
-  if (!v8::internal::ParseRegExp(&reader, multiline, &compile_data))
+  if (!v8::internal::Parser::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-spaces.cc b/test/cctest/test-spaces.cc
index 2811ee6..db8c54f 100644
--- a/test/cctest/test-spaces.cc
+++ b/test/cctest/test-spaces.cc
@@ -221,7 +221,7 @@
   CHECK(lo->Contains(ho));
 
   while (true) {
-    int available = lo->Available();
+    intptr_t available = lo->Available();
     obj = lo->AllocateRaw(lo_size);
     if (obj->IsFailure()) break;
     HeapObject::cast(obj)->set_map(faked_map);
diff --git a/test/cctest/test-strtod.cc b/test/cctest/test-strtod.cc
new file mode 100644
index 0000000..ae1c00d
--- /dev/null
+++ b/test/cctest/test-strtod.cc
@@ -0,0 +1,207 @@
+// Copyright 2006-2008 the V8 project authors. All rights reserved.
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "strtod.h"
+
+using namespace v8::internal;
+
+static Vector<const char> StringToVector(const char* str) {
+  return Vector<const char>(str, StrLength(str));
+}
+
+
+static double StrtodChar(const char* str, int exponent) {
+  return Strtod(StringToVector(str), exponent);
+}
+
+
+TEST(Strtod) {
+  Vector<const char> vector;
+
+  vector = StringToVector("0");
+  CHECK_EQ(0.0, Strtod(vector, 1));
+  CHECK_EQ(0.0, Strtod(vector, 2));
+  CHECK_EQ(0.0, Strtod(vector, -2));
+  CHECK_EQ(0.0, Strtod(vector, -999));
+  CHECK_EQ(0.0, Strtod(vector, +999));
+
+  vector = StringToVector("1");
+  CHECK_EQ(1.0, Strtod(vector, 0));
+  CHECK_EQ(10.0, Strtod(vector, 1));
+  CHECK_EQ(100.0, Strtod(vector, 2));
+  CHECK_EQ(1e20, Strtod(vector, 20));
+  CHECK_EQ(1e22, Strtod(vector, 22));
+  CHECK_EQ(1e23, Strtod(vector, 23));
+  CHECK_EQ(1e35, Strtod(vector, 35));
+  CHECK_EQ(1e36, Strtod(vector, 36));
+  CHECK_EQ(1e37, Strtod(vector, 37));
+  CHECK_EQ(1e-1, Strtod(vector, -1));
+  CHECK_EQ(1e-2, Strtod(vector, -2));
+  CHECK_EQ(1e-5, Strtod(vector, -5));
+  CHECK_EQ(1e-20, Strtod(vector, -20));
+  CHECK_EQ(1e-22, Strtod(vector, -22));
+  CHECK_EQ(1e-23, Strtod(vector, -23));
+  CHECK_EQ(1e-25, Strtod(vector, -25));
+  CHECK_EQ(1e-39, Strtod(vector, -39));
+
+  vector = StringToVector("2");
+  CHECK_EQ(2.0, Strtod(vector, 0));
+  CHECK_EQ(20.0, Strtod(vector, 1));
+  CHECK_EQ(200.0, Strtod(vector, 2));
+  CHECK_EQ(2e20, Strtod(vector, 20));
+  CHECK_EQ(2e22, Strtod(vector, 22));
+  CHECK_EQ(2e23, Strtod(vector, 23));
+  CHECK_EQ(2e35, Strtod(vector, 35));
+  CHECK_EQ(2e36, Strtod(vector, 36));
+  CHECK_EQ(2e37, Strtod(vector, 37));
+  CHECK_EQ(2e-1, Strtod(vector, -1));
+  CHECK_EQ(2e-2, Strtod(vector, -2));
+  CHECK_EQ(2e-5, Strtod(vector, -5));
+  CHECK_EQ(2e-20, Strtod(vector, -20));
+  CHECK_EQ(2e-22, Strtod(vector, -22));
+  CHECK_EQ(2e-23, Strtod(vector, -23));
+  CHECK_EQ(2e-25, Strtod(vector, -25));
+  CHECK_EQ(2e-39, Strtod(vector, -39));
+
+  vector = StringToVector("9");
+  CHECK_EQ(9.0, Strtod(vector, 0));
+  CHECK_EQ(90.0, Strtod(vector, 1));
+  CHECK_EQ(900.0, Strtod(vector, 2));
+  CHECK_EQ(9e20, Strtod(vector, 20));
+  CHECK_EQ(9e22, Strtod(vector, 22));
+  CHECK_EQ(9e23, Strtod(vector, 23));
+  CHECK_EQ(9e35, Strtod(vector, 35));
+  CHECK_EQ(9e36, Strtod(vector, 36));
+  CHECK_EQ(9e37, Strtod(vector, 37));
+  CHECK_EQ(9e-1, Strtod(vector, -1));
+  CHECK_EQ(9e-2, Strtod(vector, -2));
+  CHECK_EQ(9e-5, Strtod(vector, -5));
+  CHECK_EQ(9e-20, Strtod(vector, -20));
+  CHECK_EQ(9e-22, Strtod(vector, -22));
+  CHECK_EQ(9e-23, Strtod(vector, -23));
+  CHECK_EQ(9e-25, Strtod(vector, -25));
+  CHECK_EQ(9e-39, Strtod(vector, -39));
+
+  vector = StringToVector("12345");
+  CHECK_EQ(12345.0, Strtod(vector, 0));
+  CHECK_EQ(123450.0, Strtod(vector, 1));
+  CHECK_EQ(1234500.0, Strtod(vector, 2));
+  CHECK_EQ(12345e20, Strtod(vector, 20));
+  CHECK_EQ(12345e22, Strtod(vector, 22));
+  CHECK_EQ(12345e23, Strtod(vector, 23));
+  CHECK_EQ(12345e30, Strtod(vector, 30));
+  CHECK_EQ(12345e31, Strtod(vector, 31));
+  CHECK_EQ(12345e32, Strtod(vector, 32));
+  CHECK_EQ(12345e35, Strtod(vector, 35));
+  CHECK_EQ(12345e36, Strtod(vector, 36));
+  CHECK_EQ(12345e37, Strtod(vector, 37));
+  CHECK_EQ(12345e-1, Strtod(vector, -1));
+  CHECK_EQ(12345e-2, Strtod(vector, -2));
+  CHECK_EQ(12345e-5, Strtod(vector, -5));
+  CHECK_EQ(12345e-20, Strtod(vector, -20));
+  CHECK_EQ(12345e-22, Strtod(vector, -22));
+  CHECK_EQ(12345e-23, Strtod(vector, -23));
+  CHECK_EQ(12345e-25, Strtod(vector, -25));
+  CHECK_EQ(12345e-39, Strtod(vector, -39));
+
+  vector = StringToVector("12345678901234");
+  CHECK_EQ(12345678901234.0, Strtod(vector, 0));
+  CHECK_EQ(123456789012340.0, Strtod(vector, 1));
+  CHECK_EQ(1234567890123400.0, Strtod(vector, 2));
+  CHECK_EQ(12345678901234e20, Strtod(vector, 20));
+  CHECK_EQ(12345678901234e22, Strtod(vector, 22));
+  CHECK_EQ(12345678901234e23, Strtod(vector, 23));
+  CHECK_EQ(12345678901234e30, Strtod(vector, 30));
+  CHECK_EQ(12345678901234e31, Strtod(vector, 31));
+  CHECK_EQ(12345678901234e32, Strtod(vector, 32));
+  CHECK_EQ(12345678901234e35, Strtod(vector, 35));
+  CHECK_EQ(12345678901234e36, Strtod(vector, 36));
+  CHECK_EQ(12345678901234e37, Strtod(vector, 37));
+  CHECK_EQ(12345678901234e-1, Strtod(vector, -1));
+  CHECK_EQ(12345678901234e-2, Strtod(vector, -2));
+  CHECK_EQ(12345678901234e-5, Strtod(vector, -5));
+  CHECK_EQ(12345678901234e-20, Strtod(vector, -20));
+  CHECK_EQ(12345678901234e-22, Strtod(vector, -22));
+  CHECK_EQ(12345678901234e-23, Strtod(vector, -23));
+  CHECK_EQ(12345678901234e-25, Strtod(vector, -25));
+  CHECK_EQ(12345678901234e-39, Strtod(vector, -39));
+
+  vector = StringToVector("123456789012345");
+  CHECK_EQ(123456789012345.0, Strtod(vector, 0));
+  CHECK_EQ(1234567890123450.0, Strtod(vector, 1));
+  CHECK_EQ(12345678901234500.0, Strtod(vector, 2));
+  CHECK_EQ(123456789012345e20, Strtod(vector, 20));
+  CHECK_EQ(123456789012345e22, Strtod(vector, 22));
+  CHECK_EQ(123456789012345e23, Strtod(vector, 23));
+  CHECK_EQ(123456789012345e35, Strtod(vector, 35));
+  CHECK_EQ(123456789012345e36, Strtod(vector, 36));
+  CHECK_EQ(123456789012345e37, Strtod(vector, 37));
+  CHECK_EQ(123456789012345e39, Strtod(vector, 39));
+  CHECK_EQ(123456789012345e-1, Strtod(vector, -1));
+  CHECK_EQ(123456789012345e-2, Strtod(vector, -2));
+  CHECK_EQ(123456789012345e-5, Strtod(vector, -5));
+  CHECK_EQ(123456789012345e-20, Strtod(vector, -20));
+  CHECK_EQ(123456789012345e-22, Strtod(vector, -22));
+  CHECK_EQ(123456789012345e-23, Strtod(vector, -23));
+  CHECK_EQ(123456789012345e-25, Strtod(vector, -25));
+  CHECK_EQ(123456789012345e-39, Strtod(vector, -39));
+
+  CHECK_EQ(0.0, StrtodChar("0", 12345));
+  CHECK_EQ(0.0, StrtodChar("", 1324));
+  CHECK_EQ(0.0, StrtodChar("000000000", 123));
+  CHECK_EQ(0.0, StrtodChar("2", -324));
+  CHECK_EQ(4e-324, StrtodChar("3", -324));
+  // It would be more readable to put non-zero literals on the left side (i.e.
+  //   CHECK_EQ(1e-325, StrtodChar("1", -325))), but then Gcc complains that
+  // they are truncated to zero.
+  CHECK_EQ(0.0, StrtodChar("1", -325));
+  CHECK_EQ(0.0, StrtodChar("1", -325));
+  CHECK_EQ(0.0, StrtodChar("20000", -328));
+  CHECK_EQ(40000e-328, StrtodChar("30000", -328));
+  CHECK_EQ(0.0, StrtodChar("10000", -329));
+  CHECK_EQ(0.0, StrtodChar("90000", -329));
+  CHECK_EQ(0.0, StrtodChar("000000001", -325));
+  CHECK_EQ(0.0, StrtodChar("000000001", -325));
+  CHECK_EQ(0.0, StrtodChar("0000000020000", -328));
+  CHECK_EQ(40000e-328, StrtodChar("00000030000", -328));
+  CHECK_EQ(0.0, StrtodChar("0000000010000", -329));
+  CHECK_EQ(0.0, StrtodChar("0000000090000", -329));
+
+  // It would be more readable to put the literals (and not V8_INFINITY) on the
+  // left side (i.e. CHECK_EQ(1e309, StrtodChar("1", 309))), but then Gcc
+  // complains that the floating constant exceeds range of 'double'.
+  CHECK_EQ(V8_INFINITY, StrtodChar("1", 309));
+  CHECK_EQ(1e308, StrtodChar("1", 308));
+  CHECK_EQ(1234e305, StrtodChar("1234", 305));
+  CHECK_EQ(1234e304, StrtodChar("1234", 304));
+  CHECK_EQ(V8_INFINITY, StrtodChar("18", 307));
+  CHECK_EQ(17e307, StrtodChar("17", 307));
+  CHECK_EQ(V8_INFINITY, StrtodChar("0000001", 309));
+  CHECK_EQ(1e308, StrtodChar("00000001", 308));
+  CHECK_EQ(1234e305, StrtodChar("00000001234", 305));
+  CHECK_EQ(1234e304, StrtodChar("000000001234", 304));
+  CHECK_EQ(V8_INFINITY, StrtodChar("0000000018", 307));
+  CHECK_EQ(17e307, StrtodChar("0000000017", 307));
+  CHECK_EQ(V8_INFINITY, StrtodChar("1000000", 303));
+  CHECK_EQ(1e308, StrtodChar("100000", 303));
+  CHECK_EQ(1234e305, StrtodChar("123400000", 300));
+  CHECK_EQ(1234e304, StrtodChar("123400000", 299));
+  CHECK_EQ(V8_INFINITY, StrtodChar("180000000", 300));
+  CHECK_EQ(17e307, StrtodChar("170000000", 300));
+  CHECK_EQ(V8_INFINITY, StrtodChar("00000001000000", 303));
+  CHECK_EQ(1e308, StrtodChar("000000000000100000", 303));
+  CHECK_EQ(1234e305, StrtodChar("00000000123400000", 300));
+  CHECK_EQ(1234e304, StrtodChar("0000000123400000", 299));
+  CHECK_EQ(V8_INFINITY, StrtodChar("00000000180000000", 300));
+  CHECK_EQ(17e307, StrtodChar("00000000170000000", 300));
+
+  // The following number is the result of 89255.0/1e-22. Both floating-point
+  // numbers can be accurately represented with doubles. However on Linux,x86
+  // the floating-point stack is set to 80bits and the double-rounding
+  // introduces an error.
+  CHECK_EQ(89255e-22, StrtodChar("89255", -22));
+}
diff --git a/test/mjsunit/abs.js b/test/mjsunit/abs.js
deleted file mode 100644
index d1c453c..0000000
--- a/test/mjsunit/abs.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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 Math.sin and Math.abs.
-
-assertEquals(1, Math.abs(1));  // Positive SMI.
-assertEquals(1, Math.abs(-1));  // Negative SMI.
-assertEquals(0.5, Math.abs(0.5));  // Positive double.
-assertEquals(0.5, Math.abs(-0.5));  // Negative double.
-assertEquals('Infinity', Math.abs(Number('+Infinity').toString()));
-assertEquals('Infinity', Math.abs(Number('-Infinity').toString()));
-assertEquals('NaN', Math.abs(NaN).toString());
-assertEquals('NaN', Math.abs(-NaN).toString());
-
-var minusZero = 1 / (-1 / 0);
-function isMinusZero(x) {
-  return x === 0 && 1 / x < 0;
-}
-
-assertTrue(!isMinusZero(0));
-assertTrue(isMinusZero(minusZero));
-assertEquals(0, Math.abs(minusZero));
-assertTrue(!isMinusZero(Math.abs(minusZero)));
-assertTrue(!isMinusZero(Math.abs(0.0)));
diff --git a/test/mjsunit/binary-op-newspace.js b/test/mjsunit/binary-op-newspace.js
index 40d53b9..032284c 100644
--- a/test/mjsunit/binary-op-newspace.js
+++ b/test/mjsunit/binary-op-newspace.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: --max-new-space-size=262144
+// Flags: --max-new-space-size=256
 
 
 // Check that a mod where the stub code hits a failure in heap number
diff --git a/test/mjsunit/int32-ops.js b/test/mjsunit/int32-ops.js
new file mode 100644
index 0000000..1883926
--- /dev/null
+++ b/test/mjsunit/int32-ops.js
@@ -0,0 +1,227 @@
+// 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.
+
+// Repeat most the tests in smi-ops.js that use SMI_MIN and SMI_MAX, but
+// with SMI_MIN and SMI_MAX from the 64-bit platform, which represents all
+// signed 32-bit integer values as smis.
+
+const SMI_MAX = (1 << 30) - 1 + (1 << 30);  // Create without overflowing.
+const SMI_MIN = -SMI_MAX - 1;  // Create without overflowing.
+const ONE = 1;
+const ONE_HUNDRED = 100;
+
+const OBJ_42 = new (function() {
+  this.valueOf = function() { return 42; };
+})();
+
+assertEquals(42, OBJ_42.valueOf());
+
+
+function Add1(x) {
+  return x + 1;
+}
+
+function Add100(x) {
+  return x + 100;
+}
+
+function Add1Reversed(x) {
+  return 1 + x;
+}
+
+function Add100Reversed(x) {
+  return 100 + x;
+}
+
+
+assertEquals(1, Add1(0));  // fast case
+assertEquals(1, Add1Reversed(0));  // fast case
+assertEquals(SMI_MAX + ONE, Add1(SMI_MAX), "smimax + 1");
+assertEquals(SMI_MAX + ONE, Add1Reversed(SMI_MAX), "1 + smimax");
+assertEquals(42 + ONE, Add1(OBJ_42));  // non-smi
+assertEquals(42 + ONE, Add1Reversed(OBJ_42));  // non-smi
+
+assertEquals(100, Add100(0));  // fast case
+assertEquals(100, Add100Reversed(0));  // fast case
+assertEquals(SMI_MAX + ONE_HUNDRED, Add100(SMI_MAX), "smimax + 100");
+assertEquals(SMI_MAX + ONE_HUNDRED, Add100Reversed(SMI_MAX), " 100 + smimax");
+assertEquals(42 + ONE_HUNDRED, Add100(OBJ_42));  // non-smi
+assertEquals(42 + ONE_HUNDRED, Add100Reversed(OBJ_42));  // non-smi
+
+
+
+function Sub1(x) {
+  return x - 1;
+}
+
+function Sub100(x) {
+  return x - 100;
+}
+
+function Sub1Reversed(x) {
+  return 1 - x;
+}
+
+function Sub100Reversed(x) {
+  return 100 - x;
+}
+
+
+assertEquals(0, Sub1(1));  // fast case
+assertEquals(-1, Sub1Reversed(2));  // fast case
+assertEquals(SMI_MIN - ONE, Sub1(SMI_MIN));  // overflow
+assertEquals(ONE - SMI_MIN, Sub1Reversed(SMI_MIN));  // overflow
+assertEquals(42 - ONE, Sub1(OBJ_42));  // non-smi
+assertEquals(ONE - 42, Sub1Reversed(OBJ_42));  // non-smi
+
+assertEquals(0, Sub100(100));  // fast case
+assertEquals(1, Sub100Reversed(99));  // fast case
+assertEquals(SMI_MIN - ONE_HUNDRED, Sub100(SMI_MIN));  // overflow
+assertEquals(ONE_HUNDRED - SMI_MIN, Sub100Reversed(SMI_MIN));  // overflow
+assertEquals(42 - ONE_HUNDRED, Sub100(OBJ_42));  // non-smi
+assertEquals(ONE_HUNDRED - 42, Sub100Reversed(OBJ_42));  // non-smi
+
+
+function Shr1(x) {
+  return x >>> 1;
+}
+
+function Shr100(x) {
+  return x >>> 100;
+}
+
+function Shr1Reversed(x) {
+  return 1 >>> x;
+}
+
+function Shr100Reversed(x) {
+  return 100 >>> x;
+}
+
+function Sar1(x) {
+  return x >> 1;
+}
+
+function Sar100(x) {
+  return x >> 100;
+}
+
+function Sar1Reversed(x) {
+  return 1 >> x;
+}
+
+function Sar100Reversed(x) {
+  return 100 >> x;
+}
+
+
+assertEquals(0, Shr1(1));
+assertEquals(0, Sar1(1));
+assertEquals(0, Shr1Reversed(2));
+assertEquals(0, Sar1Reversed(2));
+assertEquals(1073741824, Shr1(SMI_MIN));
+assertEquals(-1073741824, Sar1(SMI_MIN));
+assertEquals(1, Shr1Reversed(SMI_MIN));
+assertEquals(1, Sar1Reversed(SMI_MIN));
+assertEquals(21, Shr1(OBJ_42));
+assertEquals(21, Sar1(OBJ_42));
+assertEquals(0, Shr1Reversed(OBJ_42));
+assertEquals(0, Sar1Reversed(OBJ_42));
+
+assertEquals(6, Shr100(100), "100 >>> 100");
+assertEquals(6, Sar100(100), "100 >> 100");
+assertEquals(12, Shr100Reversed(99));
+assertEquals(12, Sar100Reversed(99));
+assertEquals(134217728, Shr100(SMI_MIN));
+assertEquals(-134217728, Sar100(SMI_MIN));
+assertEquals(100, Shr100Reversed(SMI_MIN));
+assertEquals(100, Sar100Reversed(SMI_MIN));
+assertEquals(2, Shr100(OBJ_42));
+assertEquals(2, Sar100(OBJ_42));
+assertEquals(0, Shr100Reversed(OBJ_42));
+assertEquals(0, Sar100Reversed(OBJ_42));
+
+
+function Xor1(x) {
+  return x ^ 1;
+}
+
+function Xor100(x) {
+  return x ^ 100;
+}
+
+function Xor1Reversed(x) {
+  return 1 ^ x;
+}
+
+function Xor100Reversed(x) {
+  return 100 ^ x;
+}
+
+
+assertEquals(0, Xor1(1));
+assertEquals(3, Xor1Reversed(2));
+assertEquals(SMI_MIN + 1, Xor1(SMI_MIN));
+assertEquals(SMI_MIN + 1, Xor1Reversed(SMI_MIN));
+assertEquals(43, Xor1(OBJ_42));
+assertEquals(43, Xor1Reversed(OBJ_42));
+
+assertEquals(0, Xor100(100));
+assertEquals(7, Xor100Reversed(99));
+assertEquals(-2147483548, Xor100(SMI_MIN));
+assertEquals(-2147483548, Xor100Reversed(SMI_MIN));
+assertEquals(78, Xor100(OBJ_42));
+assertEquals(78, Xor100Reversed(OBJ_42));
+
+var x = 0x23; var y = 0x35;
+assertEquals(0x16, x ^ y);
+
+
+// Bitwise not.
+var v = 0;
+assertEquals(-1, ~v);
+v = SMI_MIN;
+assertEquals(0x7fffffff, ~v, "~smimin");
+v = SMI_MAX;
+assertEquals(-0x80000000, ~v, "~smimax");
+
+// Overflowing ++ and --.
+v = SMI_MAX;
+v++;
+assertEquals(0x80000000, v, "smimax++");
+v = SMI_MIN;
+v--;
+assertEquals(-0x80000001, v, "smimin--");
+
+// Check that comparisons of numbers separated by MIN_SMI work.
+assertFalse(SMI_MIN > 0);
+assertFalse(SMI_MIN + 1 > 1);
+assertFalse(SMI_MIN + 1 > 2);
+assertFalse(SMI_MIN + 2 > 1);
+assertFalse(0 < SMI_MIN);
+assertTrue(-1 < SMI_MAX);
+assertFalse(SMI_MAX < -1);
diff --git a/test/mjsunit/math-abs.js b/test/mjsunit/math-abs.js
new file mode 100644
index 0000000..bec1a01
--- /dev/null
+++ b/test/mjsunit/math-abs.js
@@ -0,0 +1,98 @@
+// 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: --max-new-space-size=256
+
+function zero() {
+  var x = 0.5;
+  return (function() { return x - 0.5; })();
+}
+
+function test() {
+  assertEquals(0, Math.abs(0));
+  assertEquals(0, Math.abs(zero()));
+  assertEquals(1/0, 1/Math.abs(-0));  // 0 == -0, so we use reciprocals.
+  assertEquals(Infinity, Math.abs(Infinity));
+  assertEquals(Infinity, Math.abs(-Infinity));
+  assertNaN(Math.abs(NaN));
+  assertNaN(Math.abs(-NaN));
+  assertEquals('Infinity', Math.abs(Number('+Infinity').toString()));
+  assertEquals('Infinity', Math.abs(Number('-Infinity').toString()));
+  assertEquals('NaN', Math.abs(NaN).toString());
+  assertEquals('NaN', Math.abs(-NaN).toString());
+
+  assertEquals(0.1, Math.abs(0.1));
+  assertEquals(0.5, Math.abs(0.5));
+  assertEquals(0.1, Math.abs(-0.1));
+  assertEquals(0.5, Math.abs(-0.5));
+  assertEquals(1, Math.abs(1));
+  assertEquals(1.1, Math.abs(1.1));
+  assertEquals(1.5, Math.abs(1.5));
+  assertEquals(1, Math.abs(-1));
+  assertEquals(1.1, Math.abs(-1.1));
+  assertEquals(1.5, Math.abs(-1.5));
+
+  assertEquals(Number.MIN_VALUE, Math.abs(Number.MIN_VALUE));
+  assertEquals(Number.MIN_VALUE, Math.abs(-Number.MIN_VALUE));
+  assertEquals(Number.MAX_VALUE, Math.abs(Number.MAX_VALUE));
+  assertEquals(Number.MAX_VALUE, Math.abs(-Number.MAX_VALUE));
+
+  // 2^30 is a smi boundary on arm and ia32.
+  var two_30 = 1 << 30;
+
+  assertEquals(two_30, Math.abs(two_30));
+  assertEquals(two_30, Math.abs(-two_30));
+
+  assertEquals(two_30 + 1, Math.abs(two_30 + 1));
+  assertEquals(two_30 + 1, Math.abs(-two_30 - 1));
+
+  assertEquals(two_30 - 1, Math.abs(two_30 - 1));
+  assertEquals(two_30 - 1, Math.abs(-two_30 + 1));
+
+  // 2^31 is a smi boundary on x64.
+  var two_31 = 2 * two_30;
+
+  assertEquals(two_31, Math.abs(two_31));
+  assertEquals(two_31, Math.abs(-two_31));
+
+  assertEquals(two_31 + 1, Math.abs(two_31 + 1));
+  assertEquals(two_31 + 1, Math.abs(-two_31 - 1));
+
+  assertEquals(two_31 - 1, Math.abs(two_31 - 1));
+  assertEquals(two_31 - 1, Math.abs(-two_31 + 1));
+
+  assertNaN(Math.abs("not a number"));
+  assertNaN(Math.abs([1, 2, 3]));
+  assertEquals(42, Math.abs({valueOf: function() { return 42; } }));
+  assertEquals(42, Math.abs({valueOf: function() { return -42; } }));
+}
+
+
+// Test in a loop to cover the custom IC and GC-related issues.
+for (var i = 0; i < 500; i++) {
+  test();
+}
diff --git a/test/mjsunit/math-floor.js b/test/mjsunit/math-floor.js
index e56341c..0d1c0ac 100644
--- a/test/mjsunit/math-floor.js
+++ b/test/mjsunit/math-floor.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: --max-new-space-size=262144
+// Flags: --max-new-space-size=256
 
 function zero() {
   var x = 0.5;
diff --git a/test/mjsunit/regexp.js b/test/mjsunit/regexp.js
index db8b133..b57b86d 100644
--- a/test/mjsunit/regexp.js
+++ b/test/mjsunit/regexp.js
@@ -502,3 +502,148 @@
   res[3] = "Glopglyf";
   assertEquals("Arglebargle", res.foobar);
 }
+
+// Test that we perform the spec required conversions in the correct order.
+var log;
+var string = "the string";
+var fakeLastIndex = { 
+      valueOf: function() { 
+        log.push("li");
+        return 0;
+      } 
+    };
+var fakeString = { 
+      toString: function() {
+        log.push("ts");
+        return string;
+      }, 
+      length: 0 
+    };
+
+var re = /str/;
+log = [];
+re.lastIndex = fakeLastIndex;
+var result = re.exec(fakeString);
+assertEquals(["str"], result);
+assertEquals(["ts", "li"], log);
+
+// Again, to check if caching interferes.
+log = [];
+re.lastIndex = fakeLastIndex;
+result = re.exec(fakeString);
+assertEquals(["str"], result);
+assertEquals(["ts", "li"], log);
+
+// And one more time, just to be certain.
+log = [];
+re.lastIndex = fakeLastIndex;
+result = re.exec(fakeString);
+assertEquals(["str"], result);
+assertEquals(["ts", "li"], log);
+
+// Now with a global regexp, where lastIndex is actually used.
+re = /str/g;
+log = [];
+re.lastIndex = fakeLastIndex;
+var result = re.exec(fakeString);
+assertEquals(["str"], result);
+assertEquals(["ts", "li"], log);
+
+// Again, to check if caching interferes.
+log = [];
+re.lastIndex = fakeLastIndex;
+result = re.exec(fakeString);
+assertEquals(["str"], result);
+assertEquals(["ts", "li"], log);
+
+// And one more time, just to be certain.
+log = [];
+re.lastIndex = fakeLastIndex;
+result = re.exec(fakeString);
+assertEquals(["str"], result);
+assertEquals(["ts", "li"], log);
+
+
+// Check that properties of RegExp have the correct permissions.
+var re = /x/g;
+var desc = Object.getOwnPropertyDescriptor(re, "global");
+assertEquals(true, desc.value);
+assertEquals(false, desc.configurable);
+assertEquals(false, desc.enumerable);
+assertEquals(false, desc.writable);
+
+desc = Object.getOwnPropertyDescriptor(re, "multiline");
+assertEquals(false, desc.value);
+assertEquals(false, desc.configurable);
+assertEquals(false, desc.enumerable);
+assertEquals(false, desc.writable);
+
+desc = Object.getOwnPropertyDescriptor(re, "ignoreCase");
+assertEquals(false, desc.value);
+assertEquals(false, desc.configurable);
+assertEquals(false, desc.enumerable);
+assertEquals(false, desc.writable);
+
+desc = Object.getOwnPropertyDescriptor(re, "lastIndex");
+assertEquals(0, desc.value);
+assertEquals(false, desc.configurable);
+assertEquals(false, desc.enumerable);
+assertEquals(true, desc.writable);
+
+
+// Check that end-anchored regexps are optimized correctly.
+var re = /(?:a|bc)g$/;
+assertTrue(re.test("ag"));
+assertTrue(re.test("bcg"));
+assertTrue(re.test("abcg"));
+assertTrue(re.test("zimbag"));
+assertTrue(re.test("zimbcg"));
+
+assertFalse(re.test("g"));
+assertFalse(re.test(""));
+
+// Global regexp (non-zero start).
+var re = /(?:a|bc)g$/g;
+assertTrue(re.test("ag"));
+re.lastIndex = 1;  // Near start of string.
+assertTrue(re.test("zimbag"));
+re.lastIndex = 6;  // At end of string.
+assertFalse(re.test("zimbag"));
+re.lastIndex = 5;  // Near end of string.
+assertFalse(re.test("zimbag"));
+re.lastIndex = 4;
+assertTrue(re.test("zimbag"));
+
+// Anchored at both ends.
+var re = /^(?:a|bc)g$/g;
+assertTrue(re.test("ag"));
+re.lastIndex = 1;
+assertFalse(re.test("ag"));
+re.lastIndex = 1;
+assertFalse(re.test("zag"));
+
+// Long max_length of RegExp.
+var re = /VeryLongRegExp!{1,1000}$/;
+assertTrue(re.test("BahoolaVeryLongRegExp!!!!!!"));
+assertFalse(re.test("VeryLongRegExp"));
+assertFalse(re.test("!"));
+
+// End anchor inside disjunction.
+var re = /(?:a$|bc$)/;
+assertTrue(re.test("a"));
+assertTrue(re.test("bc"));
+assertTrue(re.test("abc"));
+assertTrue(re.test("zimzamzumba"));
+assertTrue(re.test("zimzamzumbc"));
+assertFalse(re.test("c"));
+assertFalse(re.test(""));
+
+// Only partially anchored.
+var re = /(?:a|bc$)/;
+assertTrue(re.test("a"));
+assertTrue(re.test("bc"));
+assertEquals(["a"], re.exec("abc"));
+assertEquals(4, re.exec("zimzamzumba").index);
+assertEquals(["bc"], re.exec("zimzomzumbc"));
+assertFalse(re.test("c"));
+assertFalse(re.test(""));
diff --git a/src/vm-state.cc b/test/mjsunit/regress/regress-58740.js
similarity index 88%
rename from src/vm-state.cc
rename to test/mjsunit/regress/regress-58740.js
index 6bd737d..ab3e93b 100644
--- a/src/vm-state.cc
+++ b/test/mjsunit/regress/regress-58740.js
@@ -25,15 +25,11 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "v8.h"
+// See: http://code.google.com/p/chromium/issues/detail?id=58740
 
-#include "vm-state.h"
-
-namespace v8 {
-namespace internal {
-
-#ifdef ENABLE_VMSTATE_TRACKING
-AtomicWord VMState::current_state_ = 0;
-#endif
-
-} }  // namespace v8::internal
+var re = /.+/g;
+re.exec("");
+re.exec("anystring");
+re=/.+/g;
+re.exec("");
+assertEquals(0, re.lastIndex);
diff --git a/src/vm-state.cc b/test/mjsunit/regress/regress-create-exception.js
similarity index 64%
copy from src/vm-state.cc
copy to test/mjsunit/regress/regress-create-exception.js
index 6bd737d..7d53f1c 100644
--- a/src/vm-state.cc
+++ b/test/mjsunit/regress/regress-create-exception.js
@@ -25,15 +25,34 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "v8.h"
+// Flags: --max-new-space-size=256
 
-#include "vm-state.h"
+// Check for GC bug constructing exceptions.
+var v = [1, 2, 3, 4]
 
-namespace v8 {
-namespace internal {
+Object.preventExtensions(v);
 
-#ifdef ENABLE_VMSTATE_TRACKING
-AtomicWord VMState::current_state_ = 0;
-#endif
+function foo() {
+  var re = /2147483647/;  // Equal to 0x7fffffff.
+  for  (var i = 0; i < 10000; i++) {
+    var ok = false;
+    try {
+      var j = 1;
+      // Allocate some heap numbers in order to randomize the behaviour of the
+      // garbage collector.  93 is chosen to be a prime number to avoid the
+      // allocation settling into a too neat pattern.
+      for (var j = 0; j < i % 93; j++) {
+        j *= 1.123567;  // An arbitrary floating point number.
+      }
+      v[0x7fffffff] = 0;  // Trigger exception.
+      assertTrue(false);
+      return j;  // Make sure that future optimizations don't eliminate j.
+    } catch(e) {
+      ok = true;
+      assertTrue(re.test(e));
+    }
+    assertTrue(ok);
+  }
+}
 
-} }  // namespace v8::internal
+foo();
diff --git a/test/mjsunit/smi-negative-zero.js b/test/mjsunit/smi-negative-zero.js
index 6906443..ea2fa5a 100644
--- a/test/mjsunit/smi-negative-zero.js
+++ b/test/mjsunit/smi-negative-zero.js
@@ -98,3 +98,16 @@
 assertEquals(-Infinity, one / (-4 % -2), "fiskhest2");
 assertEquals(Infinity, one / (4 % 2), "fiskhest3");
 assertEquals(Infinity, one / (4 % -2), "fiskhest4");
+
+
+// This tests against a singleton -0.0 object being overwritten.gc
+x = 0;
+z = 3044;
+
+function foo(x) {
+  var y = -x + z;
+  return -x;
+}
+
+assertEquals(0, foo(x));
+assertEquals(0, foo(x));
diff --git a/test/mjsunit/smi-ops.js b/test/mjsunit/smi-ops.js
index 499535c..8fa6fec 100644
--- a/test/mjsunit/smi-ops.js
+++ b/test/mjsunit/smi-ops.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2010 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,8 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-const SMI_MAX = (1 << 30) - 1;
-const SMI_MIN = -(1 << 30);
+const SMI_MAX = (1 << 29) - 1 + (1 << 29);  // Create without overflowing.
+const SMI_MIN = -SMI_MAX - 1;  // Create without overflowing.
 const ONE = 1;
 const ONE_HUNDRED = 100;
 
@@ -213,6 +213,15 @@
 v--;
 assertEquals(-0x40000001, v, "smimin--");
 
+// Check that comparisons of numbers separated by MIN_SMI work.
+assertFalse(SMI_MIN > 0);
+assertFalse(SMI_MIN + 1 > 1);
+assertFalse(SMI_MIN + 1 > 2);
+assertFalse(SMI_MIN + 2 > 1);
+assertFalse(0 < SMI_MIN);
+assertTrue(-1 < SMI_MAX);
+assertFalse(SMI_MAX < -1);
+
 // Not actually Smi operations.
 // Check that relations on unary ops work.
 var v = -1.2;
diff --git a/test/mjsunit/string-indexof-1.js b/test/mjsunit/string-indexof-1.js
index c7dcdb8..c5ae4b8 100644
--- a/test/mjsunit/string-indexof-1.js
+++ b/test/mjsunit/string-indexof-1.js
@@ -97,3 +97,29 @@
 pattern = "JABACABADABACABA";
 assertEquals(511, long.indexOf(pattern), "Long JABACABA..., First J");
 assertEquals(1535, long.indexOf(pattern, 512), "Long JABACABA..., Second J");
+
+
+// Search for a non-ASCII string in a pure ASCII string.
+var asciiString = "arglebargleglopglyfarglebargleglopglyfarglebargleglopglyf";
+assertEquals(-1, asciiString.indexOf("\x2061"));
+
+
+// Search in string containing many non-ASCII chars.
+var allCodePoints = [];
+for (var i = 0; i < 65536; i++) allCodePoints[i] = i;
+var allCharsString = String.fromCharCode.apply(String, allCodePoints);
+// Search for string long enough to trigger complex search with ASCII pattern
+// and UC16 subject.
+assertEquals(-1, allCharsString.indexOf("notfound"));
+
+// Find substrings.
+var lengths = [1, 4, 15];  // Single char, simple and complex.
+var indices = [0x5, 0x65, 0x85, 0x105, 0x205, 0x285, 0x2005, 0x2085, 0xfff0];
+for (var lengthIndex = 0; lengthIndex < lengths.length; lengthIndex++) {
+  var length = lengths[lengthIndex];
+  for (var i = 0; i < indices.length; i++) {
+    var index = indices[i];
+    var pattern = allCharsString.substring(index, index + length);
+    assertEquals(index, allCharsString.indexOf(pattern));
+  }
+}
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index b355fb6..17d556f 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -285,6 +285,7 @@
         '../../src/builtins.cc',
         '../../src/builtins.h',
         '../../src/bytecodes-irregexp.h',
+        '../../src/cached-powers.cc',
         '../../src/cached-powers.h',
         '../../src/char-predicates-inl.h',
         '../../src/char-predicates.h',
@@ -402,7 +403,6 @@
         '../../src/parser.cc',
         '../../src/parser.h',
         '../../src/platform.h',
-        '../../src/powers-ten.h',
         '../../src/prettyprinter.cc',
         '../../src/prettyprinter.h',
         '../../src/property.cc',
@@ -441,8 +441,12 @@
         '../../src/spaces-inl.h',
         '../../src/spaces.cc',
         '../../src/spaces.h',
+        '../../src/string-search.cc',
+        '../../src/string-search.h',
         '../../src/string-stream.cc',
         '../../src/string-stream.h',
+        '../../src/strtod.cc',
+        '../../src/strtod.h',
         '../../src/stub-cache.cc',
         '../../src/stub-cache.h',
         '../../src/token.cc',
@@ -472,7 +476,6 @@
         '../../src/virtual-frame.cc',
         '../../src/virtual-frame.h',
         '../../src/vm-state-inl.h',
-        '../../src/vm-state.cc',
         '../../src/vm-state.h',
         '../../src/zone-inl.h',
         '../../src/zone.cc',
diff --git a/tools/ll_prof.py b/tools/ll_prof.py
new file mode 100755
index 0000000..563084d
--- /dev/null
+++ b/tools/ll_prof.py
@@ -0,0 +1,955 @@
+#!/usr/bin/env python
+#
+# 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.
+
+import bisect
+import collections
+import ctypes
+import mmap
+import optparse
+import os
+import re
+import subprocess
+import sys
+import tempfile
+import time
+
+
+USAGE="""usage: %prog [OPTION]...
+
+Analyses V8 and perf logs to produce profiles.
+
+Perf logs can be collected using a command like:
+  $ perf record -R -e cycles -c 10000 -f -i ./shell bench.js --ll-prof
+  # -R: collect all data
+  # -e cycles: use cpu-cycles event (run "perf list" for details)
+  # -c 10000: write a sample after each 10000 events
+  # -f: force output file overwrite
+  # -i: limit profiling to our process and the kernel
+  # --ll-prof shell flag enables the right V8 logs
+This will produce a binary trace file (perf.data) that %prog can analyse.
+
+Examples:
+  # Print flat profile with annotated disassembly for the 10 top
+  # symbols. Use default log names and include the snapshot log.
+  $ %prog --snapshot --disasm-top=10
+
+  # Print flat profile with annotated disassembly for all used symbols.
+  # Use default log names and include kernel symbols into analysis.
+  $ %prog --disasm-all --kernel
+
+  # Print flat profile. Use custom log names.
+  $ %prog --log=foo.log --snapshot-log=snap-foo.log --trace=foo.data --snapshot
+"""
+
+
+# Must match kGcFakeMmap.
+V8_GC_FAKE_MMAP = "/tmp/__v8_gc__"
+
+JS_ORIGIN = "js"
+JS_SNAPSHOT_ORIGIN = "js-snapshot"
+
+# Avoid using the slow (google-specific) wrapper around objdump.
+OBJDUMP_BIN = "/usr/bin/objdump"
+if not os.path.exists(OBJDUMP_BIN):
+  OBJDUMP_BIN = "objdump"
+
+
+class Code(object):
+  """Code object."""
+
+  _COMMON_DISASM_OPTIONS = ["-M", "intel-mnemonic", "-C"]
+
+  _DISASM_HEADER_RE = re.compile(r"[a-f0-9]+\s+<.*:$")
+  _DISASM_LINE_RE = re.compile(r"\s*([a-f0-9]+):.*")
+
+  # Keys must match constants in Logger::LogCodeInfo.
+  _ARCH_MAP = {
+    "ia32": "-m i386",
+    "x64": "-m i386 -M x86-64",
+    "arm": "-m arm"  # Not supported by our objdump build.
+  }
+
+  _id = 0
+
+  def __init__(self, name, start_address, end_address, origin, origin_offset):
+    self.id = Code._id
+    Code._id += 1
+    self.name = name
+    self.other_names = None
+    self.start_address = start_address
+    self.end_address = end_address
+    self.origin = origin
+    self.origin_offset = origin_offset
+    self.self_ticks = 0
+    self.self_ticks_map = None
+    self.callee_ticks = None
+
+  def AddName(self, name):
+    assert self.name != name
+    if self.other_names is None:
+      self.other_names = [name]
+      return
+    if not name in self.other_names:
+      self.other_names.append(name)
+
+  def FullName(self):
+    if self.other_names is None:
+      return self.name
+    self.other_names.sort()
+    return "%s (aka %s)" % (self.name, ", ".join(self.other_names))
+
+  def IsUsed(self):
+    return self.self_ticks > 0 or self.callee_ticks is not None
+
+  def Tick(self, pc):
+    self.self_ticks += 1
+    if self.self_ticks_map is None:
+      self.self_ticks_map = collections.defaultdict(lambda: 0)
+    offset = pc - self.start_address
+    self.self_ticks_map[offset] += 1
+
+  def CalleeTick(self, callee):
+    if self.callee_ticks is None:
+      self.callee_ticks = collections.defaultdict(lambda: 0)
+    self.callee_ticks[callee] += 1
+
+  def PrintAnnotated(self, code_info, options):
+    if self.self_ticks_map is None:
+      ticks_map = []
+    else:
+      ticks_map = self.self_ticks_map.items()
+    # Convert the ticks map to offsets and counts arrays so that later
+    # we can do binary search in the offsets array.
+    ticks_map.sort(key=lambda t: t[0])
+    ticks_offsets = [t[0] for t in ticks_map]
+    ticks_counts = [t[1] for t in ticks_map]
+    # Get a list of disassembled lines and their addresses.
+    lines = []
+    for line in self._GetDisasmLines(code_info, options):
+      match = Code._DISASM_LINE_RE.match(line)
+      if match:
+        line_address = int(match.group(1), 16)
+        lines.append((line_address, line))
+    if len(lines) == 0:
+      return
+    # Print annotated lines.
+    address = lines[0][0]
+    total_count = 0
+    for i in xrange(len(lines)):
+      start_offset = lines[i][0] - address
+      if i == len(lines) - 1:
+        end_offset = self.end_address - self.start_address
+      else:
+        end_offset = lines[i + 1][0] - address
+      # Ticks (reported pc values) are not always precise, i.e. not
+      # necessarily point at instruction starts. So we have to search
+      # for ticks that touch the current instruction line.
+      j = bisect.bisect_left(ticks_offsets, end_offset)
+      count = 0
+      for offset, cnt in reversed(zip(ticks_offsets[:j], ticks_counts[:j])):
+        if offset < start_offset:
+          break
+        count += cnt
+      total_count += count
+      count = 100.0 * count / self.self_ticks
+      if count >= 0.01:
+        print "%15.2f %s" % (count, lines[i][1])
+      else:
+        print "%s %s" % (" " * 15, lines[i][1])
+    print
+    assert total_count == self.self_ticks, \
+        "Lost ticks (%d != %d) in %s" % (total_count, self.self_ticks, self)
+
+  def __str__(self):
+    return "%s [0x%x, 0x%x) size: %d origin: %s" % (
+      self.name,
+      self.start_address,
+      self.end_address,
+      self.end_address - self.start_address,
+      self.origin)
+
+  def _GetDisasmLines(self, code_info, options):
+    tmp_name = None
+    if self.origin == JS_ORIGIN or self.origin == JS_SNAPSHOT_ORIGIN:
+      assert code_info.arch in Code._ARCH_MAP, \
+          "Unsupported architecture '%s'" % arch
+      arch_flags = Code._ARCH_MAP[code_info.arch]
+      # Create a temporary file just with this code object.
+      tmp_name = tempfile.mktemp(".v8code")
+      size = self.end_address - self.start_address
+      command = "dd if=%s.code of=%s bs=1 count=%d skip=%d && " \
+                "%s %s -D -b binary %s %s" % (
+        options.log, tmp_name, size, self.origin_offset,
+        OBJDUMP_BIN, ' '.join(Code._COMMON_DISASM_OPTIONS), arch_flags,
+        tmp_name)
+    else:
+      command = "%s %s --start-address=%d --stop-address=%d -d %s " % (
+        OBJDUMP_BIN, ' '.join(Code._COMMON_DISASM_OPTIONS),
+        self.origin_offset,
+        self.origin_offset + self.end_address - self.start_address,
+        self.origin)
+    process = subprocess.Popen(command,
+                               shell=True,
+                               stdout=subprocess.PIPE,
+                               stderr=subprocess.STDOUT)
+    out, err = process.communicate()
+    lines = out.split("\n")
+    header_line = 0
+    for i, line in enumerate(lines):
+      if Code._DISASM_HEADER_RE.match(line):
+        header_line = i
+        break
+    if tmp_name:
+      os.unlink(tmp_name)
+    return lines[header_line + 1:]
+
+
+class CodePage(object):
+  """Group of adjacent code objects."""
+
+  SHIFT = 12  # 4K pages
+  SIZE = (1 << SHIFT)
+  MASK = ~(SIZE - 1)
+
+  @staticmethod
+  def PageAddress(address):
+    return address & CodePage.MASK
+
+  @staticmethod
+  def PageId(address):
+    return address >> CodePage.SHIFT
+
+  @staticmethod
+  def PageAddressFromId(id):
+    return id << CodePage.SHIFT
+
+  def __init__(self, address):
+    self.address = address
+    self.code_objects = []
+
+  def Add(self, code):
+    self.code_objects.append(code)
+
+  def Remove(self, code):
+    self.code_objects.remove(code)
+
+  def Find(self, pc):
+    code_objects = self.code_objects
+    for i, code in enumerate(code_objects):
+      if code.start_address <= pc < code.end_address:
+        code_objects[0], code_objects[i] = code, code_objects[0]
+        return code
+    return None
+
+  def __iter__(self):
+    return self.code_objects.__iter__()
+
+
+class CodeMap(object):
+  """Code object map."""
+
+  def __init__(self):
+    self.pages = {}
+    self.min_address = 1 << 64
+    self.max_address = -1
+
+  def Add(self, code, max_pages=-1):
+    page_id = CodePage.PageId(code.start_address)
+    limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1)
+    pages = 0
+    while page_id < limit_id:
+      if max_pages >= 0 and pages > max_pages:
+        print >>sys.stderr, \
+            "Warning: page limit (%d) reached for %s [%s]" % (
+            max_pages, code.name, code.origin)
+        break
+      if page_id in self.pages:
+        page = self.pages[page_id]
+      else:
+        page = CodePage(CodePage.PageAddressFromId(page_id))
+        self.pages[page_id] = page
+      page.Add(code)
+      page_id += 1
+      pages += 1
+    self.min_address = min(self.min_address, code.start_address)
+    self.max_address = max(self.max_address, code.end_address)
+
+  def Remove(self, code):
+    page_id = CodePage.PageId(code.start_address)
+    limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1)
+    removed = False
+    while page_id < limit_id:
+      if page_id not in self.pages:
+        page_id += 1
+        continue
+      page = self.pages[page_id]
+      page.Remove(code)
+      removed = True
+      page_id += 1
+    return removed
+
+  def AllCode(self):
+    for page in self.pages.itervalues():
+      for code in page:
+        if CodePage.PageAddress(code.start_address) == page.address:
+          yield code
+
+  def UsedCode(self):
+    for code in self.AllCode():
+      if code.IsUsed():
+        yield code
+
+  def Print(self):
+    for code in self.AllCode():
+      print code
+
+  def Find(self, pc):
+    if pc < self.min_address or pc >= self.max_address:
+      return None
+    page_id = CodePage.PageId(pc)
+    if page_id not in self.pages:
+      return None
+    return self.pages[page_id].Find(pc)
+
+
+class CodeInfo(object):
+  """Generic info about generated code objects."""
+
+  def __init__(self, arch, header_size):
+    self.arch = arch
+    self.header_size = header_size
+
+
+class CodeLogReader(object):
+  """V8 code event log reader."""
+
+  _CODE_INFO_RE = re.compile(
+    r"code-info,([^,]+),(\d+)")
+
+  _CODE_CREATE_RE = re.compile(
+    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]+)")
+
+  _CODE_DELETE_RE = re.compile(
+    r"code-delete,(0x[a-f0-9]+)")
+
+  _SNAPSHOT_POS_RE = re.compile(
+    r"snapshot-pos,(0x[a-f0-9]+),(\d+)")
+
+  _CODE_MOVING_GC = "code-moving-gc"
+
+  def __init__(self, log_name, code_map, is_snapshot, snapshot_pos_to_name):
+    self.log = open(log_name, "r")
+    self.code_map = code_map
+    self.is_snapshot = is_snapshot
+    self.snapshot_pos_to_name = snapshot_pos_to_name
+    self.address_to_snapshot_name = {}
+
+  def ReadCodeInfo(self):
+    line = self.log.readline() or ""
+    match = CodeLogReader._CODE_INFO_RE.match(line)
+    assert match, "No code info in log"
+    return CodeInfo(arch=match.group(1), header_size=int(match.group(2)))
+
+  def ReadUpToGC(self, code_info):
+    made_progress = False
+    code_header_size = code_info.header_size
+    while True:
+      line = self.log.readline()
+      if not line:
+        return made_progress
+      made_progress = True
+
+      if line.startswith(CodeLogReader._CODE_MOVING_GC):
+        self.address_to_snapshot_name.clear()
+        return made_progress
+
+      match = CodeLogReader._CODE_CREATE_RE.match(line)
+      if match:
+        start_address = int(match.group(2), 16) + code_header_size
+        end_address = start_address + int(match.group(3)) - code_header_size
+        if start_address in self.address_to_snapshot_name:
+          name = self.address_to_snapshot_name[start_address]
+          origin = JS_SNAPSHOT_ORIGIN
+        else:
+          name = "%s:%s" % (match.group(1), match.group(4))
+          origin = JS_ORIGIN
+        if self.is_snapshot:
+          origin_offset = 0
+        else:
+          origin_offset = int(match.group(5))
+        code = Code(name, start_address, end_address, origin, origin_offset)
+        conficting_code = self.code_map.Find(start_address)
+        if conficting_code:
+          CodeLogReader._HandleCodeConflict(conficting_code, code)
+          # TODO(vitalyr): this warning is too noisy because of our
+          # attempts to reconstruct code log from the snapshot.
+          # print >>sys.stderr, \
+          #     "Warning: Skipping duplicate code log entry %s" % code
+          continue
+        self.code_map.Add(code)
+        continue
+
+      match = CodeLogReader._CODE_MOVE_RE.match(line)
+      if match:
+        old_start_address = int(match.group(1), 16) + code_header_size
+        new_start_address = int(match.group(2), 16) + code_header_size
+        if old_start_address == new_start_address:
+          # Skip useless code move entries.
+          continue
+        code = self.code_map.Find(old_start_address)
+        if not code:
+          print >>sys.stderr, "Warning: Not found %x" % old_start_address
+          continue
+        assert code.start_address == old_start_address, \
+            "Inexact move address %x for %s" % (old_start_address, code)
+        self.code_map.Remove(code)
+        size = code.end_address - code.start_address
+        code.start_address = new_start_address
+        code.end_address = new_start_address + size
+        self.code_map.Add(code)
+        continue
+
+      match = CodeLogReader._CODE_DELETE_RE.match(line)
+      if match:
+        old_start_address = int(match.group(1), 16) + code_header_size
+        code = self.code_map.Find(old_start_address)
+        if not code:
+          print >>sys.stderr, "Warning: Not found %x" % old_start_address
+          continue
+        assert code.start_address == old_start_address, \
+            "Inexact delete address %x for %s" % (old_start_address, code)
+        self.code_map.Remove(code)
+        continue
+
+      match = CodeLogReader._SNAPSHOT_POS_RE.match(line)
+      if match:
+        start_address = int(match.group(1), 16) + code_header_size
+        snapshot_pos = int(match.group(2))
+        if self.is_snapshot:
+          code = self.code_map.Find(start_address)
+          if code:
+            assert code.start_address == start_address, \
+                "Inexact snapshot address %x for %s" % (start_address, code)
+            self.snapshot_pos_to_name[snapshot_pos] = code.name
+        else:
+          if snapshot_pos in self.snapshot_pos_to_name:
+            self.address_to_snapshot_name[start_address] = \
+                self.snapshot_pos_to_name[snapshot_pos]
+
+  def Dispose(self):
+    self.log.close()
+
+  @staticmethod
+  def _HandleCodeConflict(old_code, new_code):
+    assert (old_code.start_address == new_code.start_address and
+            old_code.end_address == new_code.end_address), \
+        "Conficting code log entries %s and %s" % (old_code, new_code)
+    CodeLogReader._UpdateNames(old_code, new_code)
+
+  @staticmethod
+  def _UpdateNames(old_code, new_code):
+    if old_code.name == new_code.name:
+      return
+    # Kludge: there are code objects with custom names that don't
+    # match their flags.
+    misnamed_code = set(["Builtin:CpuFeatures::Probe"])
+    if old_code.name in misnamed_code:
+      return
+    # Code object may be shared by a few functions. Collect the full
+    # set of names.
+    old_code.AddName(new_code.name)
+
+
+class Descriptor(object):
+  """Descriptor of a structure in the binary trace log."""
+
+  CTYPE_MAP = {
+    "u16": ctypes.c_uint16,
+    "u32": ctypes.c_uint32,
+    "u64": ctypes.c_uint64
+  }
+
+  def __init__(self, fields):
+    class TraceItem(ctypes.Structure):
+      _fields_ = Descriptor.CtypesFields(fields)
+
+      def __str__(self):
+        return ", ".join("%s: %s" % (field, self.__getattribute__(field))
+                         for field, _ in TraceItem._fields_)
+
+    self.ctype = TraceItem
+
+  def Read(self, trace, offset):
+    return self.ctype.from_buffer(trace, offset)
+
+  @staticmethod
+  def CtypesFields(fields):
+    return [(field, Descriptor.CTYPE_MAP[format]) for (field, format) in fields]
+
+
+# Please see http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=tools/perf
+# for the gory details.
+
+
+TRACE_HEADER_DESC = Descriptor([
+  ("magic", "u64"),
+  ("size", "u64"),
+  ("attr_size", "u64"),
+  ("attrs_offset", "u64"),
+  ("attrs_size", "u64"),
+  ("data_offset", "u64"),
+  ("data_size", "u64"),
+  ("event_types_offset", "u64"),
+  ("event_types_size", "u64")
+])
+
+
+PERF_EVENT_ATTR_DESC = Descriptor([
+  ("type", "u32"),
+  ("size", "u32"),
+  ("config", "u64"),
+  ("sample_period_or_freq", "u64"),
+  ("sample_type", "u64"),
+  ("read_format", "u64"),
+  ("flags", "u64"),
+  ("wakeup_events_or_watermark", "u32"),
+  ("bt_type", "u32"),
+  ("bp_addr", "u64"),
+  ("bp_len", "u64"),
+])
+
+
+PERF_EVENT_HEADER_DESC = Descriptor([
+  ("type", "u32"),
+  ("misc", "u16"),
+  ("size", "u16")
+])
+
+
+PERF_MMAP_EVENT_BODY_DESC = Descriptor([
+  ("pid", "u32"),
+  ("tid", "u32"),
+  ("addr", "u64"),
+  ("len", "u64"),
+  ("pgoff", "u64")
+])
+
+
+# perf_event_attr.sample_type bits control the set of
+# perf_sample_event fields.
+PERF_SAMPLE_IP = 1 << 0
+PERF_SAMPLE_TID = 1 << 1
+PERF_SAMPLE_TIME = 1 << 2
+PERF_SAMPLE_ADDR = 1 << 3
+PERF_SAMPLE_READ = 1 << 4
+PERF_SAMPLE_CALLCHAIN = 1 << 5
+PERF_SAMPLE_ID = 1 << 6
+PERF_SAMPLE_CPU = 1 << 7
+PERF_SAMPLE_PERIOD = 1 << 8
+PERF_SAMPLE_STREAM_ID = 1 << 9
+PERF_SAMPLE_RAW = 1 << 10
+
+
+PERF_SAMPLE_EVENT_BODY_FIELDS = [
+  ("ip", "u64", PERF_SAMPLE_IP),
+  ("pid", "u32", PERF_SAMPLE_TID),
+  ("tid", "u32", PERF_SAMPLE_TID),
+  ("time", "u64", PERF_SAMPLE_TIME),
+  ("addr", "u64", PERF_SAMPLE_ADDR),
+  ("id", "u64", PERF_SAMPLE_ID),
+  ("stream_id", "u64", PERF_SAMPLE_STREAM_ID),
+  ("cpu", "u32", PERF_SAMPLE_CPU),
+  ("res", "u32", PERF_SAMPLE_CPU),
+  ("period", "u64", PERF_SAMPLE_PERIOD),
+  # Don't want to handle read format that comes after the period and
+  # before the callchain and has variable size.
+  ("nr", "u64", PERF_SAMPLE_CALLCHAIN)
+  # Raw data follows the callchain and is ignored.
+]
+
+
+PERF_SAMPLE_EVENT_IP_FORMAT = "u64"
+
+
+PERF_RECORD_MMAP = 1
+PERF_RECORD_SAMPLE = 9
+
+
+class TraceReader(object):
+  """Perf (linux-2.6/tools/perf) trace file reader."""
+
+  _TRACE_HEADER_MAGIC = 4993446653023372624
+
+  def __init__(self, trace_name):
+    self.trace_file = open(trace_name, "r")
+    self.trace = mmap.mmap(self.trace_file.fileno(), 0, mmap.MAP_PRIVATE)
+    self.trace_header = TRACE_HEADER_DESC.Read(self.trace, 0)
+    if self.trace_header.magic != TraceReader._TRACE_HEADER_MAGIC:
+      print >>sys.stderr, "Warning: unsupported trace header magic"
+    self.offset = self.trace_header.data_offset
+    self.limit = self.trace_header.data_offset + self.trace_header.data_size
+    assert self.limit <= self.trace.size(), \
+        "Trace data limit exceeds trace file size"
+    self.header_size = ctypes.sizeof(PERF_EVENT_HEADER_DESC.ctype)
+    assert self.trace_header.attrs_size != 0, \
+        "No perf event attributes found in the trace"
+    perf_event_attr = PERF_EVENT_ATTR_DESC.Read(self.trace,
+                                                self.trace_header.attrs_offset)
+    self.sample_event_body_desc = self._SampleEventBodyDesc(
+        perf_event_attr.sample_type)
+    self.callchain_supported = \
+        (perf_event_attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0
+    if self.callchain_supported:
+      self.ip_struct = Descriptor.CTYPE_MAP[PERF_SAMPLE_EVENT_IP_FORMAT]
+      self.ip_size = ctypes.sizeof(self.ip_struct)
+
+  def ReadEventHeader(self):
+    if self.offset >= self.limit:
+      return None, 0
+    offset = self.offset
+    header = PERF_EVENT_HEADER_DESC.Read(self.trace, self.offset)
+    self.offset += header.size
+    return header, offset
+
+  def ReadMmap(self, header, offset):
+    mmap_info = PERF_MMAP_EVENT_BODY_DESC.Read(self.trace,
+                                               offset + self.header_size)
+    # Read null-padded filename.
+    filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info):
+                          offset + header.size].rstrip(chr(0))
+    mmap_info.filename = filename
+    return mmap_info
+
+  def ReadSample(self, header, offset):
+    sample = self.sample_event_body_desc.Read(self.trace,
+                                              offset + self.header_size)
+    if not self.callchain_supported:
+      return sample
+    sample.ips = []
+    offset += self.header_size + ctypes.sizeof(sample)
+    for _ in xrange(sample.nr):
+      sample.ips.append(
+        self.ip_struct.from_buffer(self.trace, offset).value)
+      offset += self.ip_size
+    return sample
+
+  def Dispose(self):
+    self.trace.close()
+    self.trace_file.close()
+
+  def _SampleEventBodyDesc(self, sample_type):
+    assert (sample_type & PERF_SAMPLE_READ) == 0, \
+           "Can't hande read format in samples"
+    fields = [(field, format)
+              for (field, format, bit) in PERF_SAMPLE_EVENT_BODY_FIELDS
+              if (bit & sample_type) != 0]
+    return Descriptor(fields)
+
+
+OBJDUMP_SECTION_HEADER_RE = re.compile(
+  r"^\s*\d+\s(\.\S+)\s+[a-f0-9]")
+OBJDUMP_SYMBOL_LINE_RE = re.compile(
+  r"^([a-f0-9]+)\s(.{7})\s(\S+)\s+([a-f0-9]+)\s+(?:\.hidden\s+)?(.*)$")
+OBJDUMP_DYNAMIC_SYMBOLS_START_RE = re.compile(
+   r"^DYNAMIC SYMBOL TABLE")
+KERNEL_ALLSYMS_FILE = "/proc/kallsyms"
+PERF_KERNEL_ALLSYMS_RE = re.compile(
+  r".*kallsyms.*")
+KERNEL_ALLSYMS_LINE_RE = re.compile(
+  r"^([a-f0-9]+)\s(?:t|T)\s(\S+)$")
+
+
+class LibraryRepo(object):
+  def __init__(self):
+    self.infos = []
+    self.names = set()
+    self.ticks = {}
+
+  def Load(self, mmap_info, code_map, options):
+    # Skip kernel mmaps when requested using the fact that their tid
+    # is 0.
+    if mmap_info.tid == 0 and not options.kernel:
+      return True
+    if PERF_KERNEL_ALLSYMS_RE.match(mmap_info.filename):
+      return self._LoadKernelSymbols(code_map)
+    self.infos.append(mmap_info)
+    mmap_info.ticks = 0
+    mmap_info.unique_name = self._UniqueMmapName(mmap_info)
+    if not os.path.exists(mmap_info.filename):
+      return True
+    # Request section headers (-h), symbols (-t), and dynamic symbols
+    # (-T) from objdump.
+    # Unfortunately, section headers span two lines, so we have to
+    # keep the just seen section name (from the first line in each
+    # section header) in the after_section variable.
+    process = subprocess.Popen(
+      "%s -h -t -T -C %s" % (OBJDUMP_BIN, mmap_info.filename),
+      shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    pipe = process.stdout
+    after_section = None
+    code_sections = set()
+    reloc_sections = set()
+    dynamic = False
+    try:
+      for line in pipe:
+        if after_section:
+          if line.find("CODE") != -1:
+            code_sections.add(after_section)
+          if line.find("RELOC") != -1:
+            reloc_sections.add(after_section)
+          after_section = None
+          continue
+
+        match = OBJDUMP_SECTION_HEADER_RE.match(line)
+        if match:
+          after_section = match.group(1)
+          continue
+
+        if OBJDUMP_DYNAMIC_SYMBOLS_START_RE.match(line):
+          dynamic = True
+          continue
+
+        match = OBJDUMP_SYMBOL_LINE_RE.match(line)
+        if match:
+          start_address = int(match.group(1), 16)
+          origin_offset = start_address
+          flags = match.group(2)
+          section = match.group(3)
+          if section in code_sections:
+            if dynamic or section in reloc_sections:
+              start_address += mmap_info.addr
+            size = int(match.group(4), 16)
+            name = match.group(5)
+            origin = mmap_info.filename
+            code_map.Add(Code(name, start_address, start_address + size,
+                              origin, origin_offset))
+    finally:
+      pipe.close()
+    assert process.wait() == 0, "Failed to objdump %s" % mmap_info.filename
+
+  def Tick(self, pc):
+    for i, mmap_info in enumerate(self.infos):
+      if mmap_info.addr <= pc < (mmap_info.addr + mmap_info.len):
+        mmap_info.ticks += 1
+        self.infos[0], self.infos[i] = mmap_info, self.infos[0]
+        return True
+    return False
+
+  def _UniqueMmapName(self, mmap_info):
+    name = mmap_info.filename
+    index = 1
+    while name in self.names:
+      name = "%s-%d" % (mmap_info.filename, index)
+      index += 1
+    self.names.add(name)
+    return name
+
+  def _LoadKernelSymbols(self, code_map):
+    if not os.path.exists(KERNEL_ALLSYMS_FILE):
+      print >>sys.stderr, "Warning: %s not found" % KERNEL_ALLSYMS_FILE
+      return False
+    kallsyms = open(KERNEL_ALLSYMS_FILE, "r")
+    code = None
+    for line in kallsyms:
+      match = KERNEL_ALLSYMS_LINE_RE.match(line)
+      if match:
+        start_address = int(match.group(1), 16)
+        end_address = start_address
+        name = match.group(2)
+        if code:
+          code.end_address = start_address
+          code_map.Add(code, 16)
+        code = Code(name, start_address, end_address, "kernel", 0)
+    return True
+
+
+def PrintReport(code_map, library_repo, code_info, options):
+  print "Ticks per symbol:"
+  used_code = [code for code in code_map.UsedCode()]
+  used_code.sort(key=lambda x: x.self_ticks, reverse=True)
+  for i, code in enumerate(used_code):
+    print "%10d %s [%s]" % (code.self_ticks, code.FullName(), code.origin)
+    if options.disasm_all or i < options.disasm_top:
+      code.PrintAnnotated(code_info, options)
+  print
+  print "Ticks per library:"
+  mmap_infos = [m for m in library_repo.infos]
+  mmap_infos.sort(key=lambda m: m.ticks, reverse=True)
+  for mmap_info in mmap_infos:
+    print "%10d %s" % (mmap_info.ticks, mmap_info.unique_name)
+
+
+def PrintDot(code_map, options):
+  print "digraph G {"
+  for code in code_map.UsedCode():
+    if code.self_ticks < 10:
+      continue
+    print "n%d [shape=box,label=\"%s\"];" % (code.id, code.name)
+    if code.callee_ticks:
+      for callee, ticks in code.callee_ticks.iteritems():
+        print "n%d -> n%d [label=\"%d\"];" % (code.id, callee.id, ticks)
+  print "}"
+
+
+if __name__ == "__main__":
+  parser = optparse.OptionParser(USAGE)
+  parser.add_option("--snapshot-log",
+                    default="obj/release/snapshot.log",
+                    help="V8 snapshot log file name [default: %default]")
+  parser.add_option("--log",
+                    default="v8.log",
+                    help="V8 log file name [default: %default]")
+  parser.add_option("--snapshot",
+                    default=False,
+                    action="store_true",
+                    help="process V8 snapshot log [default: %default]")
+  parser.add_option("--trace",
+                    default="perf.data",
+                    help="perf trace file name [default: %default]")
+  parser.add_option("--kernel",
+                    default=False,
+                    action="store_true",
+                    help="process kernel entries [default: %default]")
+  parser.add_option("--disasm-top",
+                    default=0,
+                    type="int",
+                    help=("number of top symbols to disassemble and annotate "
+                          "[default: %default]"))
+  parser.add_option("--disasm-all",
+                    default=False,
+                    action="store_true",
+                    help=("disassemble and annotate all used symbols "
+                          "[default: %default]"))
+  parser.add_option("--dot",
+                    default=False,
+                    action="store_true",
+                    help="produce dot output (WIP) [default: %default]")
+  parser.add_option("--quiet", "-q",
+                    default=False,
+                    action="store_true",
+                    help="no auxiliary messages [default: %default]")
+  options, args = parser.parse_args()
+
+  if not options.quiet:
+    if options.snapshot:
+      print "V8 logs: %s, %s, %s.code" % (options.snapshot_log,
+                                          options.log,
+                                          options.log)
+    else:
+      print "V8 log: %s, %s.code (no snapshot)" % (options.log, options.log)
+    print "Perf trace file: %s" % options.trace
+
+  # Stats.
+  events = 0
+  ticks = 0
+  missed_ticks = 0
+  really_missed_ticks = 0
+  mmap_time = 0
+  sample_time = 0
+
+  # Initialize the log reader and get the code info.
+  code_map = CodeMap()
+  snapshot_name_map = {}
+  log_reader = CodeLogReader(log_name=options.log,
+                             code_map=code_map,
+                             is_snapshot=False,
+                             snapshot_pos_to_name=snapshot_name_map)
+  code_info = log_reader.ReadCodeInfo()
+  if not options.quiet:
+    print "Generated code architecture: %s" % code_info.arch
+    print
+
+  # Process the snapshot log to fill the snapshot name map.
+  if options.snapshot:
+    snapshot_log_reader = CodeLogReader(log_name=options.snapshot_log,
+                                        code_map=CodeMap(),
+                                        is_snapshot=True,
+                                        snapshot_pos_to_name=snapshot_name_map)
+    while snapshot_log_reader.ReadUpToGC(code_info):
+      pass
+
+  # Process the code and trace logs.
+  library_repo = LibraryRepo()
+  log_reader.ReadUpToGC(code_info)
+  trace_reader = TraceReader(options.trace)
+  while True:
+    header, offset = trace_reader.ReadEventHeader()
+    if not header:
+      break
+    events += 1
+    if header.type == PERF_RECORD_MMAP:
+      start = time.time()
+      mmap_info = trace_reader.ReadMmap(header, offset)
+      if mmap_info.filename == V8_GC_FAKE_MMAP:
+        log_reader.ReadUpToGC()
+      else:
+        library_repo.Load(mmap_info, code_map, options)
+      mmap_time += time.time() - start
+    elif header.type == PERF_RECORD_SAMPLE:
+      ticks += 1
+      start = time.time()
+      sample = trace_reader.ReadSample(header, offset)
+      code = code_map.Find(sample.ip)
+      if code:
+        code.Tick(sample.ip)
+      else:
+        missed_ticks += 1
+      if not library_repo.Tick(sample.ip) and not code:
+        really_missed_ticks += 1
+      if trace_reader.callchain_supported:
+        for ip in sample.ips:
+          caller_code = code_map.Find(ip)
+          if caller_code:
+            if code:
+              caller_code.CalleeTick(code)
+            code = caller_code
+      sample_time += time.time() - start
+
+  if options.dot:
+    PrintDot(code_map, options)
+  else:
+    PrintReport(code_map, library_repo, code_info, options)
+
+    if not options.quiet:
+      print
+      print "Stats:"
+      print "%10d total trace events" % events
+      print "%10d total ticks" % ticks
+      print "%10d ticks not in symbols" % missed_ticks
+      print "%10d unaccounted ticks" % really_missed_ticks
+      print "%10d total symbols" % len([c for c in code_map.AllCode()])
+      print "%10d used symbols" % len([c for c in code_map.UsedCode()])
+      print "%9.2fs library processing time" % mmap_time
+      print "%9.2fs tick processing time" % sample_time
+
+  log_reader.Dispose()
+  trace_reader.Dispose()
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index 3ebc458..08558cc 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -122,6 +122,7 @@
 		89A88E1F0E71A6B40043BA31 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
 		89A88E200E71A6B60043BA31 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
 		89A88E210E71A6B70043BA31 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
+		89A88E220E71A6BC0043BA31 /* string-search.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-search.cc */; };
 		89A88E220E71A6BC0043BA31 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
 		89A88E230E71A6BE0043BA31 /* stub-cache-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18B0E719B8F00D62E90 /* stub-cache-ia32.cc */; };
 		89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
@@ -183,6 +184,7 @@
 		89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
 		89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
 		89F23C750E78D5B2006B2466 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
+		89F23C760E78D5B2006B2466 /* string-search.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-search.cc */; };
 		89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
 		89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
 		89F23C790E78D5B2006B2466 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
@@ -218,8 +220,6 @@
 		9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F73E3AF114E61A100F84A5A /* profile-generator.cc */; };
 		9F92FAA90F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
 		9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
-		9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
-		9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
 		9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
 		9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
 		9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
@@ -502,6 +502,8 @@
 		897FF1850E719B8F00D62E90 /* spaces-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spaces-inl.h"; sourceTree = "<group>"; };
 		897FF1860E719B8F00D62E90 /* spaces.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spaces.cc; sourceTree = "<group>"; };
 		897FF1870E719B8F00D62E90 /* spaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spaces.h; sourceTree = "<group>"; };
+		897FF1880E719B8F00D62E90 /* string-search.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "string-search.cc"; sourceTree = "<group>"; };
+		897FF1880E719B8F00D62E90 /* string-search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "string-search.h"; sourceTree = "<group>"; };
 		897FF1880E719B8F00D62E90 /* string-stream.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "string-stream.cc"; sourceTree = "<group>"; };
 		897FF1890E719B8F00D62E90 /* string-stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "string-stream.h"; sourceTree = "<group>"; };
 		897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "stub-cache-arm.cc"; path = "arm/stub-cache-arm.cc"; sourceTree = "<group>"; };
@@ -586,7 +588,6 @@
 		9F92FAA80F8F28AD0089F02C /* func-name-inferrer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "func-name-inferrer.h"; sourceTree = "<group>"; };
 		9FA36F62116BA26500C4CD55 /* v8-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-profiler.h"; sourceTree = "<group>"; };
 		9FA37332116DD9F000C4CD55 /* vm-state-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state-inl.h"; sourceTree = "<group>"; };
-		9FA37333116DD9F000C4CD55 /* vm-state.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "vm-state.cc"; sourceTree = "<group>"; };
 		9FA37334116DD9F000C4CD55 /* vm-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state.h"; sourceTree = "<group>"; };
 		9FA38B9B1175B2D200C4CD55 /* cached-powers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cached-powers.h"; sourceTree = "<group>"; };
 		9FA38B9C1175B2D200C4CD55 /* data-flow.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "data-flow.cc"; sourceTree = "<group>"; };
@@ -964,6 +965,8 @@
 				897FF1870E719B8F00D62E90 /* spaces.h */,
 				9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */,
 				9FA38BAD1175B2D200C4CD55 /* splay-tree.h */,
+				897FF1880E719B8F00D62E90 /* string-search.cc */,
+				897FF1890E719B8F00D62E90 /* string-search.h */,
 				897FF1880E719B8F00D62E90 /* string-stream.cc */,
 				897FF1890E719B8F00D62E90 /* string-stream.h */,
 				897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */,
@@ -1007,7 +1010,6 @@
 				58950D5A0F55514900F3E8BA /* virtual-frame.cc */,
 				58950D5B0F55514900F3E8BA /* virtual-frame.h */,
 				9FA37332116DD9F000C4CD55 /* vm-state-inl.h */,
-				9FA37333116DD9F000C4CD55 /* vm-state.cc */,
 				9FA37334116DD9F000C4CD55 /* vm-state.h */,
 				897FF1A10E719B8F00D62E90 /* zone-inl.h */,
 				897FF1A20E719B8F00D62E90 /* zone.cc */,
@@ -1353,6 +1355,7 @@
 				89A88E1F0E71A6B40043BA31 /* snapshot-common.cc in Sources */,
 				89A88E200E71A6B60043BA31 /* snapshot-empty.cc in Sources */,
 				89A88E210E71A6B70043BA31 /* spaces.cc in Sources */,
+				89A88E220E71A6BC0043BA31 /* string-search.cc in Sources */,
 				89A88E220E71A6BC0043BA31 /* string-stream.cc in Sources */,
 				89A88E230E71A6BE0043BA31 /* stub-cache-ia32.cc in Sources */,
 				89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */,
@@ -1370,7 +1373,6 @@
 				9FA38BC71175B2E500C4CD55 /* virtual-frame-ia32.cc in Sources */,
 				58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
 				58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
-				9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */,
 				89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */,
 				C68081B112251239001EAFE4 /* code-stubs-ia32.cc in Sources */,
 			);
@@ -1478,6 +1480,7 @@
 				89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */,
 				89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */,
 				89F23C750E78D5B2006B2466 /* spaces.cc in Sources */,
+				89F23C760E78D5B2006B2466 /* string-search.cc in Sources */,
 				89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */,
 				89F23CA00E78D609006B2466 /* stub-cache-arm.cc in Sources */,
 				89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */,
@@ -1495,7 +1498,6 @@
 				58950D690F5551CE00F3E8BA /* virtual-frame-light.cc in Sources */,
 				58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
 				58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
-				9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */,
 				89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
 				C68081AD1225120B001EAFE4 /* code-stubs-arm.cc in Sources */,
 			);
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
index 4629b5d..62d4501 100644
--- a/tools/visual_studio/v8_base.vcproj
+++ b/tools/visual_studio/v8_base.vcproj
@@ -938,6 +938,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\string-search.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\string-search.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\string-stream.cc"
 				>
 			</File>
@@ -1074,10 +1082,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\vm-state.cc"
-				>
-			</File>
-			<File
 				RelativePath="..\..\src\vm-state-inl.h"
 				>
 			</File>
diff --git a/tools/visual_studio/v8_base_arm.vcproj b/tools/visual_studio/v8_base_arm.vcproj
index 4848c9b..4f9ff4c 100644
--- a/tools/visual_studio/v8_base_arm.vcproj
+++ b/tools/visual_studio/v8_base_arm.vcproj
@@ -912,6 +912,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\string-search.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\string-search.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\string-stream.cc"
 				>
 			</File>
@@ -1052,10 +1060,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\vm-state.cc"
-				>
-			</File>
-			<File
 				RelativePath="..\..\src\vm-state-inl.h"
 				>
 			</File>
diff --git a/tools/visual_studio/v8_base_x64.vcproj b/tools/visual_studio/v8_base_x64.vcproj
index e9af65d..c84bce2 100644
--- a/tools/visual_studio/v8_base_x64.vcproj
+++ b/tools/visual_studio/v8_base_x64.vcproj
@@ -898,6 +898,14 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\src\string-search.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\string-search.h"
+				>
+			</File>
+			<File
 				RelativePath="..\..\src\string-stream.cc"
 				>
 			</File>
@@ -1034,10 +1042,6 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\src\vm-state.cc"
-				>
-			</File>
-			<File
 				RelativePath="..\..\src\vm-state-inl.h"
 				>
 			</File>