Update V8 to r5675 as required by WebKit r70209

Change-Id: Ib10adb470d41ca8c109ead5fc893b880e18d489f
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%
rename from src/vm-state.cc
rename 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) {