Version 3.2.10

Fixed bug in external float arrays on ARM (issue 1323).

Minor performance improvements and bug fixes.


git-svn-id: http://v8.googlecode.com/svn/trunk@7596 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index f5f55ae..781f0ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-04-13: Version 3.2.10
+
+        Fixed bug in external float arrays on ARM (issue 1323).
+
+        Minor performance improvements and bug fixes.
+
+
 2011-04-11: Version 3.2.9
 
         Removed support for ABI prior to EABI on ARM.
diff --git a/src/api.cc b/src/api.cc
index c2b2df8..a2373cd 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -4625,7 +4625,7 @@
 int V8::GetCurrentThreadId() {
   i::Isolate* isolate = i::Isolate::Current();
   EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
-  return isolate->thread_id();
+  return isolate->thread_id().ToInteger();
 }
 
 
@@ -4636,10 +4636,11 @@
   // If the thread_id identifies the current thread just terminate
   // execution right away.  Otherwise, ask the thread manager to
   // terminate the thread with the given id if any.
-  if (thread_id == isolate->thread_id()) {
+  i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
+  if (isolate->thread_id().Equals(internal_tid)) {
     isolate->stack_guard()->TerminateExecution();
   } else {
-    isolate->thread_manager()->TerminateExecution(thread_id);
+    isolate->thread_manager()->TerminateExecution(internal_tid);
   }
 }
 
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 73dddfd..fd8e8b5 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -59,12 +59,12 @@
 #endif  // def CAN_USE_ARMV7_INSTRUCTIONS
   // If the compiler is allowed to use VFP then we can use VFP too in our code
   // generation even when generating snapshots.  This won't work for cross
-  // compilation.
+  // compilation. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
 #if defined(__VFP_FP__) && !defined(__SOFTFP__)
-  answer |= 1u << VFP3;
+  answer |= 1u << VFP3 | 1u << ARMv7;
 #endif  // defined(__VFP_FP__) && !defined(__SOFTFP__)
 #ifdef CAN_USE_VFP_INSTRUCTIONS
-  answer |= 1u << VFP3;
+  answer |= 1u << VFP3 | 1u << ARMv7;
 #endif  // def CAN_USE_VFP_INSTRUCTIONS
   return answer;
 }
@@ -77,9 +77,10 @@
   initialized_ = true;
 #endif
 #ifndef __arm__
-  // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is enabled.
+  // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is
+  // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
   if (FLAG_enable_vfp3) {
-    supported_ |= 1u << VFP3;
+    supported_ |= 1u << VFP3 | 1u << ARMv7;
   }
   // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled
   if (FLAG_enable_armv7) {
@@ -93,10 +94,11 @@
   }
 
   if (OS::ArmCpuHasFeature(VFP3)) {
-    // This implementation also sets the VFP flags if
-    // runtime detection of VFP returns true.
-    supported_ |= 1u << VFP3;
-    found_by_runtime_probing_ |= 1u << VFP3;
+    // This implementation also sets the VFP flags if runtime
+    // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
+    // 0406B, page A1-6.
+    supported_ |= 1u << VFP3 | 1u << ARMv7;
+    found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7;
   }
 
   if (OS::ArmCpuHasFeature(ARMv7)) {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 6af30c4..4912449 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2474,15 +2474,11 @@
   Register key = ToRegister(instr->key());
   ExternalArrayType array_type = instr->array_type();
   if (array_type == kExternalFloatArray) {
-    if (CpuFeatures::IsSupported(VFP3)) {
-      CpuFeatures::Scope scope(VFP3);
-      DwVfpRegister result(ToDoubleRegister(instr->result()));
-      __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
-      __ vldr(result, scratch0(), 0);
-    } else {
-      Register result(ToRegister(instr->result()));
-      __ ldr(result, MemOperand(external_pointer, key, LSL, 2));
-    }
+    CpuFeatures::Scope scope(VFP3);
+    DwVfpRegister result(ToDoubleRegister(instr->result()));
+    __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
+    __ vldr(result.low(), scratch0(), 0);
+    __ vcvt_f64_f32(result, result.low());
   } else {
     Register result(ToRegister(instr->result()));
     switch (array_type) {
@@ -3182,15 +3178,11 @@
   Register key = ToRegister(instr->key());
   ExternalArrayType array_type = instr->array_type();
   if (array_type == kExternalFloatArray) {
-    if (CpuFeatures::IsSupported(VFP3)) {
-      CpuFeatures::Scope scope(VFP3);
-      DwVfpRegister value(ToDoubleRegister(instr->value()));
-      __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
-      __ vstr(value, scratch0(), 0);
-    } else {
-      Register value(ToRegister(instr->value()));
-      __ str(value, MemOperand(external_pointer, key, LSL, 2));
-    }
+    CpuFeatures::Scope scope(VFP3);
+    DwVfpRegister value(ToDoubleRegister(instr->value()));
+    __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
+    __ vcvt_f32_f64(double_scratch0().low(), value);
+    __ vstr(double_scratch0().low(), scratch0(), 0);
   } else {
     Register value(ToRegister(instr->value()));
     switch (array_type) {
diff --git a/src/ast.cc b/src/ast.cc
index 6ea8c27..7ae0f34 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -349,6 +349,143 @@
 // ----------------------------------------------------------------------------
 // Inlining support
 
+bool Declaration::IsInlineable() const {
+  UNREACHABLE();
+  return false;
+}
+
+
+bool TargetCollector::IsInlineable() const {
+  UNREACHABLE();
+  return false;
+}
+
+
+bool Slot::IsInlineable() const {
+  UNREACHABLE();
+  return false;
+}
+
+
+bool ForInStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool WithEnterStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool WithExitStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool SwitchStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool TryStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool TryCatchStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool TryFinallyStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool CatchExtensionObject::IsInlineable() const {
+  return false;
+}
+
+
+bool DebuggerStatement::IsInlineable() const {
+  return false;
+}
+
+
+bool Throw::IsInlineable() const {
+  // TODO(1143): Make functions containing throw inlineable.
+  return false;
+}
+
+
+bool MaterializedLiteral::IsInlineable() const {
+  // TODO(1322): Allow materialized literals.
+  return false;
+}
+
+
+bool FunctionLiteral::IsInlineable() const {
+  // TODO(1322): Allow materialized literals.
+  return false;
+}
+
+
+bool ThisFunction::IsInlineable() const {
+  return false;
+}
+
+
+bool SharedFunctionInfoLiteral::IsInlineable() const {
+  return false;
+}
+
+
+bool ValidLeftHandSideSentinel::IsInlineable() const {
+  UNREACHABLE();
+  return false;
+}
+
+
+bool ForStatement::IsInlineable() const {
+  return (init() == NULL || init()->IsInlineable())
+      && (cond() == NULL || cond()->IsInlineable())
+      && (next() == NULL || next()->IsInlineable())
+      && body()->IsInlineable();
+}
+
+
+bool WhileStatement::IsInlineable() const {
+  return cond()->IsInlineable()
+      && body()->IsInlineable();
+}
+
+
+bool DoWhileStatement::IsInlineable() const {
+  return cond()->IsInlineable()
+      && body()->IsInlineable();
+}
+
+
+bool ContinueStatement::IsInlineable() const {
+  return true;
+}
+
+
+bool BreakStatement::IsInlineable() const {
+  return true;
+}
+
+
+bool EmptyStatement::IsInlineable() const {
+  return true;
+}
+
+
+bool Literal::IsInlineable() const {
+  return true;
+}
+
+
 bool Block::IsInlineable() const {
   const int count = statements_.length();
   for (int i = 0; i < count; ++i) {
@@ -364,8 +501,9 @@
 
 
 bool IfStatement::IsInlineable() const {
-  return condition()->IsInlineable() && then_statement()->IsInlineable() &&
-      else_statement()->IsInlineable();
+  return condition()->IsInlineable()
+      && then_statement()->IsInlineable()
+      && else_statement()->IsInlineable();
 }
 
 
diff --git a/src/ast.h b/src/ast.h
index 7f52c88..65a25a9 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -159,7 +159,7 @@
   virtual Slot* AsSlot() { return NULL; }
 
   // True if the node is simple enough for us to inline calls containing it.
-  virtual bool IsInlineable() const { return false; }
+  virtual bool IsInlineable() const = 0;
 
   static int Count() { return Isolate::Current()->ast_node_count(); }
   static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
@@ -291,6 +291,7 @@
  public:
   virtual bool IsValidLeftHandSide() { return true; }
   virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
+  virtual bool IsInlineable() const;
 };
 
 
@@ -375,6 +376,7 @@
   VariableProxy* proxy() const { return proxy_; }
   Variable::Mode mode() const { return mode_; }
   FunctionLiteral* fun() const { return fun_; }  // may be NULL
+  virtual bool IsInlineable() const;
 
  private:
   VariableProxy* proxy_;
@@ -433,6 +435,8 @@
   virtual int ContinueId() const { return continue_id_; }
   int BackEdgeId() const { return back_edge_id_; }
 
+  virtual bool IsInlineable() const;
+
  private:
   Expression* cond_;
   int condition_position_;
@@ -459,6 +463,7 @@
   void set_may_have_function_literal(bool value) {
     may_have_function_literal_ = value;
   }
+  virtual bool IsInlineable() const;
 
   // Bailout support.
   virtual int ContinueId() const { return EntryId(); }
@@ -506,6 +511,7 @@
   bool is_fast_smi_loop() { return loop_variable_ != NULL; }
   Variable* loop_variable() { return loop_variable_; }
   void set_loop_variable(Variable* var) { loop_variable_ = var; }
+  virtual bool IsInlineable() const;
 
  private:
   Statement* init_;
@@ -533,6 +539,7 @@
 
   Expression* each() const { return each_; }
   Expression* enumerable() const { return enumerable_; }
+  virtual bool IsInlineable() const;
 
   // Bailout support.
   int AssignmentId() const { return assignment_id_; }
@@ -573,6 +580,7 @@
   DECLARE_NODE_TYPE(ContinueStatement)
 
   IterationStatement* target() const { return target_; }
+  virtual bool IsInlineable() const;
 
  private:
   IterationStatement* target_;
@@ -587,6 +595,7 @@
   DECLARE_NODE_TYPE(BreakStatement)
 
   BreakableStatement* target() const { return target_; }
+  virtual bool IsInlineable() const;
 
  private:
   BreakableStatement* target_;
@@ -618,6 +627,7 @@
   Expression* expression() const { return expression_; }
 
   bool is_catch_block() const { return is_catch_block_; }
+  virtual bool IsInlineable() const;
 
  private:
   Expression* expression_;
@@ -629,6 +639,8 @@
  public:
   WithExitStatement() { }
 
+  virtual bool IsInlineable() const;
+
   DECLARE_NODE_TYPE(WithExitStatement)
 };
 
@@ -679,6 +691,7 @@
 
   Expression* tag() const { return tag_; }
   ZoneList<CaseClause*>* cases() const { return cases_; }
+  virtual bool IsInlineable() const;
 
  private:
   Expression* tag_;
@@ -744,6 +757,7 @@
   virtual TargetCollector* AsTargetCollector() { return this; }
 
   ZoneList<Label*>* targets() { return targets_; }
+  virtual bool IsInlineable() const;
 
  private:
   ZoneList<Label*>* targets_;
@@ -761,6 +775,7 @@
 
   Block* try_block() const { return try_block_; }
   ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
+  virtual bool IsInlineable() const;
 
  private:
   Block* try_block_;
@@ -782,6 +797,7 @@
 
   VariableProxy* catch_var() const { return catch_var_; }
   Block* catch_block() const { return catch_block_; }
+  virtual bool IsInlineable() const;
 
  private:
   VariableProxy* catch_var_;
@@ -798,6 +814,7 @@
   DECLARE_NODE_TYPE(TryFinallyStatement)
 
   Block* finally_block() const { return finally_block_; }
+  virtual bool IsInlineable() const;
 
  private:
   Block* finally_block_;
@@ -807,6 +824,7 @@
 class DebuggerStatement: public Statement {
  public:
   DECLARE_NODE_TYPE(DebuggerStatement)
+  virtual bool IsInlineable() const;
 };
 
 
@@ -814,7 +832,7 @@
  public:
   DECLARE_NODE_TYPE(EmptyStatement)
 
-  virtual bool IsInlineable() const { return true; }
+  virtual bool IsInlineable() const;
 };
 
 
@@ -825,7 +843,6 @@
   DECLARE_NODE_TYPE(Literal)
 
   virtual bool IsTrivial() { return true; }
-  virtual bool IsInlineable() const { return true; }
   virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
 
   // Check if this literal is identical to the other literal.
@@ -864,6 +881,7 @@
   }
 
   Handle<Object> handle() const { return handle_; }
+  virtual bool IsInlineable() const;
 
  private:
   Handle<Object> handle_;
@@ -885,6 +903,7 @@
   bool is_simple() const { return is_simple_; }
 
   int depth() const { return depth_; }
+  virtual bool IsInlineable() const;
 
  private:
   int literal_index_;
@@ -1034,6 +1053,7 @@
 
   Literal* key() const { return key_; }
   VariableProxy* value() const { return value_; }
+  virtual bool IsInlineable() const;
 
  private:
   Literal* key_;
@@ -1160,6 +1180,7 @@
   Type type() const { return type_; }
   int index() const { return index_; }
   bool is_arguments() const { return var_->is_arguments(); }
+  virtual bool IsInlineable() const;
 
  private:
   Variable* var_;
@@ -1643,6 +1664,7 @@
 
   Expression* exception() const { return exception_; }
   virtual int position() const { return pos_; }
+  virtual bool IsInlineable() const;
 
  private:
   Expression* exception_;
@@ -1715,6 +1737,7 @@
 
   bool pretenure() { return pretenure_; }
   void set_pretenure(bool value) { pretenure_ = value; }
+  virtual bool IsInlineable() const;
 
  private:
   Handle<String> name_;
@@ -1745,6 +1768,7 @@
   Handle<SharedFunctionInfo> shared_function_info() const {
     return shared_function_info_;
   }
+  virtual bool IsInlineable() const;
 
  private:
   Handle<SharedFunctionInfo> shared_function_info_;
@@ -1754,6 +1778,7 @@
 class ThisFunction: public Expression {
  public:
   DECLARE_NODE_TYPE(ThisFunction)
+  virtual bool IsInlineable() const;
 };
 
 
diff --git a/src/conversions.cc b/src/conversions.cc
index c3d7bdf..1458584 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -109,11 +109,11 @@
 
 // Returns true if a nonspace found and false if the end has reached.
 template <class Iterator, class EndMark>
-static inline bool AdvanceToNonspace(ScannerConstants* scanner_constants,
+static inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
                                      Iterator* current,
                                      EndMark end) {
   while (*current != end) {
-    if (!scanner_constants->IsWhiteSpace(**current)) return true;
+    if (!unicode_cache->IsWhiteSpace(**current)) return true;
     ++*current;
   }
   return false;
@@ -134,7 +134,7 @@
 
 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
 template <int radix_log_2, class Iterator, class EndMark>
-static double InternalStringToIntDouble(ScannerConstants* scanner_constants,
+static double InternalStringToIntDouble(UnicodeCache* unicode_cache,
                                         Iterator current,
                                         EndMark end,
                                         bool negative,
@@ -161,7 +161,7 @@
       digit = static_cast<char>(*current) - 'A' + 10;
     } else {
       if (allow_trailing_junk ||
-          !AdvanceToNonspace(scanner_constants, &current, end)) {
+          !AdvanceToNonspace(unicode_cache, &current, end)) {
         break;
       } else {
         return JUNK_STRING_VALUE;
@@ -193,7 +193,7 @@
       }
 
       if (!allow_trailing_junk &&
-          AdvanceToNonspace(scanner_constants, &current, end)) {
+          AdvanceToNonspace(unicode_cache, &current, end)) {
         return JUNK_STRING_VALUE;
       }
 
@@ -237,14 +237,14 @@
 
 
 template <class Iterator, class EndMark>
-static double InternalStringToInt(ScannerConstants* scanner_constants,
+static double InternalStringToInt(UnicodeCache* unicode_cache,
                                   Iterator current,
                                   EndMark end,
                                   int radix) {
   const bool allow_trailing_junk = true;
   const double empty_string_val = JUNK_STRING_VALUE;
 
-  if (!AdvanceToNonspace(scanner_constants, &current, end)) {
+  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
     return empty_string_val;
   }
 
@@ -254,12 +254,12 @@
   if (*current == '+') {
     // Ignore leading sign; skip following spaces.
     ++current;
-    if (!AdvanceToNonspace(scanner_constants, &current, end)) {
+    if (!AdvanceToNonspace(unicode_cache, &current, end)) {
       return JUNK_STRING_VALUE;
     }
   } else if (*current == '-') {
     ++current;
-    if (!AdvanceToNonspace(scanner_constants, &current, end)) {
+    if (!AdvanceToNonspace(unicode_cache, &current, end)) {
       return JUNK_STRING_VALUE;
     }
     negative = true;
@@ -312,21 +312,21 @@
     switch (radix) {
       case 2:
         return InternalStringToIntDouble<1>(
-            scanner_constants, current, end, negative, allow_trailing_junk);
+            unicode_cache, current, end, negative, allow_trailing_junk);
       case 4:
         return InternalStringToIntDouble<2>(
-            scanner_constants, current, end, negative, allow_trailing_junk);
+            unicode_cache, current, end, negative, allow_trailing_junk);
       case 8:
         return InternalStringToIntDouble<3>(
-            scanner_constants, current, end, negative, allow_trailing_junk);
+            unicode_cache, current, end, negative, allow_trailing_junk);
 
       case 16:
         return InternalStringToIntDouble<4>(
-            scanner_constants, current, end, negative, allow_trailing_junk);
+            unicode_cache, current, end, negative, allow_trailing_junk);
 
       case 32:
         return InternalStringToIntDouble<5>(
-            scanner_constants, current, end, negative, allow_trailing_junk);
+            unicode_cache, current, end, negative, allow_trailing_junk);
       default:
         UNREACHABLE();
     }
@@ -352,7 +352,7 @@
     }
 
     if (!allow_trailing_junk &&
-        AdvanceToNonspace(scanner_constants, &current, end)) {
+        AdvanceToNonspace(unicode_cache, &current, end)) {
       return JUNK_STRING_VALUE;
     }
 
@@ -418,7 +418,7 @@
   } while (!done);
 
   if (!allow_trailing_junk &&
-      AdvanceToNonspace(scanner_constants, &current, end)) {
+      AdvanceToNonspace(unicode_cache, &current, end)) {
     return JUNK_STRING_VALUE;
   }
 
@@ -432,7 +432,7 @@
 // 2. *current - gets the current character in the sequence.
 // 3. ++current (advances the position).
 template <class Iterator, class EndMark>
-static double InternalStringToDouble(ScannerConstants* scanner_constants,
+static double InternalStringToDouble(UnicodeCache* unicode_cache,
                                      Iterator current,
                                      EndMark end,
                                      int flags,
@@ -445,7 +445,7 @@
   // 'parsing_done'.
   // 4. 'current' is not dereferenced after the 'parsing_done' label.
   // 5. Code before 'parsing_done' may rely on 'current != end'.
-  if (!AdvanceToNonspace(scanner_constants, &current, end)) {
+  if (!AdvanceToNonspace(unicode_cache, &current, end)) {
     return empty_string_val;
   }
 
@@ -483,7 +483,7 @@
     }
 
     if (!allow_trailing_junk &&
-        AdvanceToNonspace(scanner_constants, &current, end)) {
+        AdvanceToNonspace(unicode_cache, &current, end)) {
       return JUNK_STRING_VALUE;
     }
 
@@ -505,7 +505,7 @@
         return JUNK_STRING_VALUE;  // "0x".
       }
 
-      return InternalStringToIntDouble<4>(scanner_constants,
+      return InternalStringToIntDouble<4>(unicode_cache,
                                           current,
                                           end,
                                           negative,
@@ -643,7 +643,7 @@
   }
 
   if (!allow_trailing_junk &&
-      AdvanceToNonspace(scanner_constants, &current, end)) {
+      AdvanceToNonspace(unicode_cache, &current, end)) {
     return JUNK_STRING_VALUE;
   }
 
@@ -651,7 +651,7 @@
   exponent += insignificant_digits;
 
   if (octal) {
-    return InternalStringToIntDouble<3>(scanner_constants,
+    return InternalStringToIntDouble<3>(unicode_cache,
                                         buffer,
                                         buffer + buffer_pos,
                                         negative,
@@ -671,23 +671,22 @@
 }
 
 
-double StringToDouble(String* str, int flags, double empty_string_val) {
-  ScannerConstants* scanner_constants =
-      Isolate::Current()->scanner_constants();
+double StringToDouble(UnicodeCache* unicode_cache,
+                      String* str, int flags, double empty_string_val) {
   StringShape shape(str);
   if (shape.IsSequentialAscii()) {
     const char* begin = SeqAsciiString::cast(str)->GetChars();
     const char* end = begin + str->length();
-    return InternalStringToDouble(scanner_constants, begin, end, flags,
+    return InternalStringToDouble(unicode_cache, begin, end, flags,
                                   empty_string_val);
   } else if (shape.IsSequentialTwoByte()) {
     const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
     const uc16* end = begin + str->length();
-    return InternalStringToDouble(scanner_constants, begin, end, flags,
+    return InternalStringToDouble(unicode_cache, begin, end, flags,
                                   empty_string_val);
   } else {
     StringInputBuffer buffer(str);
-    return InternalStringToDouble(scanner_constants,
+    return InternalStringToDouble(unicode_cache,
                                   StringInputBufferIterator(&buffer),
                                   StringInputBufferIterator::EndMarker(),
                                   flags,
@@ -696,21 +695,21 @@
 }
 
 
-double StringToInt(String* str, int radix) {
-  ScannerConstants* scanner_constants =
-      Isolate::Current()->scanner_constants();
+double StringToInt(UnicodeCache* unicode_cache,
+                   String* str,
+                   int radix) {
   StringShape shape(str);
   if (shape.IsSequentialAscii()) {
     const char* begin = SeqAsciiString::cast(str)->GetChars();
     const char* end = begin + str->length();
-    return InternalStringToInt(scanner_constants, begin, end, radix);
+    return InternalStringToInt(unicode_cache, begin, end, radix);
   } else if (shape.IsSequentialTwoByte()) {
     const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
     const uc16* end = begin + str->length();
-    return InternalStringToInt(scanner_constants, begin, end, radix);
+    return InternalStringToInt(unicode_cache, begin, end, radix);
   } else {
     StringInputBuffer buffer(str);
-    return InternalStringToInt(scanner_constants,
+    return InternalStringToInt(unicode_cache,
                                StringInputBufferIterator(&buffer),
                                StringInputBufferIterator::EndMarker(),
                                radix);
@@ -718,22 +717,20 @@
 }
 
 
-double StringToDouble(const char* str, int flags, double empty_string_val) {
-  ScannerConstants* scanner_constants =
-      Isolate::Current()->scanner_constants();
+double StringToDouble(UnicodeCache* unicode_cache,
+                      const char* str, int flags, double empty_string_val) {
   const char* end = str + StrLength(str);
-  return InternalStringToDouble(scanner_constants, str, end, flags,
+  return InternalStringToDouble(unicode_cache, str, end, flags,
                                 empty_string_val);
 }
 
 
-double StringToDouble(Vector<const char> str,
+double StringToDouble(UnicodeCache* unicode_cache,
+                      Vector<const char> str,
                       int flags,
                       double empty_string_val) {
-  ScannerConstants* scanner_constants =
-      Isolate::Current()->scanner_constants();
   const char* end = str.start() + str.length();
-  return InternalStringToDouble(scanner_constants, str.start(), end, flags,
+  return InternalStringToDouble(unicode_cache, str.start(), end, flags,
                                 empty_string_val);
 }
 
diff --git a/src/conversions.h b/src/conversions.h
index 312e6ae..a14dc9a 100644
--- a/src/conversions.h
+++ b/src/conversions.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -28,6 +28,8 @@
 #ifndef V8_CONVERSIONS_H_
 #define V8_CONVERSIONS_H_
 
+#include "scanner-base.h"
+
 namespace v8 {
 namespace internal {
 
@@ -91,15 +93,22 @@
 
 
 // Converts a string into a double value according to ECMA-262 9.3.1
-double StringToDouble(String* str, int flags, double empty_string_val = 0);
-double StringToDouble(Vector<const char> str,
+double StringToDouble(UnicodeCache* unicode_cache,
+                      String* str,
+                      int flags,
+                      double empty_string_val = 0);
+double StringToDouble(UnicodeCache* unicode_cache,
+                      Vector<const char> str,
                       int flags,
                       double empty_string_val = 0);
 // This version expects a zero-terminated character array.
-double StringToDouble(const char* str, int flags, double empty_string_val = 0);
+double StringToDouble(UnicodeCache* unicode_cache,
+                      const char* str,
+                      int flags,
+                      double empty_string_val = 0);
 
 // Converts a string into an integer.
-double StringToInt(String* str, int radix);
+double StringToInt(UnicodeCache* unicode_cache, String* str, int radix);
 
 // Converts a double to a string value according to ECMA-262 9.8.1.
 // The buffer should be large enough for any floating point number.
diff --git a/src/dateparser-inl.h b/src/dateparser-inl.h
index ac28c62..7f8fac8 100644
--- a/src/dateparser-inl.h
+++ b/src/dateparser-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -34,9 +34,11 @@
 namespace internal {
 
 template <typename Char>
-bool DateParser::Parse(Vector<Char> str, FixedArray* out) {
+bool DateParser::Parse(Vector<Char> str,
+                       FixedArray* out,
+                       UnicodeCache* unicode_cache) {
   ASSERT(out->length() >= OUTPUT_SIZE);
-  InputReader<Char> in(str);
+  InputReader<Char> in(unicode_cache, str);
   TimeZoneComposer tz;
   TimeComposer time;
   DayComposer day;
diff --git a/src/dateparser.h b/src/dateparser.h
index 51109ee..9d29715 100644
--- a/src/dateparser.h
+++ b/src/dateparser.h
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -49,7 +49,7 @@
   // [7]: UTC offset in seconds, or null value if no timezone specified
   // If parsing fails, return false (content of output array is not defined).
   template <typename Char>
-  static bool Parse(Vector<Char> str, FixedArray* output);
+  static bool Parse(Vector<Char> str, FixedArray* output, UnicodeCache* cache);
 
   enum {
     YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, UTC_OFFSET, OUTPUT_SIZE
@@ -67,11 +67,11 @@
   template <typename Char>
   class InputReader BASE_EMBEDDED {
    public:
-    explicit InputReader(Vector<Char> s)
+    InputReader(UnicodeCache* unicode_cache, Vector<Char> s)
         : index_(0),
           buffer_(s),
           has_read_number_(false),
-          scanner_constants_(Isolate::Current()->scanner_constants()) {
+          unicode_cache_(unicode_cache) {
       Next();
     }
 
@@ -122,7 +122,7 @@
     }
 
     bool SkipWhiteSpace() {
-      if (scanner_constants_->IsWhiteSpace(ch_)) {
+      if (unicode_cache_->IsWhiteSpace(ch_)) {
         Next();
         return true;
       }
@@ -158,7 +158,7 @@
     Vector<Char> buffer_;
     bool has_read_number_;
     uint32_t ch_;
-    ScannerConstants* scanner_constants_;
+    UnicodeCache* unicode_cache_;
   };
 
   enum KeywordType { INVALID, MONTH_NAME, TIME_ZONE_NAME, AM_PM };
diff --git a/src/extensions/experimental/experimental.gyp b/src/extensions/experimental/experimental.gyp
index 761f4c7..a8585fd 100644
--- a/src/extensions/experimental/experimental.gyp
+++ b/src/extensions/experimental/experimental.gyp
@@ -41,6 +41,7 @@
         'break-iterator.h',
         'i18n-extension.cc',
         'i18n-extension.h',
+	'<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
       ],
       'include_dirs': [
         '<(icu_src_dir)/public/common',
@@ -48,8 +49,39 @@
       ],
       'dependencies': [
         '<(icu_src_dir)/icu.gyp:*',
+	'js2c_i18n#host',
         '../../../tools/gyp/v8.gyp:v8',
       ],
     },
+    {
+      'target_name': 'js2c_i18n',
+      'type': 'none',
+      'toolsets': ['host'],
+      'variables': {
+        'library_files': [
+	  'i18n.js'
+	],
+      },
+      'actions': [
+        {
+	  'action_name': 'js2c_i18n',
+	  'inputs': [
+	    '../../../tools/js2c.py',
+	    '<@(library_files)',
+	  ],
+	  'outputs': [
+	    '<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
+	    '<(SHARED_INTERMEDIATE_DIR)/i18n-js-empty.cc'
+	  ],
+	  'action': [
+	    'python',
+	    '../../../tools/js2c.py',
+	    '<@(_outputs)',
+	    'I18N',
+	    '<@(library_files)'
+	  ],
+	},
+      ],
+    },
   ],  # targets
 }
diff --git a/src/extensions/experimental/i18n-extension.cc b/src/extensions/experimental/i18n-extension.cc
index f14fd9e..6e3ab15 100644
--- a/src/extensions/experimental/i18n-extension.cc
+++ b/src/extensions/experimental/i18n-extension.cc
@@ -31,6 +31,7 @@
 #include <string>
 
 #include "break-iterator.h"
+#include "natives.h"
 #include "unicode/locid.h"
 #include "unicode/uloc.h"
 
@@ -39,73 +40,19 @@
 
 I18NExtension* I18NExtension::extension_ = NULL;
 
-// TODO(cira): maybe move JS code to a .js file and generata cc files from it?
-// TODO(cira): Remove v8 prefix from v8Locale once we have stable API.
-const char* const I18NExtension::kSource =
-  "v8Locale = function(optLocale) {"
-  "  native function NativeJSLocale();"
-  "  var properties = NativeJSLocale(optLocale);"
-  "  this.locale = properties.locale;"
-  "  this.language = properties.language;"
-  "  this.script = properties.script;"
-  "  this.region = properties.region;"
-  "};"
-  "v8Locale.availableLocales = function() {"
-  "  native function NativeJSAvailableLocales();"
-  "  return NativeJSAvailableLocales();"
-  "};"
-  "v8Locale.prototype.maximizedLocale = function() {"
-  "  native function NativeJSMaximizedLocale();"
-  "  return new v8Locale(NativeJSMaximizedLocale(this.locale));"
-  "};"
-  "v8Locale.prototype.minimizedLocale = function() {"
-  "  native function NativeJSMinimizedLocale();"
-  "  return new v8Locale(NativeJSMinimizedLocale(this.locale));"
-  "};"
-  "v8Locale.prototype.displayLocale_ = function(displayLocale) {"
-  "  var result = this.locale;"
-  "  if (displayLocale !== undefined) {"
-  "    result = displayLocale.locale;"
-  "  }"
-  "  return result;"
-  "};"
-  "v8Locale.prototype.displayLanguage = function(optDisplayLocale) {"
-  "  var displayLocale = this.displayLocale_(optDisplayLocale);"
-  "  native function NativeJSDisplayLanguage();"
-  "  return NativeJSDisplayLanguage(this.locale, displayLocale);"
-  "};"
-  "v8Locale.prototype.displayScript = function(optDisplayLocale) {"
-  "  var displayLocale = this.displayLocale_(optDisplayLocale);"
-  "  native function NativeJSDisplayScript();"
-  "  return NativeJSDisplayScript(this.locale, displayLocale);"
-  "};"
-  "v8Locale.prototype.displayRegion = function(optDisplayLocale) {"
-  "  var displayLocale = this.displayLocale_(optDisplayLocale);"
-  "  native function NativeJSDisplayRegion();"
-  "  return NativeJSDisplayRegion(this.locale, displayLocale);"
-  "};"
-  "v8Locale.prototype.displayName = function(optDisplayLocale) {"
-  "  var displayLocale = this.displayLocale_(optDisplayLocale);"
-  "  native function NativeJSDisplayName();"
-  "  return NativeJSDisplayName(this.locale, displayLocale);"
-  "};"
-  "v8Locale.v8BreakIterator = function(locale, type) {"
-  "  native function NativeJSBreakIterator();"
-  "  var iterator = NativeJSBreakIterator(locale, type);"
-  "  iterator.type = type;"
-  "  return iterator;"
-  "};"
-  "v8Locale.v8BreakIterator.BreakType = {"
-  "  'unknown': -1,"
-  "  'none': 0,"
-  "  'number': 100,"
-  "  'word': 200,"
-  "  'kana': 300,"
-  "  'ideo': 400"
-  "};"
-  "v8Locale.prototype.v8CreateBreakIterator = function(type) {"
-  "  return new v8Locale.v8BreakIterator(this.locale, type);"
-  "};";
+// Returns a pointer to static string containing the actual
+// JavaScript code generated from i18n.js file.
+static const char* GetScriptSource() {
+  int index = NativesCollection<I18N>::GetIndex("i18n");
+  Vector<const char> script_data =
+      NativesCollection<I18N>::GetScriptSource(index);
+
+  return script_data.start();
+}
+
+I18NExtension::I18NExtension()
+    : v8::Extension("v8/i18n", GetScriptSource()) {
+}
 
 v8::Handle<v8::FunctionTemplate> I18NExtension::GetNativeFunction(
     v8::Handle<v8::String> name) {
diff --git a/src/extensions/experimental/i18n-extension.h b/src/extensions/experimental/i18n-extension.h
index 629332b..54c973f 100644
--- a/src/extensions/experimental/i18n-extension.h
+++ b/src/extensions/experimental/i18n-extension.h
@@ -36,7 +36,8 @@
 
 class I18NExtension : public v8::Extension {
  public:
-  I18NExtension() : v8::Extension("v8/i18n", kSource) {}
+  I18NExtension();
+
   virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
       v8::Handle<v8::String> name);
 
@@ -55,7 +56,6 @@
   static I18NExtension* get();
 
  private:
-  static const char* const kSource;
   static I18NExtension* extension_;
 };
 
diff --git a/src/extensions/experimental/i18n.js b/src/extensions/experimental/i18n.js
new file mode 100644
index 0000000..baf3859
--- /dev/null
+++ b/src/extensions/experimental/i18n.js
@@ -0,0 +1,103 @@
+// Copyright 2006-2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// TODO(cira): Remove v8 prefix from v8Locale once we have stable API.
+v8Locale = function(optLocale) {
+  native function NativeJSLocale();
+  var properties = NativeJSLocale(optLocale);
+  this.locale = properties.locale;
+  this.language = properties.language;
+  this.script = properties.script;
+  this.region = properties.region;
+};
+
+v8Locale.availableLocales = function() {
+  native function NativeJSAvailableLocales();
+  return NativeJSAvailableLocales();
+};
+
+v8Locale.prototype.maximizedLocale = function() {
+  native function NativeJSMaximizedLocale();
+  return new v8Locale(NativeJSMaximizedLocale(this.locale));
+};
+
+v8Locale.prototype.minimizedLocale = function() {
+  native function NativeJSMinimizedLocale();
+  return new v8Locale(NativeJSMinimizedLocale(this.locale));
+};
+
+v8Locale.prototype.displayLocale_ = function(displayLocale) {
+  var result = this.locale;
+  if (displayLocale !== undefined) {
+    result = displayLocale.locale;
+  }
+  return result;
+};
+
+v8Locale.prototype.displayLanguage = function(optDisplayLocale) {
+  var displayLocale = this.displayLocale_(optDisplayLocale);
+  native function NativeJSDisplayLanguage();
+  return NativeJSDisplayLanguage(this.locale, displayLocale);
+};
+
+v8Locale.prototype.displayScript = function(optDisplayLocale) {
+  var displayLocale = this.displayLocale_(optDisplayLocale);
+  native function NativeJSDisplayScript();
+  return NativeJSDisplayScript(this.locale, displayLocale);
+};
+
+v8Locale.prototype.displayRegion = function(optDisplayLocale) {
+  var displayLocale = this.displayLocale_(optDisplayLocale);
+  native function NativeJSDisplayRegion();
+  return NativeJSDisplayRegion(this.locale, displayLocale);
+};
+
+v8Locale.prototype.displayName = function(optDisplayLocale) {
+  var displayLocale = this.displayLocale_(optDisplayLocale);
+  native function NativeJSDisplayName();
+  return NativeJSDisplayName(this.locale, displayLocale);
+};
+
+v8Locale.v8BreakIterator = function(locale, type) {
+  native function NativeJSBreakIterator();
+  var iterator = NativeJSBreakIterator(locale, type);
+  iterator.type = type;
+  return iterator;
+};
+
+v8Locale.v8BreakIterator.BreakType = {
+  'unknown': -1,
+  'none': 0,
+  'number': 100,
+  'word': 200,
+  'kana': 300,
+  'ideo': 400
+};
+
+v8Locale.prototype.v8CreateBreakIterator = function(type) {
+  return new v8Locale.v8BreakIterator(this.locale, type);
+};
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index d6cb6e3..15f8def 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -162,7 +162,8 @@
 DEFINE_bool(enable_sahf, true,
             "enable use of SAHF instruction if available (X64 only)")
 DEFINE_bool(enable_vfp3, true,
-            "enable use of VFP3 instructions if available (ARM only)")
+            "enable use of VFP3 instructions if available - this implies "
+            "enabling ARMv7 instructions (ARM only)")
 DEFINE_bool(enable_armv7, true,
             "enable use of ARMv7 instructions if available (ARM only)")
 DEFINE_bool(enable_fpu, true,
diff --git a/src/heap.cc b/src/heap.cc
index c77364b..9a3cfe4 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3386,8 +3386,8 @@
   const uc32 kMaxSupportedChar = 0xFFFF;
   // Count the number of characters in the UTF-8 string and check if
   // it is an ASCII string.
-  Access<ScannerConstants::Utf8Decoder>
-      decoder(isolate_->scanner_constants()->utf8_decoder());
+  Access<UnicodeCache::Utf8Decoder>
+      decoder(isolate_->unicode_cache()->utf8_decoder());
   decoder->Reset(string.start(), string.length());
   int chars = 0;
   while (decoder->has_more()) {
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index c736553..a623775 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -274,7 +274,7 @@
     return kind_ == other.kind_;
   }
 
-  Kind kind() const { return kind_; }
+  Kind kind() const { return static_cast<Kind>(kind_); }
   bool IsNone() const { return kind_ == kNone; }
   bool IsTagged() const { return kind_ == kTagged; }
   bool IsInteger32() const { return kind_ == kInteger32; }
@@ -288,7 +288,10 @@
  private:
   explicit Representation(Kind k) : kind_(k) { }
 
-  Kind kind_;
+  // Make sure kind fits in int8.
+  STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
+
+  int8_t kind_;
 };
 
 
@@ -395,9 +398,12 @@
     kUninitialized = 0x1fff  // 0001 1111 1111 1111
   };
 
+  // Make sure type fits in int16.
+  STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
+
   explicit HType(Type t) : type_(t) { }
 
-  Type type_;
+  int16_t type_;
 };
 
 
@@ -611,8 +617,8 @@
   int id_;
 
   Representation representation_;
-  SmallPointerList<HValue> uses_;
   HType type_;
+  SmallPointerList<HValue> uses_;
   Range* range_;
   int flags_;
 
diff --git a/src/isolate.cc b/src/isolate.cc
index b8a7fb7..e42d78e 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -54,6 +54,21 @@
 namespace v8 {
 namespace internal {
 
+Atomic32 ThreadId::highest_thread_id_ = 0;
+
+int ThreadId::AllocateThreadId() {
+  int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
+  return new_id;
+}
+
+int ThreadId::GetCurrentThreadId() {
+  int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
+  if (thread_id == 0) {
+    thread_id = AllocateThreadId();
+    Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
+  }
+  return thread_id;
+}
 
 // Create a dummy thread that will wait forever on a semaphore. The only
 // purpose for this thread is to have some stack area to save essential data
@@ -245,7 +260,6 @@
 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
 Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex();
 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
-Isolate::ThreadId Isolate::highest_thread_id_ = 0;
 
 
 class IsolateInitializer {
@@ -265,20 +279,12 @@
 static IsolateInitializer* static_initializer = EnsureDefaultIsolateAllocated();
 
 
-Isolate::ThreadId Isolate::AllocateThreadId() {
-  ThreadId new_id;
-  {
-    ScopedLock lock(process_wide_mutex_);
-    new_id = ++highest_thread_id_;
-  }
-  return new_id;
-}
+
 
 
 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
     ThreadId thread_id) {
-  ASSERT(thread_id != 0);
-  ASSERT(Thread::GetThreadLocalInt(thread_id_key_) == thread_id);
+  ASSERT(!thread_id.Equals(ThreadId::Invalid()));
   PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id);
   {
     ScopedLock lock(process_wide_mutex_);
@@ -292,11 +298,7 @@
 
 Isolate::PerIsolateThreadData*
     Isolate::FindOrAllocatePerThreadDataForThisThread() {
-  ThreadId thread_id = Thread::GetThreadLocalInt(thread_id_key_);
-  if (thread_id == 0) {
-    thread_id = AllocateThreadId();
-    Thread::SetThreadLocalInt(thread_id_key_, thread_id);
-  }
+  ThreadId thread_id = ThreadId::Current();
   PerIsolateThreadData* per_thread = NULL;
   {
     ScopedLock lock(process_wide_mutex_);
@@ -361,7 +363,8 @@
 
 
 Isolate::PerIsolateThreadData*
-    Isolate::ThreadDataTable::Lookup(Isolate* isolate, ThreadId thread_id) {
+    Isolate::ThreadDataTable::Lookup(Isolate* isolate,
+                                     ThreadId thread_id) {
   for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
     if (data->Matches(isolate, thread_id)) return data;
   }
@@ -383,7 +386,8 @@
 }
 
 
-void Isolate::ThreadDataTable::Remove(Isolate* isolate, ThreadId thread_id) {
+void Isolate::ThreadDataTable::Remove(Isolate* isolate,
+                                      ThreadId thread_id) {
   PerIsolateThreadData* data = Lookup(isolate, thread_id);
   if (data != NULL) {
     Remove(data);
@@ -429,7 +433,7 @@
       context_slot_cache_(NULL),
       descriptor_lookup_cache_(NULL),
       handle_scope_implementer_(NULL),
-      scanner_constants_(NULL),
+      unicode_cache_(NULL),
       in_use_list_(0),
       free_list_(0),
       preallocated_storage_preallocated_(false),
@@ -564,8 +568,8 @@
   producer_heap_profile_ = NULL;
 #endif
 
-  delete scanner_constants_;
-  scanner_constants_ = NULL;
+  delete unicode_cache_;
+  unicode_cache_ = NULL;
 
   delete regexp_stack_;
   regexp_stack_ = NULL;
@@ -672,7 +676,7 @@
   keyed_lookup_cache_ = new KeyedLookupCache();
   context_slot_cache_ = new ContextSlotCache();
   descriptor_lookup_cache_ = new DescriptorLookupCache();
-  scanner_constants_ = new ScannerConstants();
+  unicode_cache_ = new UnicodeCache();
   pc_to_code_cache_ = new PcToCodeCache(this);
   write_input_buffer_ = new StringInputBuffer();
   global_handles_ = new GlobalHandles(this);
@@ -833,8 +837,8 @@
       ASSERT(Current() == this);
       ASSERT(entry_stack_ != NULL);
       ASSERT(entry_stack_->previous_thread_data == NULL ||
-             entry_stack_->previous_thread_data->thread_id() ==
-                 Thread::GetThreadLocalInt(thread_id_key_));
+             entry_stack_->previous_thread_data->thread_id().Equals(
+                 ThreadId::Current()));
       // Same thread re-enters the isolate, no need to re-init anything.
       entry_stack_->entry_count++;
       return;
@@ -872,8 +876,8 @@
 void Isolate::Exit() {
   ASSERT(entry_stack_ != NULL);
   ASSERT(entry_stack_->previous_thread_data == NULL ||
-         entry_stack_->previous_thread_data->thread_id() ==
-             Thread::GetThreadLocalInt(thread_id_key_));
+         entry_stack_->previous_thread_data->thread_id().Equals(
+             ThreadId::Current()));
 
   if (--entry_stack_->entry_count > 0) return;
 
diff --git a/src/isolate.h b/src/isolate.h
index dd0a1fe..01b721d 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -72,7 +72,7 @@
 class ProducerHeapProfile;
 class RegExpStack;
 class SaveContext;
-class ScannerConstants;
+class UnicodeCache;
 class StringInputBuffer;
 class StringTracker;
 class StubCache;
@@ -136,6 +136,53 @@
 #endif
 
 
+// Platform-independent, reliable thread identifier.
+class ThreadId {
+ public:
+  // Creates an invalid ThreadId.
+  ThreadId() : id_(kInvalidId) {}
+
+  // Returns ThreadId for current thread.
+  static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
+
+  // Returns invalid ThreadId (guaranteed not to be equal to any thread).
+  static ThreadId Invalid() { return ThreadId(kInvalidId); }
+
+  // Compares ThreadIds for equality.
+  INLINE(bool Equals(const ThreadId& other) const) {
+    return id_ == other.id_;
+  }
+
+  // Checks whether this ThreadId refers to any thread.
+  INLINE(bool IsValid() const) {
+    return id_ != kInvalidId;
+  }
+
+  // Converts ThreadId to an integer representation
+  // (required for public API: V8::V8::GetCurrentThreadId).
+  int ToInteger() const { return id_; }
+
+  // Converts ThreadId to an integer representation
+  // (required for public API: V8::V8::TerminateExecution).
+  static ThreadId FromInteger(int id) { return ThreadId(id); }
+
+ private:
+  static const int kInvalidId = -1;
+
+  explicit ThreadId(int id) : id_(id) {}
+
+  static int AllocateThreadId();
+
+  static int GetCurrentThreadId();
+
+  int id_;
+
+  static Atomic32 highest_thread_id_;
+
+  friend class Isolate;
+};
+
+
 class ThreadLocalTop BASE_EMBEDDED {
  public:
   // Initialize the thread data.
@@ -176,7 +223,7 @@
   // The context where the current execution method is created and for variable
   // lookups.
   Context* context_;
-  int thread_id_;
+  ThreadId thread_id_;
   MaybeObject* pending_exception_;
   bool has_pending_message_;
   Object* pending_message_obj_;
@@ -188,9 +235,6 @@
   // unify them later.
   MaybeObject* scheduled_exception_;
   bool external_caught_exception_;
-  // True if unhandled message is being currently reported by
-  // MessageHandler::ReportMessage.
-  bool in_exception_reporting_;
   SaveContext* save_context_;
   v8::TryCatch* catcher_;
 
@@ -332,8 +376,6 @@
  public:
   ~Isolate();
 
-  typedef int ThreadId;
-
   // A thread has a PerIsolateThreadData instance for each isolate that it has
   // entered. That instance is allocated when the isolate is initially entered
   // and reused on subsequent entries.
@@ -366,7 +408,7 @@
 #endif
 
     bool Matches(Isolate* isolate, ThreadId thread_id) const {
-      return isolate_ == isolate && thread_id_ == thread_id;
+      return isolate_ == isolate && thread_id_.Equals(thread_id);
     }
 
    private:
@@ -458,9 +500,6 @@
     return thread_id_key_;
   }
 
-  // Atomically allocates a new thread ID.
-  static ThreadId AllocateThreadId();
-
   // If a client attempts to create a Locker without specifying an isolate,
   // we assume that the client is using legacy behavior. Set up the current
   // thread to be inside the implicit isolate (or fail a check if we have
@@ -486,8 +525,8 @@
   }
 
   // Access to current thread id.
-  int thread_id() { return thread_local_top_.thread_id_; }
-  void set_thread_id(int id) { thread_local_top_.thread_id_ = id; }
+  ThreadId thread_id() { return thread_local_top_.thread_id_; }
+  void set_thread_id(ThreadId id) { thread_local_top_.thread_id_ = id; }
 
   // Interface to pending exception.
   MaybeObject* pending_exception() {
@@ -526,12 +565,6 @@
   bool* external_caught_exception_address() {
     return &thread_local_top_.external_caught_exception_;
   }
-  bool in_exception_reporting() {
-    return thread_local_top_.in_exception_reporting_;
-  }
-  void set_in_exception_reporting(bool value) {
-    thread_local_top_.in_exception_reporting_ = value;
-  }
   v8::TryCatch* catcher() {
     return thread_local_top_.catcher_;
   }
@@ -786,8 +819,8 @@
   }
   Zone* zone() { return &zone_; }
 
-  ScannerConstants* scanner_constants() {
-    return scanner_constants_;
+  UnicodeCache* unicode_cache() {
+    return unicode_cache_;
   }
 
   PcToCodeCache* pc_to_code_cache() { return pc_to_code_cache_; }
@@ -1005,7 +1038,6 @@
   static Thread::LocalStorageKey thread_id_key_;
   static Isolate* default_isolate_;
   static ThreadDataTable* thread_data_table_;
-  static ThreadId highest_thread_id_;
 
   bool PreInit();
 
@@ -1090,7 +1122,7 @@
   DescriptorLookupCache* descriptor_lookup_cache_;
   v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
   HandleScopeImplementer* handle_scope_implementer_;
-  ScannerConstants* scanner_constants_;
+  UnicodeCache* unicode_cache_;
   Zone zone_;
   PreallocatedStorage in_use_list_;
   PreallocatedStorage free_list_;
@@ -1165,6 +1197,7 @@
 
   friend class ExecutionAccess;
   friend class IsolateInitializer;
+  friend class ThreadId;
   friend class v8::Isolate;
   friend class v8::Locker;
 
diff --git a/src/messages.cc b/src/messages.cc
index 0cc8251..abc2537 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -104,15 +104,6 @@
 void MessageHandler::ReportMessage(Isolate* isolate,
                                    MessageLocation* loc,
                                    Handle<Object> message) {
-  // If we are in process of message reporting, just ignore all other requests
-  // to report a message as they are due to unhandled exceptions thrown in
-  // message callbacks.
-  if (isolate->in_exception_reporting()) {
-    PrintF("uncaught exception thrown while reporting\n");
-    return;
-  }
-  isolate->set_in_exception_reporting(true);
-
   // We are calling into embedder's code which can throw exceptions.
   // Thus we need to save current exception state, reset it to the clean one
   // and ignore scheduled exceptions callbacks can throw.
@@ -138,14 +129,16 @@
       v8::MessageCallback callback =
           FUNCTION_CAST<v8::MessageCallback>(callback_obj->proxy());
       Handle<Object> callback_data(listener.get(1));
-      callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+      {
+        // Do not allow exceptions to propagate.
+        v8::TryCatch tryCatch;
+        callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+      }
       if (isolate->has_scheduled_exception()) {
         isolate->clear_scheduled_exception();
       }
     }
   }
-
-  isolate->set_in_exception_reporting(false);
 }
 
 
diff --git a/src/natives.h b/src/natives.h
index 639a2d3..1df94b0 100644
--- a/src/natives.h
+++ b/src/natives.h
@@ -36,7 +36,7 @@
                                      int index);
 
 enum NativeType {
-  CORE, D8
+  CORE, D8, I18N
 };
 
 template <NativeType type>
diff --git a/src/objects-inl.h b/src/objects-inl.h
index ebdf0a0..823b2da 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -3309,6 +3309,11 @@
 }
 
 
+bool JSFunction::IsOptimizable() {
+  return code()->kind() == Code::FUNCTION && code()->optimizable();
+}
+
+
 bool JSFunction::IsMarkedForLazyRecompilation() {
   return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
 }
diff --git a/src/objects.cc b/src/objects.cc
index d211d62..6ce4c44 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -1279,6 +1279,22 @@
 }
 
 
+static bool IsIdentifier(UnicodeCache* cache,
+                         unibrow::CharacterStream* buffer) {
+  // Checks whether the buffer contains an identifier (no escape).
+  if (!buffer->has_more()) return false;
+  if (!cache->IsIdentifierStart(buffer->GetNext())) {
+    return false;
+  }
+  while (buffer->has_more()) {
+    if (!cache->IsIdentifierPart(buffer->GetNext())) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
 MaybeObject* JSObject::AddFastProperty(String* name,
                                        Object* value,
                                        PropertyAttributes attributes) {
@@ -1288,7 +1304,7 @@
   // hidden symbols) and is not a real identifier.
   Isolate* isolate = GetHeap()->isolate();
   StringInputBuffer buffer(name);
-  if (!isolate->scanner_constants()->IsIdentifier(&buffer)
+  if (!IsIdentifier(isolate->unicode_cache(), &buffer)
       && name != isolate->heap()->hidden_symbol()) {
     Object* obj;
     { MaybeObject* maybe_obj =
@@ -5423,8 +5439,8 @@
 bool String::IsEqualTo(Vector<const char> str) {
   Isolate* isolate = GetIsolate();
   int slen = length();
-  Access<ScannerConstants::Utf8Decoder>
-      decoder(isolate->scanner_constants()->utf8_decoder());
+  Access<UnicodeCache::Utf8Decoder>
+      decoder(isolate->unicode_cache()->utf8_decoder());
   decoder->Reset(str.start(), str.length());
   int i;
   for (i = 0; i < slen && decoder->has_more(); i++) {
@@ -7635,7 +7651,6 @@
   Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate);
   Handle<Object> this_handle(receiver, isolate);
   Handle<JSObject> holder_handle(this, isolate);
-
   if (!interceptor->getter()->IsUndefined()) {
     v8::IndexedPropertyGetter getter =
         v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
diff --git a/src/objects.h b/src/objects.h
index 449a210..03445e8 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4526,6 +4526,9 @@
   // Tells whether or not this function has been optimized.
   inline bool IsOptimized();
 
+  // Tells whether or not this function can be optimized.
+  inline bool IsOptimizable();
+
   // Mark this function for lazy recompilation. The function will be
   // recompiled the next time it is executed.
   void MarkForLazyRecompilation();
diff --git a/src/parser.cc b/src/parser.cc
index 4fad6e4..cf84bfa 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -576,7 +576,7 @@
     : isolate_(script->GetIsolate()),
       symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
       script_(script),
-      scanner_(isolate_->scanner_constants()),
+      scanner_(isolate_->unicode_cache()),
       top_scope_(NULL),
       with_nesting_level_(0),
       lexical_scope_(NULL),
@@ -2894,7 +2894,8 @@
     case Token::NUMBER: {
       Consume(Token::NUMBER);
       ASSERT(scanner().is_literal_ascii());
-      double value = StringToDouble(scanner().literal_ascii_string(),
+      double value = StringToDouble(isolate()->unicode_cache(),
+                                    scanner().literal_ascii_string(),
                                     ALLOW_HEX | ALLOW_OCTALS);
       result = NewNumberLiteral(value);
       break;
@@ -3392,7 +3393,8 @@
       case Token::NUMBER: {
         Consume(Token::NUMBER);
         ASSERT(scanner().is_literal_ascii());
-        double value = StringToDouble(scanner().literal_ascii_string(),
+        double value = StringToDouble(isolate()->unicode_cache(),
+                                      scanner().literal_ascii_string(),
                                       ALLOW_HEX | ALLOW_OCTALS);
         key = NewNumberLiteral(value);
         break;
@@ -5056,7 +5058,7 @@
                                   bool allow_lazy,
                                   ParserRecorder* recorder) {
   Isolate* isolate = Isolate::Current();
-  V8JavaScriptScanner scanner(isolate->scanner_constants());
+  V8JavaScriptScanner scanner(isolate->unicode_cache());
   scanner.Initialize(source);
   intptr_t stack_limit = isolate->stack_guard()->real_climit();
   if (!preparser::PreParser::PreParseProgram(&scanner,
diff --git a/src/parser.h b/src/parser.h
index e8cd102..a63651a 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -783,7 +783,7 @@
  private:
   JsonParser()
       : isolate_(Isolate::Current()),
-        scanner_(isolate_->scanner_constants()) { }
+        scanner_(isolate_->unicode_cache()) { }
   ~JsonParser() { }
 
   Isolate* isolate() { return isolate_; }
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index d591b9d..6511328 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -362,50 +362,17 @@
 }
 
 
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
  public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
-    Initialize(kind);
-  }
-
-  void Initialize(ThreadHandle::Kind kind) {
-    switch (kind) {
-      case ThreadHandle::SELF: thread_ = pthread_self(); break;
-      case ThreadHandle::INVALID: thread_ = kNoThread; break;
-    }
-  }
-
+  PlatformData() : thread_(kNoThread) {}
   pthread_t thread_;  // Thread handle for pthread.
 };
 
 
-ThreadHandle::ThreadHandle(Kind kind) {
-  data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
-  data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
-  delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
-  return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
-  return data_->thread_ != kNoThread;
-}
 
 
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData),
       isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
@@ -413,7 +380,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData),
       isolate_(isolate),
       stack_size_(0) {
   set_name(name);
@@ -421,6 +388,7 @@
 
 
 Thread::~Thread() {
+  delete data_;
 }
 
 
@@ -429,8 +397,8 @@
   // This is also initialized by the first argument to pthread_create() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
-  thread->thread_handle_data()->thread_ = pthread_self();
-  ASSERT(thread->IsValid());
+  thread->data()->thread_ = pthread_self();
+  ASSERT(thread->data()->thread_ != kNoThread);
   Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
@@ -451,13 +419,13 @@
     pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
     attr_ptr = &attr;
   }
-  pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
-  ASSERT(IsValid());
+  pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+  ASSERT(data_->thread_ != kNoThread);
 }
 
 
 void Thread::Join() {
-  pthread_join(thread_handle_data()->thread_, NULL);
+  pthread_join(data_->thread_, NULL);
 }
 
 
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 2a73b6e..ca4e54f 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -391,18 +391,8 @@
 }
 
 
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
  public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
-    Initialize(kind);
-  }
-
-  void Initialize(ThreadHandle::Kind kind) {
-    switch (kind) {
-      case ThreadHandle::SELF: thread_ = pthread_self(); break;
-      case ThreadHandle::INVALID: thread_ = kNoThread; break;
-    }
-  }
   pthread_t thread_;  // Thread handle for pthread.
 };
 
@@ -433,7 +423,7 @@
 
 
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData),
       isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
@@ -441,7 +431,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData),
       isolate_(isolate),
       stack_size_(0) {
   set_name(name);
@@ -449,6 +439,7 @@
 
 
 Thread::~Thread() {
+  delete data_;
 }
 
 
@@ -457,7 +448,7 @@
   // This is also initialized by the first argument to pthread_create() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
-  thread->thread_handle_data()->thread_ = pthread_self();
+  thread_->data_->thread_ = pthread_self();
   ASSERT(thread->IsValid());
   Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 73a6ccb..e2ab9d8 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -92,9 +92,10 @@
 
 uint64_t OS::CpuFeaturesImpliedByPlatform() {
 #if (defined(__VFP_FP__) && !defined(__SOFTFP__))
-  // Here gcc is telling us that we are on an ARM and gcc is assuming that we
-  // have VFP3 instructions.  If gcc can assume it then so can we.
-  return 1u << VFP3;
+  // Here gcc is telling us that we are on an ARM and gcc is assuming
+  // that we have VFP3 instructions.  If gcc can assume it then so can
+  // we. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
+  return 1u << VFP3 | 1u << ARMv7;
 #elif CAN_USE_ARMV7_INSTRUCTIONS
   return 1u << ARMv7;
 #elif(defined(__mips_hard_float) && __mips_hard_float != 0)
@@ -588,50 +589,15 @@
 }
 
 
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
  public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
-    Initialize(kind);
-  }
-
-  void Initialize(ThreadHandle::Kind kind) {
-    switch (kind) {
-      case ThreadHandle::SELF: thread_ = pthread_self(); break;
-      case ThreadHandle::INVALID: thread_ = kNoThread; break;
-    }
-  }
+  PlatformData() : thread_(kNoThread) {}
 
   pthread_t thread_;  // Thread handle for pthread.
 };
 
-
-ThreadHandle::ThreadHandle(Kind kind) {
-  data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
-  data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
-  delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
-  return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
-  return data_->thread_ != kNoThread;
-}
-
-
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData()),
       isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
@@ -639,7 +605,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData()),
       isolate_(isolate),
       stack_size_(0) {
   set_name(name);
@@ -647,6 +613,7 @@
 
 
 Thread::~Thread() {
+  delete data_;
 }
 
 
@@ -658,8 +625,8 @@
   prctl(PR_SET_NAME,
         reinterpret_cast<unsigned long>(thread->name()),  // NOLINT
         0, 0, 0);
-  thread->thread_handle_data()->thread_ = pthread_self();
-  ASSERT(thread->IsValid());
+  thread->data()->thread_ = pthread_self();
+  ASSERT(thread->data()->thread_ != kNoThread);
   Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
@@ -680,13 +647,13 @@
     pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
     attr_ptr = &attr;
   }
-  pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
-  ASSERT(IsValid());
+  pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+  ASSERT(data_->thread_ != kNoThread);
 }
 
 
 void Thread::Join() {
-  pthread_join(thread_handle_data()->thread_, NULL);
+  pthread_join(data_->thread_, NULL);
 }
 
 
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index bfdf3b2..3e10b6a 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -392,50 +392,14 @@
 }
 
 
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
  public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
-    Initialize(kind);
-  }
-
-  void Initialize(ThreadHandle::Kind kind) {
-    switch (kind) {
-      case ThreadHandle::SELF: thread_ = pthread_self(); break;
-      case ThreadHandle::INVALID: thread_ = kNoThread; break;
-    }
-  }
+  PlatformData() : thread_(kNoThread) {}
   pthread_t thread_;  // Thread handle for pthread.
 };
 
-
-
-ThreadHandle::ThreadHandle(Kind kind) {
-  data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
-  data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
-  delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
-  return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
-  return data_->thread_ != kNoThread;
-}
-
-
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData),
       isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
@@ -443,7 +407,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData),
       isolate_(isolate),
       stack_size_(0) {
   set_name(name);
@@ -451,6 +415,7 @@
 
 
 Thread::~Thread() {
+  delete data_;
 }
 
 
@@ -476,9 +441,9 @@
   // This is also initialized by the first argument to pthread_create() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
-  thread->thread_handle_data()->thread_ = pthread_self();
+  thread->data()->thread_ = pthread_self();
   SetThreadName(thread->name());
-  ASSERT(thread->IsValid());
+  ASSERT(thread->data()->thread_ != kNoThread);
   Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
@@ -499,13 +464,13 @@
     pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
     attr_ptr = &attr;
   }
-  pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
-  ASSERT(IsValid());
+  pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+  ASSERT(data_->thread_ != kNoThread);
 }
 
 
 void Thread::Join() {
-  pthread_join(thread_handle_data()->thread_, NULL);
+  pthread_join(data_->thread_, NULL);
 }
 
 
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index 5409936..aacad14 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -299,9 +299,9 @@
 }
 
 
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
  public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
+  PlatformData() {
     UNIMPLEMENTED();
   }
 
@@ -309,39 +309,8 @@
 };
 
 
-ThreadHandle::ThreadHandle(Kind kind) {
-  UNIMPLEMENTED();
-  // Shared setup follows.
-  data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
-  UNIMPLEMENTED();
-}
-
-
-ThreadHandle::~ThreadHandle() {
-  UNIMPLEMENTED();
-  // Shared tear down follows.
-  delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
-bool ThreadHandle::IsValid() const {
-  UNIMPLEMENTED();
-  return false;
-}
-
-
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData()),
       isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
@@ -350,7 +319,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData()),
       isolate_(isolate),
       stack_size_(0) {
   set_name(name);
@@ -359,6 +328,7 @@
 
 
 Thread::~Thread() {
+  delete data_;
   UNIMPLEMENTED();
 }
 
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index fe1a62a..e90b3e8 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -359,49 +359,16 @@
 }
 
 
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
  public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
-    Initialize(kind);
-  }
+  PlatformData() : thread_(kNoThread) {}
 
-  void Initialize(ThreadHandle::Kind kind) {
-    switch (kind) {
-      case ThreadHandle::SELF: thread_ = pthread_self(); break;
-      case ThreadHandle::INVALID: thread_ = kNoThread; break;
-    }
-  }
   pthread_t thread_;  // Thread handle for pthread.
 };
 
 
-ThreadHandle::ThreadHandle(Kind kind) {
-  data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
-  data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
-  delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
-  return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
-  return data_->thread_ != kNoThread;
-}
-
-
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData()),
       isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
@@ -409,7 +376,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatfromData()),
       isolate_(isolate),
       stack_size_(0) {
   set_name(name);
@@ -417,6 +384,7 @@
 
 
 Thread::~Thread() {
+  delete data_;
 }
 
 
@@ -425,8 +393,8 @@
   // This is also initialized by the first argument to pthread_create() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
-  thread->thread_handle_data()->thread_ = pthread_self();
-  ASSERT(thread->IsValid());
+  thread->data()->thread_ = pthread_self();
+  ASSERT(thread->data()->thread_ != kNoThread);
   Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
@@ -447,13 +415,13 @@
     pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
     attr_ptr = &attr;
   }
-  pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
+  pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
   ASSERT(IsValid());
 }
 
 
 void Thread::Join() {
-  pthread_join(thread_handle_data()->thread_, NULL);
+  pthread_join(data_->thread_, NULL);
 }
 
 
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index da278f3..1a19bac 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -373,50 +373,15 @@
 }
 
 
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
  public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
-    Initialize(kind);
-  }
-
-  void Initialize(ThreadHandle::Kind kind) {
-    switch (kind) {
-      case ThreadHandle::SELF: thread_ = pthread_self(); break;
-      case ThreadHandle::INVALID: thread_ = kNoThread; break;
-    }
-  }
+  PlatformData() : thread_(kNoThread) {  }
 
   pthread_t thread_;  // Thread handle for pthread.
 };
 
-
-ThreadHandle::ThreadHandle(Kind kind) {
-  data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
-  data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
-  delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
-  return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
-  return data_->thread_ != kNoThread;
-}
-
-
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData()),
       isolate_(isolate),
       stack_size_(options.stack_size) {
   set_name(options.name);
@@ -424,7 +389,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
+    : data_(new PlatformData()),
       isolate_(isolate),
       stack_size_(0) {
   set_name(name);
@@ -432,6 +397,7 @@
 
 
 Thread::~Thread() {
+  delete data_;
 }
 
 
@@ -440,8 +406,8 @@
   // This is also initialized by the first argument to pthread_create() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
-  thread->thread_handle_data()->thread_ = pthread_self();
-  ASSERT(thread->IsValid());
+  thread->data()->thread_ = pthread_self();
+  ASSERT(thread->data()->thread_ != kNoThread);
   Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return NULL;
@@ -462,13 +428,13 @@
     pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
     attr_ptr = &attr;
   }
-  pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
-  ASSERT(IsValid());
+  pthread_create(&data_->thread_, NULL, ThreadEntry, this);
+  ASSERT(data_->thread_ != kNoThread);
 }
 
 
 void Thread::Join() {
-  pthread_join(thread_handle_data()->thread_, NULL);
+  pthread_join(data_->thread_, NULL);
 }
 
 
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index ab03e3d..8673f04 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1468,24 +1468,6 @@
 
 // Definition of invalid thread handle and id.
 static const HANDLE kNoThread = INVALID_HANDLE_VALUE;
-static const DWORD kNoThreadId = 0;
-
-
-class ThreadHandle::PlatformData : public Malloced {
- public:
-  explicit PlatformData(ThreadHandle::Kind kind) {
-    Initialize(kind);
-  }
-
-  void Initialize(ThreadHandle::Kind kind) {
-    switch (kind) {
-      case ThreadHandle::SELF: tid_ = GetCurrentThreadId(); break;
-      case ThreadHandle::INVALID: tid_ = kNoThreadId; break;
-    }
-  }
-  DWORD tid_;  // Win32 thread identifier.
-};
-
 
 // Entry point for threads. The supplied argument is a pointer to the thread
 // object. The entry function dispatches to the run method in the thread
@@ -1496,41 +1478,12 @@
   // This is also initialized by the last parameter to _beginthreadex() but we
   // don't know which thread will run first (the original thread or the new
   // one) so we initialize it here too.
-  thread->thread_handle_data()->tid_ = GetCurrentThreadId();
   Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
   thread->Run();
   return 0;
 }
 
 
-// Initialize thread handle to invalid handle.
-ThreadHandle::ThreadHandle(ThreadHandle::Kind kind) {
-  data_ = new PlatformData(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
-  delete data_;
-}
-
-
-// The thread is running if it has the same id as the current thread.
-bool ThreadHandle::IsSelf() const {
-  return GetCurrentThreadId() == data_->tid_;
-}
-
-
-// Test for invalid thread handle.
-bool ThreadHandle::IsValid() const {
-  return data_->tid_ != kNoThreadId;
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
-  data_->Initialize(kind);
-}
-
-
 class Thread::PlatformData : public Malloced {
  public:
   explicit PlatformData(HANDLE thread) : thread_(thread) {}
@@ -1542,8 +1495,7 @@
 // handle until it is started.
 
 Thread::Thread(Isolate* isolate, const Options& options)
-    : ThreadHandle(ThreadHandle::INVALID),
-      isolate_(isolate),
+    : isolate_(isolate),
       stack_size_(options.stack_size) {
   data_ = new PlatformData(kNoThread);
   set_name(options.name);
@@ -1551,8 +1503,7 @@
 
 
 Thread::Thread(Isolate* isolate, const char* name)
-    : ThreadHandle(ThreadHandle::INVALID),
-      isolate_(isolate),
+    : isolate_(isolate),
       stack_size_(0) {
   data_ = new PlatformData(kNoThread);
   set_name(name);
@@ -1582,9 +1533,7 @@
                      ThreadEntry,
                      this,
                      0,
-                     reinterpret_cast<unsigned int*>(
-                         &thread_handle_data()->tid_)));
-  ASSERT(IsValid());
+                     NULL));
 }
 
 
diff --git a/src/platform.h b/src/platform.h
index fea16c8..fc417ef 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -354,40 +354,6 @@
   size_t size_;  // Size of the virtual memory.
 };
 
-
-// ----------------------------------------------------------------------------
-// ThreadHandle
-//
-// A ThreadHandle represents a thread identifier for a thread. The ThreadHandle
-// does not own the underlying os handle. Thread handles can be used for
-// refering to threads and testing equality.
-
-class ThreadHandle {
- public:
-  enum Kind { SELF, INVALID };
-  explicit ThreadHandle(Kind kind);
-
-  // Destructor.
-  ~ThreadHandle();
-
-  // Test for thread running.
-  bool IsSelf() const;
-
-  // Test for valid thread handle.
-  bool IsValid() const;
-
-  // Get platform-specific data.
-  class PlatformData;
-  PlatformData* thread_handle_data() { return data_; }
-
-  // Initialize the handle to kind
-  void Initialize(Kind kind);
-
- private:
-  PlatformData* data_;  // Captures platform dependent data.
-};
-
-
 // ----------------------------------------------------------------------------
 // Thread
 //
@@ -396,7 +362,7 @@
 // thread. The Thread object should not be deallocated before the thread has
 // terminated.
 
-class Thread: public ThreadHandle {
+class Thread {
  public:
   // Opaque data type for thread-local storage keys.
   // LOCAL_STORAGE_KEY_MIN_VALUE and LOCAL_STORAGE_KEY_MAX_VALUE are specified
@@ -468,11 +434,15 @@
   // The thread name length is limited to 16 based on Linux's implementation of
   // prctl().
   static const int kMaxThreadNameLength = 16;
+
+  class PlatformData;
+  PlatformData* data() { return data_; }
+
  private:
   void set_name(const char *name);
 
-  class PlatformData;
   PlatformData* data_;
+
   Isolate* isolate_;
   char name_[kMaxThreadNameLength];
   int stack_size_;
diff --git a/src/preparser-api.cc b/src/preparser-api.cc
index 61e9e7e..9646eb6 100644
--- a/src/preparser-api.cc
+++ b/src/preparser-api.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -159,8 +159,8 @@
 
 class StandAloneJavaScriptScanner : public JavaScriptScanner {
  public:
-  explicit StandAloneJavaScriptScanner(ScannerConstants* scanner_constants)
-      : JavaScriptScanner(scanner_constants) { }
+  explicit StandAloneJavaScriptScanner(UnicodeCache* unicode_cache)
+      : JavaScriptScanner(unicode_cache) { }
 
   void Initialize(UC16CharacterStream* source) {
     source_ = source;
@@ -192,8 +192,8 @@
 PreParserData Preparse(UnicodeInputStream* input, size_t max_stack) {
   internal::InputStreamUTF16Buffer buffer(input);
   uintptr_t stack_limit = reinterpret_cast<uintptr_t>(&buffer) - max_stack;
-  internal::ScannerConstants scanner_constants;
-  internal::StandAloneJavaScriptScanner scanner(&scanner_constants);
+  internal::UnicodeCache unicode_cache;
+  internal::StandAloneJavaScriptScanner scanner(&unicode_cache);
   scanner.Initialize(&buffer);
   internal::CompleteParserRecorder recorder;
   preparser::PreParser::PreParseResult result =
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 6e25169..97f0341 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -107,12 +107,6 @@
 }
 
 
-static bool IsOptimizable(JSFunction* function) {
-  Code* code = function->code();
-  return code->kind() == Code::FUNCTION && code->optimizable();
-}
-
-
 Atomic32 RuntimeProfiler::state_ = 0;
 // TODO(isolates): Create the semaphore lazily and clean it up when no
 // longer required.
@@ -120,6 +114,11 @@
 Semaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0);
 #endif
 
+#ifdef DEBUG
+bool RuntimeProfiler::has_been_globally_setup_ = false;
+#endif
+bool RuntimeProfiler::enabled_ = false;
+
 
 RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
     : isolate_(isolate),
@@ -140,13 +139,17 @@
 }
 
 
-bool RuntimeProfiler::IsEnabled() {
-  return V8::UseCrankshaft() && FLAG_opt;
+void RuntimeProfiler::GlobalSetup() {
+  ASSERT(!has_been_globally_setup_);
+  enabled_ = V8::UseCrankshaft() && FLAG_opt;
+#ifdef DEBUG
+  has_been_globally_setup_ = true;
+#endif
 }
 
 
 void RuntimeProfiler::Optimize(JSFunction* function, bool eager, int delay) {
-  ASSERT(IsOptimizable(function));
+  ASSERT(function->IsOptimizable());
   if (FLAG_trace_opt) {
     PrintF("[marking (%s) ", eager ? "eagerly" : "lazily");
     function->PrintName();
@@ -245,7 +248,7 @@
     if (current->IsValid()) {
       Handle<JSFunction> function = current->function();
       int delay = current->Delay();
-      if (IsOptimizable(*function)) {
+      if (function->IsOptimizable()) {
         Optimize(*function, true, delay);
       }
     }
@@ -290,7 +293,7 @@
     }
 
     // Do not record non-optimizable functions.
-    if (!IsOptimizable(function)) continue;
+    if (!function->IsOptimizable()) continue;
     samples[sample_count++] = function;
 
     int function_size = function->shared()->SourceSize();
@@ -330,7 +333,7 @@
 
 
 void RuntimeProfiler::OptimizeSoon(JSFunction* function) {
-  if (!IsOptimizable(function)) return;
+  if (!function->IsOptimizable()) return;
   PendingListNode* node = new PendingListNode(function);
   node->set_next(optimize_soon_list_);
   optimize_soon_list_ = node;
@@ -369,6 +372,7 @@
 
 
 void RuntimeProfiler::Setup() {
+  ASSERT(has_been_globally_setup_);
   ClearSampleBuffer();
   // If the ticker hasn't already started, make sure to do so to get
   // the ticks for the runtime profiler.
diff --git a/src/runtime-profiler.h b/src/runtime-profiler.h
index 3656893..692b4ff 100644
--- a/src/runtime-profiler.h
+++ b/src/runtime-profiler.h
@@ -44,7 +44,12 @@
  public:
   explicit RuntimeProfiler(Isolate* isolate);
 
-  static bool IsEnabled();
+  static void GlobalSetup();
+
+  static inline bool IsEnabled() {
+    ASSERT(has_been_globally_setup_);
+    return enabled_;
+  }
 
   void OptimizeNow();
   void OptimizeSoon(JSFunction* function);
@@ -143,6 +148,11 @@
   //   0 or positive => the number of isolates running JavaScript code.
   static Atomic32 state_;
   static Semaphore* semaphore_;
+
+#ifdef DEBUG
+  static bool has_been_globally_setup_;
+#endif
+  static bool enabled_;
 };
 
 
diff --git a/src/runtime.cc b/src/runtime.cc
index c7ff3a3..ceb6c10 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -4680,7 +4680,8 @@
   }
 
   // Slower case.
-  return isolate->heap()->NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
+  return isolate->heap()->NumberFromDouble(
+      StringToDouble(isolate->unicode_cache(), subject, ALLOW_HEX));
 }
 
 
@@ -5179,7 +5180,7 @@
   s->TryFlatten();
 
   RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
-  double value = StringToInt(s, radix);
+  double value = StringToInt(isolate->unicode_cache(), s, radix);
   return isolate->heap()->NumberFromDouble(value);
 }
 
@@ -5189,7 +5190,8 @@
   CONVERT_CHECKED(String, str, args[0]);
 
   // ECMA-262 section 15.1.2.3, empty string is NaN
-  double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value());
+  double value = StringToDouble(isolate->unicode_cache(),
+                                str, ALLOW_TRAILING_JUNK, OS::nan_value());
 
   // Create a number object from the value.
   return isolate->heap()->NumberFromDouble(value);
@@ -7405,6 +7407,16 @@
 }
 
 
+RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
+  HandleScope scope(isolate);
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, function, 0);
+  if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
+  function->MarkForLazyRecompilation();
+  return isolate->heap()->undefined_value();
+}
+
+
 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
   HandleScope scope(isolate);
   ASSERT(args.length() == 1);
@@ -8069,10 +8081,14 @@
   RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
   bool result;
   if (str->IsAsciiRepresentation()) {
-    result = DateParser::Parse(str->ToAsciiVector(), output_array);
+    result = DateParser::Parse(str->ToAsciiVector(),
+                               output_array,
+                               isolate->unicode_cache());
   } else {
     ASSERT(str->IsTwoByteRepresentation());
-    result = DateParser::Parse(str->ToUC16Vector(), output_array);
+    result = DateParser::Parse(str->ToUC16Vector(),
+                               output_array,
+                               isolate->unicode_cache());
   }
 
   if (result) {
@@ -10161,8 +10177,7 @@
     details->set(kThreadDetailsCurrentThreadIndex,
                  isolate->heap()->true_value());
     details->set(kThreadDetailsThreadIdIndex,
-                 Smi::FromInt(
-                     isolate->thread_manager()->CurrentId()));
+                 Smi::FromInt(ThreadId::Current().ToInteger()));
   } else {
     // Find the thread with the requested index.
     int n = 1;
@@ -10179,7 +10194,8 @@
     // Fill the details.
     details->set(kThreadDetailsCurrentThreadIndex,
                  isolate->heap()->false_value());
-    details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id()));
+    details->set(kThreadDetailsThreadIdIndex,
+                 Smi::FromInt(thread->id().ToInteger()));
   }
 
   // Convert to JS array and return.
diff --git a/src/runtime.h b/src/runtime.h
index 58062ca..bf1ba68 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -84,7 +84,8 @@
   F(LazyRecompile, 1, 1) \
   F(NotifyDeoptimized, 1, 1) \
   F(NotifyOSR, 0, 1) \
-  F(DeoptimizeFunction, 1, 1)             \
+  F(DeoptimizeFunction, 1, 1) \
+  F(OptimizeFunctionOnNextCall, 1, 1) \
   F(CompileForOnStackReplacement, 1, 1) \
   F(SetNewFunctionAttributes, 1, 1) \
   F(AllocateInNewSpace, 1, 1) \
diff --git a/src/scanner-base.cc b/src/scanner-base.cc
index 2066b5a..9715ca9 100644
--- a/src/scanner-base.cc
+++ b/src/scanner-base.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -35,29 +35,11 @@
 namespace internal {
 
 // ----------------------------------------------------------------------------
-// Compound predicates.
-
-bool ScannerConstants::IsIdentifier(unibrow::CharacterStream* buffer) {
-  // Checks whether the buffer contains an identifier (no escape).
-  if (!buffer->has_more()) return false;
-  if (!kIsIdentifierStart.get(buffer->GetNext())) {
-    return false;
-  }
-  while (buffer->has_more()) {
-    if (!kIsIdentifierPart.get(buffer->GetNext())) {
-      return false;
-    }
-  }
-  return true;
-}
-
-// ----------------------------------------------------------------------------
 // Scanner
 
-Scanner::Scanner(ScannerConstants* scanner_constants)
-    : scanner_constants_(scanner_constants),
-      octal_pos_(kNoOctalLocation) {
-}
+Scanner::Scanner(UnicodeCache* unicode_cache)
+    : unicode_cache_(unicode_cache),
+      octal_pos_(kNoOctalLocation) { }
 
 
 uc32 Scanner::ScanHexEscape(uc32 c, int length) {
@@ -114,7 +96,7 @@
 // ----------------------------------------------------------------------------
 // JavaScriptScanner
 
-JavaScriptScanner::JavaScriptScanner(ScannerConstants* scanner_contants)
+JavaScriptScanner::JavaScriptScanner(UnicodeCache* scanner_contants)
     : Scanner(scanner_contants) { }
 
 
@@ -144,9 +126,9 @@
   while (true) {
     // We treat byte-order marks (BOMs) as whitespace for better
     // compatibility with Spidermonkey and other JavaScript engines.
-    while (scanner_constants_->IsWhiteSpace(c0_) || IsByteOrderMark(c0_)) {
+    while (unicode_cache_->IsWhiteSpace(c0_) || IsByteOrderMark(c0_)) {
       // IsWhiteSpace() includes line terminators!
-      if (scanner_constants_->IsLineTerminator(c0_)) {
+      if (unicode_cache_->IsLineTerminator(c0_)) {
         // Ignore line terminators, but remember them. This is necessary
         // for automatic semicolon insertion.
         has_line_terminator_before_next_ = true;
@@ -186,7 +168,7 @@
   // separately by the lexical grammar and becomes part of the
   // stream of input elements for the syntactic grammar (see
   // ECMA-262, section 7.4, page 12).
-  while (c0_ >= 0 && !scanner_constants_->IsLineTerminator(c0_)) {
+  while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
     Advance();
   }
 
@@ -451,7 +433,7 @@
         break;
 
       default:
-        if (scanner_constants_->IsIdentifierStart(c0_)) {
+        if (unicode_cache_->IsIdentifierStart(c0_)) {
           token = ScanIdentifierOrKeyword();
         } else if (IsDecimalDigit(c0_)) {
           token = ScanNumber(false);
@@ -499,7 +481,7 @@
   Advance();
 
   // Skip escaped newlines.
-  if (scanner_constants_->IsLineTerminator(c)) {
+  if (unicode_cache_->IsLineTerminator(c)) {
     // Allow CR+LF newlines in multiline string literals.
     if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance();
     // Allow LF+CR newlines in multiline string literals.
@@ -542,7 +524,7 @@
 
   LiteralScope literal(this);
   while (c0_ != quote && c0_ >= 0
-         && !scanner_constants_->IsLineTerminator(c0_)) {
+         && !unicode_cache_->IsLineTerminator(c0_)) {
     uc32 c = c0_;
     Advance();
     if (c == '\\') {
@@ -641,7 +623,7 @@
   // not be an identifier start or a decimal digit; see ECMA-262
   // section 7.8.3, page 17 (note that we read only one decimal digit
   // if the value is 0).
-  if (IsDecimalDigit(c0_) || scanner_constants_->IsIdentifierStart(c0_))
+  if (IsDecimalDigit(c0_) || unicode_cache_->IsIdentifierStart(c0_))
     return Token::ILLEGAL;
 
   literal.Complete();
@@ -663,14 +645,14 @@
 
 
 Token::Value JavaScriptScanner::ScanIdentifierOrKeyword() {
-  ASSERT(scanner_constants_->IsIdentifierStart(c0_));
+  ASSERT(unicode_cache_->IsIdentifierStart(c0_));
   LiteralScope literal(this);
   KeywordMatcher keyword_match;
   // Scan identifier start character.
   if (c0_ == '\\') {
     uc32 c = ScanIdentifierUnicodeEscape();
     // Only allow legal identifier start characters.
-    if (!scanner_constants_->IsIdentifierStart(c)) return Token::ILLEGAL;
+    if (!unicode_cache_->IsIdentifierStart(c)) return Token::ILLEGAL;
     AddLiteralChar(c);
     return ScanIdentifierSuffix(&literal);
   }
@@ -683,7 +665,7 @@
   }
 
   // Scan the rest of the identifier characters.
-  while (scanner_constants_->IsIdentifierPart(c0_)) {
+  while (unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ != '\\') {
       uc32 next_char = c0_;
       Advance();
@@ -701,11 +683,11 @@
 
 Token::Value JavaScriptScanner::ScanIdentifierSuffix(LiteralScope* literal) {
   // Scan the rest of the identifier characters.
-  while (scanner_constants_->IsIdentifierPart(c0_)) {
+  while (unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ == '\\') {
       uc32 c = ScanIdentifierUnicodeEscape();
       // Only allow legal identifier part characters.
-      if (!scanner_constants_->IsIdentifierPart(c)) return Token::ILLEGAL;
+      if (!unicode_cache_->IsIdentifierPart(c)) return Token::ILLEGAL;
       AddLiteralChar(c);
     } else {
       AddLiteralChar(c0_);
@@ -735,10 +717,10 @@
     AddLiteralChar('=');
 
   while (c0_ != '/' || in_character_class) {
-    if (scanner_constants_->IsLineTerminator(c0_) || c0_ < 0) return false;
+    if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
     if (c0_ == '\\') {  // Escape sequence.
       AddLiteralCharAdvance();
-      if (scanner_constants_->IsLineTerminator(c0_) || c0_ < 0) return false;
+      if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
       AddLiteralCharAdvance();
       // If the escape allows more characters, i.e., \x??, \u????, or \c?,
       // only "safe" characters are allowed (letters, digits, underscore),
@@ -764,7 +746,7 @@
 bool JavaScriptScanner::ScanRegExpFlags() {
   // Scan regular expression flags.
   LiteralScope literal(this);
-  while (scanner_constants_->IsIdentifierPart(c0_)) {
+  while (unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ == '\\') {
       uc32 c = ScanIdentifierUnicodeEscape();
       if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) {
diff --git a/src/scanner-base.h b/src/scanner-base.h
index 552f387..60b97d2 100644
--- a/src/scanner-base.h
+++ b/src/scanner-base.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -119,11 +119,11 @@
 };
 
 
-class ScannerConstants {
+class UnicodeCache {
 // ---------------------------------------------------------------------
-// Constants used by scanners.
+// Caching predicates used by scanners.
  public:
-  ScannerConstants() {}
+  UnicodeCache() {}
   typedef unibrow::Utf8InputBuffer<1024> Utf8Decoder;
 
   StaticResource<Utf8Decoder>* utf8_decoder() {
@@ -135,8 +135,6 @@
   bool IsLineTerminator(unibrow::uchar c) { return kIsLineTerminator.get(c); }
   bool IsWhiteSpace(unibrow::uchar c) { return kIsWhiteSpace.get(c); }
 
-  bool IsIdentifier(unibrow::CharacterStream* buffer);
-
  private:
 
   unibrow::Predicate<IdentifierStart, 128> kIsIdentifierStart;
@@ -145,9 +143,10 @@
   unibrow::Predicate<unibrow::WhiteSpace, 128> kIsWhiteSpace;
   StaticResource<Utf8Decoder> utf8_decoder_;
 
-  DISALLOW_COPY_AND_ASSIGN(ScannerConstants);
+  DISALLOW_COPY_AND_ASSIGN(UnicodeCache);
 };
 
+
 // ----------------------------------------------------------------------------
 // LiteralBuffer -  Collector of chars of literals.
 
@@ -272,7 +271,7 @@
     bool complete_;
   };
 
-  explicit Scanner(ScannerConstants* scanner_contants);
+  explicit Scanner(UnicodeCache* scanner_contants);
 
   // Returns the current token again.
   Token::Value current_token() { return current_.token; }
@@ -427,7 +426,7 @@
     return source_->pos() - kCharacterLookaheadBufferSize;
   }
 
-  ScannerConstants* scanner_constants_;
+  UnicodeCache* unicode_cache_;
 
   // Buffers collecting literal strings, numbers, etc.
   LiteralBuffer literal_buffer1_;
@@ -473,7 +472,7 @@
     bool complete_;
   };
 
-  explicit JavaScriptScanner(ScannerConstants* scanner_contants);
+  explicit JavaScriptScanner(UnicodeCache* scanner_contants);
 
   // Returns the next token.
   Token::Value Next();
diff --git a/src/scanner.cc b/src/scanner.cc
index d9c2188..666818e 100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -345,8 +345,8 @@
 // ----------------------------------------------------------------------------
 // JsonScanner
 
-JsonScanner::JsonScanner(ScannerConstants* scanner_constants)
-    : Scanner(scanner_constants) { }
+JsonScanner::JsonScanner(UnicodeCache* unicode_cache)
+    : Scanner(unicode_cache) { }
 
 
 void JsonScanner::Initialize(UC16CharacterStream* source) {
@@ -560,7 +560,8 @@
   }
   literal.Complete();
   ASSERT_NOT_NULL(next_.literal_chars);
-  number_ = StringToDouble(next_.literal_chars->ascii_literal(),
+  number_ = StringToDouble(unicode_cache_,
+                           next_.literal_chars->ascii_literal(),
                            NO_FLAGS,  // Hex, octal or trailing junk.
                            OS::nan_value());
   return Token::NUMBER;
@@ -575,7 +576,7 @@
     Advance();
     text++;
   }
-  if (scanner_constants_->IsIdentifierPart(c0_)) return Token::ILLEGAL;
+  if (unicode_cache_->IsIdentifierPart(c0_)) return Token::ILLEGAL;
   literal.Complete();
   return token;
 }
diff --git a/src/scanner.h b/src/scanner.h
index 776ba53..871c69b 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -134,8 +134,8 @@
 
 class V8JavaScriptScanner : public JavaScriptScanner {
  public:
-  explicit V8JavaScriptScanner(ScannerConstants* scanner_constants)
-      : JavaScriptScanner(scanner_constants) {}
+  explicit V8JavaScriptScanner(UnicodeCache* unicode_cache)
+      : JavaScriptScanner(unicode_cache) {}
 
   void Initialize(UC16CharacterStream* source);
 };
@@ -143,7 +143,7 @@
 
 class JsonScanner : public Scanner {
  public:
-  explicit JsonScanner(ScannerConstants* scanner_constants);
+  explicit JsonScanner(UnicodeCache* unicode_cache);
 
   void Initialize(UC16CharacterStream* source);
 
diff --git a/src/top.cc b/src/top.cc
index 8611a31..899dfbe 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -69,10 +69,8 @@
 #endif
   try_catch_handler_address_ = NULL;
   context_ = NULL;
-  int id = Isolate::Current()->thread_manager()->CurrentId();
-  thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id;
+  thread_id_ = ThreadId::Current();
   external_caught_exception_ = false;
-  in_exception_reporting_ = false;
   failed_access_check_callback_ = NULL;
   save_context_ = NULL;
   catcher_ = NULL;
diff --git a/src/v8.cc b/src/v8.cc
index 19ed184..0b562fc 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -63,8 +63,8 @@
   }
 
   ASSERT(i::Isolate::CurrentPerIsolateThreadData() != NULL);
-  ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id() ==
-         i::Thread::GetThreadLocalInt(i::Isolate::thread_id_key()));
+  ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
+           i::ThreadId::Current()));
   ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
          i::Isolate::Current());
 
@@ -204,6 +204,8 @@
     use_crankshaft_ = false;
   }
 
+  RuntimeProfiler::GlobalSetup();
+
   // Peephole optimization might interfere with deoptimization.
   FLAG_peephole_optimization = !use_crankshaft_;
 }
diff --git a/src/v8threads.cc b/src/v8threads.cc
index cecafaa..4b033fc 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -147,11 +147,11 @@
   // First check whether the current thread has been 'lazily archived', ie
   // not archived at all.  If that is the case we put the state storage we
   // had prepared back in the free list, since we didn't need it after all.
-  if (lazily_archived_thread_.IsSelf()) {
-    lazily_archived_thread_.Initialize(ThreadHandle::INVALID);
+  if (lazily_archived_thread_.Equals(ThreadId::Current())) {
+    lazily_archived_thread_ = ThreadId::Invalid();
     ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() ==
            lazily_archived_thread_state_);
-    lazily_archived_thread_state_->set_id(kInvalidId);
+    lazily_archived_thread_state_->set_id(ThreadId::Invalid());
     lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST);
     lazily_archived_thread_state_ = NULL;
     Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL);
@@ -190,7 +190,7 @@
     isolate_->stack_guard()->TerminateExecution();
     state->set_terminate_on_restore(false);
   }
-  state->set_id(kInvalidId);
+  state->set_id(ThreadId::Invalid());
   state->Unlink();
   state->LinkInto(ThreadState::FREE_LIST);
   return true;
@@ -199,13 +199,13 @@
 
 void ThreadManager::Lock() {
   mutex_->Lock();
-  mutex_owner_.Initialize(ThreadHandle::SELF);
+  mutex_owner_ = ThreadId::Current();
   ASSERT(IsLockedByCurrentThread());
 }
 
 
 void ThreadManager::Unlock() {
-  mutex_owner_.Initialize(ThreadHandle::INVALID);
+  mutex_owner_ = ThreadId::Invalid();
   mutex_->Unlock();
 }
 
@@ -224,7 +224,7 @@
 
 
 ThreadState::ThreadState(ThreadManager* thread_manager)
-    : id_(ThreadManager::kInvalidId),
+    : id_(ThreadId::Invalid()),
       terminate_on_restore_(false),
       next_(this),
       previous_(this),
@@ -282,8 +282,8 @@
 // defined as 0.)
 ThreadManager::ThreadManager()
     : mutex_(OS::CreateMutex()),
-      mutex_owner_(ThreadHandle::INVALID),
-      lazily_archived_thread_(ThreadHandle::INVALID),
+      mutex_owner_(ThreadId::Invalid()),
+      lazily_archived_thread_(ThreadId::Invalid()),
       lazily_archived_thread_state_(NULL),
       free_anchor_(NULL),
       in_use_anchor_(NULL) {
@@ -298,16 +298,16 @@
 
 
 void ThreadManager::ArchiveThread() {
-  ASSERT(!lazily_archived_thread_.IsValid());
+  ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid()));
   ASSERT(!IsArchived());
   ThreadState* state = GetFreeThreadState();
   state->Unlink();
   Isolate::CurrentPerIsolateThreadData()->set_thread_state(state);
-  lazily_archived_thread_.Initialize(ThreadHandle::SELF);
+  lazily_archived_thread_ = ThreadId::Current();
   lazily_archived_thread_state_ = state;
-  ASSERT(state->id() == kInvalidId);
+  ASSERT(state->id().Equals(ThreadId::Invalid()));
   state->set_id(CurrentId());
-  ASSERT(state->id() != kInvalidId);
+  ASSERT(!state->id().Equals(ThreadId::Invalid()));
 }
 
 
@@ -326,7 +326,7 @@
   to = isolate_->stack_guard()->ArchiveStackGuard(to);
   to = isolate_->regexp_stack()->ArchiveStack(to);
   to = isolate_->bootstrapper()->ArchiveState(to);
-  lazily_archived_thread_.Initialize(ThreadHandle::INVALID);
+  lazily_archived_thread_ = ThreadId::Invalid();
   lazily_archived_thread_state_ = NULL;
 }
 
@@ -373,16 +373,16 @@
 }
 
 
-int ThreadManager::CurrentId() {
-  return Thread::GetThreadLocalInt(Isolate::thread_id_key());
+ThreadId ThreadManager::CurrentId() {
+  return ThreadId::Current();
 }
 
 
-void ThreadManager::TerminateExecution(int thread_id) {
+void ThreadManager::TerminateExecution(ThreadId thread_id) {
   for (ThreadState* state = FirstThreadStateInUse();
        state != NULL;
        state = state->Next()) {
-    if (thread_id == state->id()) {
+    if (thread_id.Equals(state->id())) {
       state->set_terminate_on_restore(true);
     }
   }
diff --git a/src/v8threads.h b/src/v8threads.h
index 1266af7..d8a923e 100644
--- a/src/v8threads.h
+++ b/src/v8threads.h
@@ -43,8 +43,8 @@
   void Unlink();
 
   // Id of thread.
-  void set_id(int id) { id_ = id; }
-  int id() { return id_; }
+  void set_id(ThreadId id) { id_ = id; }
+  ThreadId id() { return id_; }
 
   // Should the thread be terminated when it is restored?
   bool terminate_on_restore() { return terminate_on_restore_; }
@@ -59,7 +59,7 @@
 
   void AllocateSpace();
 
-  int id_;
+  ThreadId id_;
   bool terminate_on_restore_;
   char* data_;
   ThreadState* next_;
@@ -97,17 +97,18 @@
 
   void Iterate(ObjectVisitor* v);
   void IterateArchivedThreads(ThreadVisitor* v);
-  bool IsLockedByCurrentThread() { return mutex_owner_.IsSelf(); }
+  bool IsLockedByCurrentThread() {
+    return mutex_owner_.Equals(ThreadId::Current());
+  }
 
-  int CurrentId();
+  ThreadId CurrentId();
 
-  void TerminateExecution(int thread_id);
+  void TerminateExecution(ThreadId thread_id);
 
   // Iterate over in-use states.
   ThreadState* FirstThreadStateInUse();
   ThreadState* GetFreeThreadState();
 
-  static const int kInvalidId = -1;
  private:
   ThreadManager();
   ~ThreadManager();
@@ -115,8 +116,8 @@
   void EagerlyArchiveThread();
 
   Mutex* mutex_;
-  ThreadHandle mutex_owner_;
-  ThreadHandle lazily_archived_thread_;
+  ThreadId mutex_owner_;
+  ThreadId lazily_archived_thread_;
   ThreadState* lazily_archived_thread_state_;
 
   // In the following two lists there is always at least one object on the list.
diff --git a/src/version.cc b/src/version.cc
index 120e564..c5ded6d 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     2
-#define BUILD_NUMBER      9
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      10
+#define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 0ab676f..9fe212e 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -99,7 +99,7 @@
   // ecx:edx. Temporarily enable CPUID support because we know it's
   // safe here.
   __ bind(&cpuid);
-  __ movq(rax, Immediate(1));
+  __ movl(rax, Immediate(1));
   supported_ = kDefaultCpuFeatures | (1 << CPUID);
   { Scope fscope(CPUID);
     __ cpuid();
@@ -1398,7 +1398,12 @@
 
 void Assembler::movb(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  emit_rex_32(dst, src);
+  if (dst.code() > 3) {
+    // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
+    emit_rex_32(dst, src);
+  } else {
+    emit_optional_rex_32(dst, src);
+  }
   emit(0x8A);
   emit_operand(dst, src);
 }
@@ -1406,16 +1411,21 @@
 
 void Assembler::movb(Register dst, Immediate imm) {
   EnsureSpace ensure_space(this);
-  emit_rex_32(dst);
-  emit(0xC6);
-  emit_modrm(0x0, dst);
+  if (dst.code() > 3) {
+    emit_rex_32(dst);
+  }
+  emit(0xB0 + dst.low_bits());
   emit(imm.value_);
 }
 
 
 void Assembler::movb(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
-  emit_rex_32(src, dst);
+  if (src.code() > 3) {
+    emit_rex_32(src, dst);
+  } else {
+    emit_optional_rex_32(src, dst);
+  }
   emit(0x88);
   emit_operand(src, dst);
 }
@@ -1465,16 +1475,15 @@
   emit_optional_rex_32(dst);
   emit(0xC7);
   emit_operand(0x0, dst);
-  emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
+  emit(value);
 }
 
 
 void Assembler::movl(Register dst, Immediate value) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(dst);
-  emit(0xC7);
-  emit_modrm(0x0, dst);
-  emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
+  emit(0xB8 + dst.low_bits());
+  emit(value);
 }
 
 
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index fc3257d..a549633 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -96,7 +96,7 @@
   // rax: number of arguments
   __ bind(&non_function_call);
   // Set expected number of arguments to zero (not changing rax).
-  __ movq(rbx, Immediate(0));
+  __ Set(rbx, 0);
   __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
           RelocInfo::CODE_TARGET);
@@ -1372,7 +1372,7 @@
     // Copy receiver and all expected arguments.
     const int offset = StandardFrameConstants::kCallerSPOffset;
     __ lea(rax, Operand(rbp, rax, times_pointer_size, offset));
-    __ movq(rcx, Immediate(-1));  // account for receiver
+    __ Set(rcx, -1);  // account for receiver
 
     Label copy;
     __ bind(&copy);
@@ -1391,7 +1391,7 @@
     // Copy receiver and all actual arguments.
     const int offset = StandardFrameConstants::kCallerSPOffset;
     __ lea(rdi, Operand(rbp, rax, times_pointer_size, offset));
-    __ movq(rcx, Immediate(-1));  // account for receiver
+    __ Set(rcx, -1);  // account for receiver
 
     Label copy;
     __ bind(&copy);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index f2f0fc6..11727a0 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -273,7 +273,7 @@
 
   // Return 1/0 for true/false in rax.
   __ bind(&true_result);
-  __ movq(rax, Immediate(1));
+  __ Set(rax, 1);
   __ ret(1 * kPointerSize);
   __ bind(&false_result);
   __ Set(rax, 0);
@@ -1281,7 +1281,7 @@
   __ bind(&check_undefined_arg1);
   __ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
   __ j(not_equal, conversion_failure);
-  __ movl(r8, Immediate(0));
+  __ Set(r8, 0);
   __ jmp(&load_arg2);
 
   __ bind(&arg1_is_object);
@@ -1301,7 +1301,7 @@
   __ bind(&check_undefined_arg2);
   __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
   __ j(not_equal, conversion_failure);
-  __ movl(rcx, Immediate(0));
+  __ Set(rcx, 0);
   __ jmp(&done);
 
   __ bind(&arg2_is_object);
@@ -1458,7 +1458,7 @@
     __ j(not_equal, &slow);
     // Operand is a float, negate its value by flipping sign bit.
     __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
-    __ movq(kScratchRegister, Immediate(0x01));
+    __ Set(kScratchRegister, 0x01);
     __ shl(kScratchRegister, Immediate(63));
     __ xor_(rdx, kScratchRegister);  // Flip sign.
     // rdx is value to store.
@@ -1530,7 +1530,7 @@
   __ movq(rax, Operand(rsp, 1 * kPointerSize));
 
   // Save 1 in xmm3 - we need this several times later on.
-  __ movl(rcx, Immediate(1));
+  __ Set(rcx, 1);
   __ cvtlsi2sd(xmm3, rcx);
 
   Label exponent_nonsmi;
@@ -3253,7 +3253,7 @@
       __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
       __ Assert(equal, "InstanceofStub unexpected call site cache (mov).");
     }
-    __ xorl(rax, rax);
+    __ Set(rax, 0);
   }
   __ ret(2 * kPointerSize + extra_stack_space);
 
@@ -4112,7 +4112,7 @@
   // if (hash == 0) hash = 27;
   Label hash_not_zero;
   __ j(not_zero, &hash_not_zero);
-  __ movl(hash, Immediate(27));
+  __ Set(hash, 27);
   __ bind(&hash_not_zero);
 }
 
@@ -4308,7 +4308,7 @@
     // Use scratch3 as loop index, min_length as limit and scratch2
     // for computation.
     const Register index = scratch3;
-    __ movl(index, Immediate(0));  // Index into strings.
+    __ Set(index, 0);  // Index into strings.
     __ bind(&loop);
     // Compare characters.
     // TODO(lrn): Could we load more than one character at a time?
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index ffd84ef..abac2b6 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -665,7 +665,7 @@
   __ PrepareCallCFunction(6);
   __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
   __ movq(arg1, rax);
-  __ movq(arg2, Immediate(type()));
+  __ Set(arg2, type());
   // Args 3 and 4 are already in the right registers.
 
   // On windows put the arguments on the stack (PrepareCallCFunction
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index 189ee42..2b7b7b7 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -652,6 +652,9 @@
     case 2:
       mnem = "adc";
       break;
+    case 3:
+      mnem = "sbb";
+      break;
     case 4:
       mnem = "and";
       break;
@@ -1502,7 +1505,39 @@
         data++;
       }
         break;
-
+      case 0xB0:
+      case 0xB1:
+      case 0xB2:
+      case 0xB3:
+      case 0xB4:
+      case 0xB5:
+      case 0xB6:
+      case 0xB7:
+      case 0xB8:
+      case 0xB9:
+      case 0xBA:
+      case 0xBB:
+      case 0xBC:
+      case 0xBD:
+      case 0xBE:
+      case 0xBF: {
+        // mov reg8,imm8 or mov reg32,imm32
+        byte opcode = *data;
+        data++;
+        bool is_32bit = (opcode >= 0xB8);
+        int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
+        if (is_32bit) {
+          AppendToBuffer("mov%c %s, ",
+                         operand_size_code(),
+                         NameOfCPURegister(reg));
+          data += PrintImmediate(data, DOUBLEWORD_SIZE);
+        } else {
+          AppendToBuffer("movb %s, ",
+                         NameOfByteCPURegister(reg));
+          data += PrintImmediate(data, BYTE_SIZE);
+        }
+        break;
+      }
       case 0xFE: {
         data++;
         int mod, regop, rm;
@@ -1513,9 +1548,8 @@
         } else {
           UnimplementedInstruction();
         }
-      }
         break;
-
+      }
       case 0x68:
         AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1));
         data += 5;
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 38c85f0..5ca56ac 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -1010,7 +1010,7 @@
 
   // Call the entry.
   CEntryStub stub(1);
-  __ movq(rax, Immediate(2));
+  __ Set(rax, 2);
   __ LoadAddress(rbx, ExternalReference(IC_Utility(id), masm->isolate()));
   __ CallStub(&stub);
 
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 56e6cc2..202e7a2 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -149,7 +149,7 @@
   int slots = StackSlotCount();
   if (slots > 0) {
     if (FLAG_debug_code) {
-      __ movl(rax, Immediate(slots));
+      __ Set(rax, slots);
       __ movq(kScratchRegister, kSlotsZapValue, RelocInfo::NONE);
       Label loop;
       __ bind(&loop);
@@ -1099,7 +1099,7 @@
 
 void LCodeGen::DoConstantI(LConstantI* instr) {
   ASSERT(instr->result()->IsRegister());
-  __ movl(ToRegister(instr->result()), Immediate(instr->value()));
+  __ Set(ToRegister(instr->result()), instr->value());
 }
 
 
@@ -1514,10 +1514,11 @@
 
   __ CompareRoot(reg, Heap::kNullValueRootIndex);
   if (instr->is_strict()) {
+    ASSERT(Heap::kTrueValueRootIndex >= 0);
     __ movl(result, Immediate(Heap::kTrueValueRootIndex));
     NearLabel load;
     __ j(equal, &load);
-    __ movl(result, Immediate(Heap::kFalseValueRootIndex));
+    __ Set(result, Heap::kFalseValueRootIndex);
     __ bind(&load);
     __ LoadRootIndexed(result, result, 0);
   } else {
@@ -1976,11 +1977,11 @@
     __ Push(instr->function());
 
     Register temp = ToRegister(instr->TempAt(0));
-    static const int kAdditionalDelta = 13;
+    static const int kAdditionalDelta = 10;
     int delta =
         masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
-    __ movq(temp, Immediate(delta));
-    __ push(temp);
+    ASSERT(delta >= 0);
+    __ push_imm32(delta);
 
     // We are pushing three values on the stack but recording a
     // safepoint with two arguments because stub is going to
@@ -1992,6 +1993,8 @@
                     RECORD_SAFEPOINT_WITH_REGISTERS,
                     2);
     ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check));
+    // Move result to a register that survives the end of the
+    // PushSafepointRegisterScope.
     __ movq(kScratchRegister, rax);
   }
   __ testq(kScratchRegister, kScratchRegister);
@@ -2426,14 +2429,14 @@
   } else {
     __ cmpq(rbp, ToOperand(instr->InputAt(0)));
   }
-  __ movq(result, Immediate(scope()->num_parameters()));
+  __ movl(result, Immediate(scope()->num_parameters()));
   __ j(equal, &done);
 
   // Arguments adaptor frame present. Get argument length from there.
   __ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
-  __ movq(result, Operand(result,
-                          ArgumentsAdaptorFrameConstants::kLengthOffset));
-  __ SmiToInteger32(result, result);
+  __ SmiToInteger32(result,
+                    Operand(result,
+                            ArgumentsAdaptorFrameConstants::kLengthOffset));
 
   // Argument length is in result register.
   __ bind(&done);
@@ -3415,7 +3418,7 @@
     // conversions.
     __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
     DeoptimizeIf(not_equal, instr->environment());
-    __ movl(input_reg, Immediate(0));
+    __ Set(input_reg, 0);
     __ jmp(&done);
 
     __ bind(&heap_number);
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index b097166..7f027f7 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -788,10 +788,10 @@
 void MacroAssembler::Set(Register dst, int64_t x) {
   if (x == 0) {
     xorl(dst, dst);
-  } else if (is_int32(x)) {
-    movq(dst, Immediate(static_cast<int32_t>(x)));
   } else if (is_uint32(x)) {
     movl(dst, Immediate(static_cast<uint32_t>(x)));
+  } else if (is_int32(x)) {
+    movq(dst, Immediate(static_cast<int32_t>(x)));
   } else {
     movq(dst, x, RelocInfo::NONE);
   }
@@ -801,7 +801,7 @@
   if (is_int32(x)) {
     movq(dst, Immediate(static_cast<int32_t>(x)));
   } else {
-    movq(kScratchRegister, x, RelocInfo::NONE);
+    Set(kScratchRegister, x);
     movq(dst, kScratchRegister);
   }
 }
@@ -1814,7 +1814,7 @@
     // Set external caught exception to false.
     ExternalReference external_caught(
         Isolate::k_external_caught_exception_address, isolate());
-    movq(rax, Immediate(false));
+    Set(rax, static_cast<int64_t>(false));
     Store(external_caught, rax);
 
     // Set pending exception and rax to out of memory exception.
@@ -2002,7 +2002,7 @@
 void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
   if (FLAG_native_code_counters && counter->Enabled()) {
     Operand counter_operand = ExternalOperand(ExternalReference(counter));
-    movq(counter_operand, Immediate(value));
+    movl(counter_operand, Immediate(value));
   }
 }
 
@@ -2220,8 +2220,8 @@
   const int kFrameAlignment = OS::ActivationFrameAlignment();
   if (kFrameAlignment > 0) {
     ASSERT(IsPowerOf2(kFrameAlignment));
-    movq(kScratchRegister, Immediate(-kFrameAlignment));
-    and_(rsp, kScratchRegister);
+    ASSERT(is_int8(kFrameAlignment));
+    and_(rsp, Immediate(-kFrameAlignment));
   }
 
   // Patch the saved entry sp.
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 03f91fa..d4ccb0e 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -762,7 +762,7 @@
   __ j(above_equal, &stack_ok);
   // Exit with OutOfMemory exception. There is not enough space on the stack
   // for our working registers.
-  __ movq(rax, Immediate(EXCEPTION));
+  __ Set(rax, EXCEPTION);
   __ jmp(&exit_label_);
 
   __ bind(&stack_limit_hit);
@@ -799,7 +799,7 @@
     // Fill saved registers with initial value = start offset - 1
     // Fill in stack push order, to avoid accessing across an unwritten
     // page (a problem on Windows).
-    __ movq(rcx, Immediate(kRegisterZero));
+    __ Set(rcx, kRegisterZero);
     Label init_loop;
     __ bind(&init_loop);
     __ movq(Operand(rbp, rcx, times_1, 0), rax);
@@ -829,7 +829,7 @@
   LoadCurrentCharacterUnchecked(-1, 1);  // Load previous char.
   __ jmp(&start_label_);
   __ bind(&at_start);
-  __ movq(current_character(), Immediate('\n'));
+  __ Set(current_character(), '\n');
   __ jmp(&start_label_);
 
 
@@ -857,7 +857,7 @@
         __ movl(Operand(rbx, i * kIntSize), rax);
       }
     }
-    __ movq(rax, Immediate(SUCCESS));
+    __ Set(rax, SUCCESS);
   }
 
   // Exit and return rax
@@ -959,7 +959,7 @@
     // If any of the code above needed to exit with an exception.
     __ bind(&exit_with_exception);
     // Exit with Result EXCEPTION(-1) to signal thrown exception.
-    __ movq(rax, Immediate(EXCEPTION));
+    __ Set(rax, EXCEPTION);
     __ jmp(&exit_label_);
   }
 
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 26b20f4..c19d29d 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -399,7 +399,7 @@
   ExternalReference ref =
       ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
                         masm->isolate());
-  __ movq(rax, Immediate(5));
+  __ Set(rax, 5);
   __ LoadAddress(rbx, ref);
 
   CEntryStub stub(1);
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 986fb8d..3bb9998 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -57,6 +57,12 @@
 test-debug/DebuggerAgentProtocolOverflowHeader: SKIP
 test-sockets/Socket: SKIP
 
+# BUG(1075): Unresolved crashes.
+cctest/test-serialize/Deserialize: PASS || FAIL
+cctest/test-serialize/DeserializeFromSecondSerializationAndRunScript2: PASS || FAIL
+cctest/test-serialize/DeserializeAndRunScript2: PASS || FAIL
+cctest/test-serialize/DeserializeFromSecondSerialization: PASS || FAIL
+
 ##############################################################################
 [ $arch == arm && $crankshaft ]
 
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 715dbdb..d7621d1 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -8671,18 +8671,21 @@
 }
 
 
+static int call_depth;
+
+
 static void WithTryCatch(Handle<Message> message, Handle<Value> data) {
   TryCatch try_catch;
 }
 
 
 static void ThrowFromJS(Handle<Message> message, Handle<Value> data) {
-  CompileRun("throw 'ThrowInJS';");
+  if (--call_depth) CompileRun("throw 'ThrowInJS';");
 }
 
 
 static void ThrowViaApi(Handle<Message> message, Handle<Value> data) {
-  ThrowException(v8_str("ThrowViaApi"));
+  if (--call_depth) ThrowException(v8_str("ThrowViaApi"));
 }
 
 
@@ -8708,6 +8711,7 @@
     if (callback != NULL) {
       V8::AddMessageListener(callback);
     }
+    call_depth = 5;
     ExpectFalse(
         "var thrown = false;\n"
         "try { func(); } catch(e) { thrown = true; }\n"
diff --git a/test/cctest/test-conversions.cc b/test/cctest/test-conversions.cc
index 1b5cc2d..7c29746 100644
--- a/test/cctest/test-conversions.cc
+++ b/test/cctest/test-conversions.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 
 #include <stdlib.h>
 
@@ -11,139 +11,151 @@
 
 
 TEST(Hex) {
-  CHECK_EQ(0.0, StringToDouble("0x0", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.0, StringToDouble("0X0", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(1.0, StringToDouble("0x1", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(16.0, StringToDouble("0x10", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(255.0, StringToDouble("0xff", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(175.0, StringToDouble("0xAF", ALLOW_HEX | ALLOW_OCTALS));
+  UnicodeCache uc;
+  CHECK_EQ(0.0, StringToDouble(&uc, "0x0", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0X0", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(1.0, StringToDouble(&uc, "0x1", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(16.0, StringToDouble(&uc, "0x10", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(255.0, StringToDouble(&uc, "0xff", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(175.0, StringToDouble(&uc, "0xAF", ALLOW_HEX | ALLOW_OCTALS));
 
-  CHECK_EQ(0.0, StringToDouble("0x0", ALLOW_HEX));
-  CHECK_EQ(0.0, StringToDouble("0X0", ALLOW_HEX));
-  CHECK_EQ(1.0, StringToDouble("0x1", ALLOW_HEX));
-  CHECK_EQ(16.0, StringToDouble("0x10", ALLOW_HEX));
-  CHECK_EQ(255.0, StringToDouble("0xff", ALLOW_HEX));
-  CHECK_EQ(175.0, StringToDouble("0xAF", ALLOW_HEX));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0x0", ALLOW_HEX));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0X0", ALLOW_HEX));
+  CHECK_EQ(1.0, StringToDouble(&uc, "0x1", ALLOW_HEX));
+  CHECK_EQ(16.0, StringToDouble(&uc, "0x10", ALLOW_HEX));
+  CHECK_EQ(255.0, StringToDouble(&uc, "0xff", ALLOW_HEX));
+  CHECK_EQ(175.0, StringToDouble(&uc, "0xAF", ALLOW_HEX));
 }
 
 
 TEST(Octal) {
-  CHECK_EQ(0.0, StringToDouble("0", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.0, StringToDouble("00", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(1.0, StringToDouble("01", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(7.0, StringToDouble("07", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(8.0, StringToDouble("010", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(63.0, StringToDouble("077", ALLOW_HEX | ALLOW_OCTALS));
+  UnicodeCache uc;
+  CHECK_EQ(0.0, StringToDouble(&uc, "0", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "00", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(1.0, StringToDouble(&uc, "01", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(7.0, StringToDouble(&uc, "07", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(8.0, StringToDouble(&uc, "010", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(63.0, StringToDouble(&uc, "077", ALLOW_HEX | ALLOW_OCTALS));
 
-  CHECK_EQ(0.0, StringToDouble("0", ALLOW_HEX));
-  CHECK_EQ(0.0, StringToDouble("00", ALLOW_HEX));
-  CHECK_EQ(1.0, StringToDouble("01", ALLOW_HEX));
-  CHECK_EQ(7.0, StringToDouble("07", ALLOW_HEX));
-  CHECK_EQ(10.0, StringToDouble("010", ALLOW_HEX));
-  CHECK_EQ(77.0, StringToDouble("077", ALLOW_HEX));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0", ALLOW_HEX));
+  CHECK_EQ(0.0, StringToDouble(&uc, "00", ALLOW_HEX));
+  CHECK_EQ(1.0, StringToDouble(&uc, "01", ALLOW_HEX));
+  CHECK_EQ(7.0, StringToDouble(&uc, "07", ALLOW_HEX));
+  CHECK_EQ(10.0, StringToDouble(&uc, "010", ALLOW_HEX));
+  CHECK_EQ(77.0, StringToDouble(&uc, "077", ALLOW_HEX));
 
   const double x = 010000000000;  // Power of 2, no rounding errors.
-  CHECK_EQ(x * x * x * x * x, StringToDouble("01" "0000000000" "0000000000"
+  CHECK_EQ(x * x * x * x * x, StringToDouble(&uc, "01" "0000000000" "0000000000"
       "0000000000" "0000000000" "0000000000", ALLOW_OCTALS));
 }
 
 
 TEST(MalformedOctal) {
-  CHECK_EQ(8.0, StringToDouble("08", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(81.0, StringToDouble("081", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(78.0, StringToDouble("078", ALLOW_HEX | ALLOW_OCTALS));
+  UnicodeCache uc;
+  CHECK_EQ(8.0, StringToDouble(&uc, "08", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(81.0, StringToDouble(&uc, "081", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(78.0, StringToDouble(&uc, "078", ALLOW_HEX | ALLOW_OCTALS));
 
-  CHECK(isnan(StringToDouble("07.7", ALLOW_HEX | ALLOW_OCTALS)));
-  CHECK(isnan(StringToDouble("07.8", ALLOW_HEX | ALLOW_OCTALS)));
-  CHECK(isnan(StringToDouble("07e8", ALLOW_HEX | ALLOW_OCTALS)));
-  CHECK(isnan(StringToDouble("07e7", ALLOW_HEX | ALLOW_OCTALS)));
+  CHECK(isnan(StringToDouble(&uc, "07.7", ALLOW_HEX | ALLOW_OCTALS)));
+  CHECK(isnan(StringToDouble(&uc, "07.8", ALLOW_HEX | ALLOW_OCTALS)));
+  CHECK(isnan(StringToDouble(&uc, "07e8", ALLOW_HEX | ALLOW_OCTALS)));
+  CHECK(isnan(StringToDouble(&uc, "07e7", ALLOW_HEX | ALLOW_OCTALS)));
 
-  CHECK_EQ(8.7, StringToDouble("08.7", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(8e7, StringToDouble("08e7", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(8.7, StringToDouble(&uc, "08.7", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(8e7, StringToDouble(&uc, "08e7", ALLOW_HEX | ALLOW_OCTALS));
 
-  CHECK_EQ(0.001, StringToDouble("0.001", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.713, StringToDouble("0.713", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.001, StringToDouble(&uc, "0.001", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.713, StringToDouble(&uc, "0.713", ALLOW_HEX | ALLOW_OCTALS));
 
-  CHECK_EQ(8.0, StringToDouble("08", ALLOW_HEX));
-  CHECK_EQ(81.0, StringToDouble("081", ALLOW_HEX));
-  CHECK_EQ(78.0, StringToDouble("078", ALLOW_HEX));
+  CHECK_EQ(8.0, StringToDouble(&uc, "08", ALLOW_HEX));
+  CHECK_EQ(81.0, StringToDouble(&uc, "081", ALLOW_HEX));
+  CHECK_EQ(78.0, StringToDouble(&uc, "078", ALLOW_HEX));
 
-  CHECK_EQ(7.7, StringToDouble("07.7", ALLOW_HEX));
-  CHECK_EQ(7.8, StringToDouble("07.8", ALLOW_HEX));
-  CHECK_EQ(7e8, StringToDouble("07e8", ALLOW_HEX));
-  CHECK_EQ(7e7, StringToDouble("07e7", ALLOW_HEX));
+  CHECK_EQ(7.7, StringToDouble(&uc, "07.7", ALLOW_HEX));
+  CHECK_EQ(7.8, StringToDouble(&uc, "07.8", ALLOW_HEX));
+  CHECK_EQ(7e8, StringToDouble(&uc, "07e8", ALLOW_HEX));
+  CHECK_EQ(7e7, StringToDouble(&uc, "07e7", ALLOW_HEX));
 
-  CHECK_EQ(8.7, StringToDouble("08.7", ALLOW_HEX));
-  CHECK_EQ(8e7, StringToDouble("08e7", ALLOW_HEX));
+  CHECK_EQ(8.7, StringToDouble(&uc, "08.7", ALLOW_HEX));
+  CHECK_EQ(8e7, StringToDouble(&uc, "08e7", ALLOW_HEX));
 
-  CHECK_EQ(0.001, StringToDouble("0.001", ALLOW_HEX));
-  CHECK_EQ(0.713, StringToDouble("0.713", ALLOW_HEX));
+  CHECK_EQ(0.001, StringToDouble(&uc, "0.001", ALLOW_HEX));
+  CHECK_EQ(0.713, StringToDouble(&uc, "0.713", ALLOW_HEX));
 }
 
 
 TEST(TrailingJunk) {
-  CHECK_EQ(8.0, StringToDouble("8q", ALLOW_TRAILING_JUNK));
-  CHECK_EQ(63.0, StringToDouble("077qqq", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
-  CHECK_EQ(10.0, StringToDouble("10e", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
-  CHECK_EQ(10.0, StringToDouble("10e-", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+  UnicodeCache uc;
+  CHECK_EQ(8.0, StringToDouble(&uc, "8q", ALLOW_TRAILING_JUNK));
+  CHECK_EQ(63.0,
+           StringToDouble(&uc, "077qqq", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+  CHECK_EQ(10.0,
+           StringToDouble(&uc, "10e", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
+  CHECK_EQ(10.0,
+           StringToDouble(&uc, "10e-", ALLOW_OCTALS | ALLOW_TRAILING_JUNK));
 }
 
 
 TEST(NonStrDecimalLiteral) {
-  CHECK(isnan(StringToDouble(" ", NO_FLAGS, OS::nan_value())));
-  CHECK(isnan(StringToDouble("", NO_FLAGS, OS::nan_value())));
-  CHECK(isnan(StringToDouble(" ", NO_FLAGS, OS::nan_value())));
-  CHECK_EQ(0.0, StringToDouble("", NO_FLAGS));
-  CHECK_EQ(0.0, StringToDouble(" ", NO_FLAGS));
+  UnicodeCache uc;
+  CHECK(isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value())));
+  CHECK(isnan(StringToDouble(&uc, "", NO_FLAGS, OS::nan_value())));
+  CHECK(isnan(StringToDouble(&uc, " ", NO_FLAGS, OS::nan_value())));
+  CHECK_EQ(0.0, StringToDouble(&uc, "", NO_FLAGS));
+  CHECK_EQ(0.0, StringToDouble(&uc, " ", NO_FLAGS));
 }
 
 TEST(IntegerStrLiteral) {
-  CHECK_EQ(0.0, StringToDouble("0.0", NO_FLAGS));
-  CHECK_EQ(0.0, StringToDouble("0", NO_FLAGS));
-  CHECK_EQ(0.0, StringToDouble("00", NO_FLAGS));
-  CHECK_EQ(0.0, StringToDouble("000", NO_FLAGS));
-  CHECK_EQ(1.0, StringToDouble("1", NO_FLAGS));
-  CHECK_EQ(-1.0, StringToDouble("-1", NO_FLAGS));
-  CHECK_EQ(-1.0, StringToDouble("  -1  ", NO_FLAGS));
-  CHECK_EQ(1.0, StringToDouble("  +1  ", NO_FLAGS));
-  CHECK(isnan(StringToDouble("  -  1  ", NO_FLAGS)));
-  CHECK(isnan(StringToDouble("  +  1  ", NO_FLAGS)));
+  UnicodeCache uc;
+  CHECK_EQ(0.0, StringToDouble(&uc, "0.0", NO_FLAGS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0", NO_FLAGS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "00", NO_FLAGS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "000", NO_FLAGS));
+  CHECK_EQ(1.0, StringToDouble(&uc, "1", NO_FLAGS));
+  CHECK_EQ(-1.0, StringToDouble(&uc, "-1", NO_FLAGS));
+  CHECK_EQ(-1.0, StringToDouble(&uc, "  -1  ", NO_FLAGS));
+  CHECK_EQ(1.0, StringToDouble(&uc, "  +1  ", NO_FLAGS));
+  CHECK(isnan(StringToDouble(&uc, "  -  1  ", NO_FLAGS)));
+  CHECK(isnan(StringToDouble(&uc, "  +  1  ", NO_FLAGS)));
 
-  CHECK_EQ(0.0, StringToDouble("0e0", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.0, StringToDouble("0e1", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.0, StringToDouble("0e-1", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.0, StringToDouble("0e-100000", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.0, StringToDouble("0e+100000", ALLOW_HEX | ALLOW_OCTALS));
-  CHECK_EQ(0.0, StringToDouble("0.", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0e0", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0e1", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0e-1", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0e-100000", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0e+100000", ALLOW_HEX | ALLOW_OCTALS));
+  CHECK_EQ(0.0, StringToDouble(&uc, "0.", ALLOW_HEX | ALLOW_OCTALS));
 }
 
 TEST(LongNumberStr) {
-  CHECK_EQ(1e10, StringToDouble("1" "0000000000", NO_FLAGS));
-  CHECK_EQ(1e20, StringToDouble("1" "0000000000" "0000000000", NO_FLAGS));
+  UnicodeCache uc;
+  CHECK_EQ(1e10, StringToDouble(&uc, "1" "0000000000", NO_FLAGS));
+  CHECK_EQ(1e20, StringToDouble(&uc, "1" "0000000000" "0000000000", NO_FLAGS));
 
-  CHECK_EQ(1e60, StringToDouble("1" "0000000000" "0000000000" "0000000000"
+  CHECK_EQ(1e60, StringToDouble(&uc, "1" "0000000000" "0000000000" "0000000000"
       "0000000000" "0000000000" "0000000000", NO_FLAGS));
 
-  CHECK_EQ(1e-2, StringToDouble("." "0" "1", NO_FLAGS));
-  CHECK_EQ(1e-11, StringToDouble("." "0000000000" "1", NO_FLAGS));
-  CHECK_EQ(1e-21, StringToDouble("." "0000000000" "0000000000" "1", NO_FLAGS));
+  CHECK_EQ(1e-2, StringToDouble(&uc, "." "0" "1", NO_FLAGS));
+  CHECK_EQ(1e-11, StringToDouble(&uc, "." "0000000000" "1", NO_FLAGS));
+  CHECK_EQ(1e-21, StringToDouble(&uc, "." "0000000000" "0000000000" "1",
+                                 NO_FLAGS));
 
-  CHECK_EQ(1e-61, StringToDouble("." "0000000000" "0000000000" "0000000000"
+  CHECK_EQ(1e-61, StringToDouble(&uc, "." "0000000000" "0000000000" "0000000000"
       "0000000000" "0000000000" "0000000000" "1", NO_FLAGS));
 
 
   // x = 24414062505131248.0 and y = 24414062505131252.0 are representable in
   // double. Check chat z = (x + y) / 2 is rounded to x...
   CHECK_EQ(24414062505131248.0,
-           StringToDouble("24414062505131250.0", NO_FLAGS));
+           StringToDouble(&uc, "24414062505131250.0", NO_FLAGS));
 
   // ... and z = (x + y) / 2 + delta is rounded to y.
   CHECK_EQ(24414062505131252.0,
-           StringToDouble("24414062505131250.000000001", NO_FLAGS));
+           StringToDouble(&uc, "24414062505131250.000000001", NO_FLAGS));
 }
 
 
 TEST(MaximumSignificantDigits) {
+  UnicodeCache uc;
   char num[] =
       "4.4501477170144020250819966727949918635852426585926051135169509"
       "122872622312493126406953054127118942431783801370080830523154578"
@@ -159,15 +171,16 @@
       "847003580761626016356864581135848683152156368691976240370422601"
       "6998291015625000000000000000000000000000000000e-308";
 
-  CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(num, NO_FLAGS));
+  CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(&uc, num, NO_FLAGS));
 
   // Changes the result of strtod (at least in glibc implementation).
   num[sizeof(num) - 8] = '1';
 
-  CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(num, NO_FLAGS));
+  CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(&uc, num, NO_FLAGS));
 }
 
 TEST(MinimumExponent) {
+  UnicodeCache uc;
   // Same test but with different point-position.
   char num[] =
   "445014771701440202508199667279499186358524265859260511351695091"
@@ -184,29 +197,31 @@
   "470035807616260163568645811358486831521563686919762403704226016"
   "998291015625000000000000000000000000000000000e-1108";
 
-  CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(num, NO_FLAGS));
+  CHECK_EQ(4.4501477170144017780491e-308, StringToDouble(&uc, num, NO_FLAGS));
 
   // Changes the result of strtod (at least in glibc implementation).
   num[sizeof(num) - 8] = '1';
 
-  CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(num, NO_FLAGS));
+  CHECK_EQ(4.4501477170144022721148e-308, StringToDouble(&uc, num, NO_FLAGS));
 }
 
 
 TEST(MaximumExponent) {
+  UnicodeCache uc;
   char num[] = "0.16e309";
 
-  CHECK_EQ(1.59999999999999997765e+308, StringToDouble(num, NO_FLAGS));
+  CHECK_EQ(1.59999999999999997765e+308, StringToDouble(&uc, num, NO_FLAGS));
 }
 
 
 TEST(ExponentNumberStr) {
-  CHECK_EQ(1e1, StringToDouble("1e1", NO_FLAGS));
-  CHECK_EQ(1e1, StringToDouble("1e+1", NO_FLAGS));
-  CHECK_EQ(1e-1, StringToDouble("1e-1", NO_FLAGS));
-  CHECK_EQ(1e100, StringToDouble("1e+100", NO_FLAGS));
-  CHECK_EQ(1e-100, StringToDouble("1e-100", NO_FLAGS));
-  CHECK_EQ(1e-106, StringToDouble(".000001e-100", NO_FLAGS));
+  UnicodeCache uc;
+  CHECK_EQ(1e1, StringToDouble(&uc, "1e1", NO_FLAGS));
+  CHECK_EQ(1e1, StringToDouble(&uc, "1e+1", NO_FLAGS));
+  CHECK_EQ(1e-1, StringToDouble(&uc, "1e-1", NO_FLAGS));
+  CHECK_EQ(1e100, StringToDouble(&uc, "1e+100", NO_FLAGS));
+  CHECK_EQ(1e-100, StringToDouble(&uc, "1e-100", NO_FLAGS));
+  CHECK_EQ(1e-106, StringToDouble(&uc, ".000001e-100", NO_FLAGS));
 }
 
 class OneBit1: public BitField<uint32_t, 0, 1> {};
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 98a5870..39856b6 100755
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -258,14 +258,14 @@
       NULL
   };
 
-  uintptr_t stack_limit = ISOLATE->stack_guard()->real_climit();
+  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
   for (int i = 0; programs[i]; i++) {
     const char* program = programs[i];
     i::Utf8ToUC16CharacterStream stream(
         reinterpret_cast<const i::byte*>(program),
         static_cast<unsigned>(strlen(program)));
     i::CompleteParserRecorder log;
-    i::V8JavaScriptScanner scanner(ISOLATE->scanner_constants());
+    i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
     scanner.Initialize(&stream);
 
     v8::preparser::PreParser::PreParseResult result =
@@ -282,7 +282,7 @@
 
 TEST(RegressChromium62639) {
   int marker;
-  ISOLATE->stack_guard()->SetStackLimit(
+  i::Isolate::Current()->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
 
   const char* program = "var x = 'something';\n"
@@ -307,7 +307,7 @@
   // the block could be lazily compiled, and an extra, unexpected,
   // entry was added to the data.
   int marker;
-  ISOLATE->stack_guard()->SetStackLimit(
+  i::Isolate::Current()->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
 
   const char* program =
@@ -343,7 +343,7 @@
 
 TEST(PreParseOverflow) {
   int marker;
-  ISOLATE->stack_guard()->SetStackLimit(
+  i::Isolate::Current()->stack_guard()->SetStackLimit(
       reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
 
   size_t kProgramSize = 1024 * 1024;
@@ -352,13 +352,13 @@
   memset(*program, '(', kProgramSize);
   program[kProgramSize] = '\0';
 
-  uintptr_t stack_limit = ISOLATE->stack_guard()->real_climit();
+  uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
 
   i::Utf8ToUC16CharacterStream stream(
       reinterpret_cast<const i::byte*>(*program),
       static_cast<unsigned>(kProgramSize));
   i::CompleteParserRecorder log;
-  i::V8JavaScriptScanner scanner(ISOLATE->scanner_constants());
+  i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
   scanner.Initialize(&stream);
 
 
@@ -576,7 +576,7 @@
                        i::Token::Value* expected_tokens,
                        int skip_pos = 0,  // Zero means not skipping.
                        int skip_to = 0) {
-  i::V8JavaScriptScanner scanner(ISOLATE->scanner_constants());
+  i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
   scanner.Initialize(stream);
 
   int i = 0;
@@ -655,7 +655,7 @@
   i::Utf8ToUC16CharacterStream stream(
        reinterpret_cast<const i::byte*>(re_source),
        static_cast<unsigned>(strlen(re_source)));
-  i::V8JavaScriptScanner scanner(ISOLATE->scanner_constants());
+  i::V8JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
   scanner.Initialize(&stream);
 
   i::Token::Value start = scanner.peek();
diff --git a/test/cctest/test-threads.cc b/test/cctest/test-threads.cc
index 37f0205..c6d5cb0 100644
--- a/test/cctest/test-threads.cc
+++ b/test/cctest/test-threads.cc
@@ -28,6 +28,7 @@
 #include "v8.h"
 
 #include "platform.h"
+#include "isolate.h"
 
 #include "cctest.h"
 
@@ -136,3 +137,55 @@
 
   CHECK_EQ(DONE, turn);
 }
+
+class ThreadIdValidationThread : public v8::internal::Thread {
+ public:
+  ThreadIdValidationThread(i::Thread* thread_to_start,
+                           i::List<i::ThreadId>* refs,
+                           unsigned int thread_no,
+                           i::Semaphore* semaphore)
+    : Thread(NULL, "ThreadRefValidationThread"),
+      refs_(refs), thread_no_(thread_no), thread_to_start_(thread_to_start),
+      semaphore_(semaphore) {
+  }
+
+  void Run() {
+    i::ThreadId thread_id = i::ThreadId::Current();
+    for (int i = 0; i < thread_no_; i++) {
+      CHECK(!(*refs_)[i].Equals(thread_id));
+    }
+    CHECK(thread_id.IsValid());
+    (*refs_)[thread_no_] = thread_id;
+    if (thread_to_start_ != NULL) {
+      thread_to_start_->Start();
+    }
+    semaphore_->Signal();
+  }
+ private:
+  i::List<i::ThreadId>* refs_;
+  int thread_no_;
+  i::Thread* thread_to_start_;
+  i::Semaphore* semaphore_;
+};
+
+TEST(ThreadIdValidation) {
+  const int kNThreads = 100;
+  i::List<ThreadIdValidationThread*> threads(kNThreads);
+  i::List<i::ThreadId> refs(kNThreads);
+  i::Semaphore* semaphore = i::OS::CreateSemaphore(0);
+  ThreadIdValidationThread* prev = NULL;
+  for (int i = kNThreads - 1; i >= 0; i--) {
+    ThreadIdValidationThread* newThread =
+        new ThreadIdValidationThread(prev, &refs, i, semaphore);
+    threads.Add(newThread);
+    prev = newThread;
+    refs.Add(i::ThreadId::Invalid());
+  }
+  prev->Start();
+  for (int i = 0; i < kNThreads; i++) {
+    semaphore->Wait();
+  }
+  for (int i = 0; i < kNThreads; i++) {
+    delete threads[i];
+  }
+}
diff --git a/test/mjsunit/compiler/array-length.js b/test/mjsunit/compiler/array-length.js
index 126c7a0..462a1e7 100644
--- a/test/mjsunit/compiler/array-length.js
+++ b/test/mjsunit/compiler/array-length.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 function ArrayLength(a) { return a.length; }
 
 function Test(a0, a2, a5) {
@@ -36,7 +38,12 @@
 var a0 = [];
 var a2 = [1,2];
 var a5 = [1,2,3,4,5];
-for (var i = 0; i < 100000; i++) Test(a0, a2, a5);
+for (var i = 0; i < 5; i++) Test(a0, a2, a5);
+%OptimizeFunctionOnNextCall(ArrayLength);
+%OptimizeFunctionOnNextCall(Test);
+Test(a0, a2, a5);
 assertEquals("undefined", typeof(ArrayLength(0)));
-for (var i = 0; i < 100000; i++) Test(a0, a2, a5);
+for (var i = 0; i < 5; i++) Test(a0, a2, a5);
+%OptimizeFunctionOnNextCall(Test);
+Test(a0, a2, a5);
 assertEquals(4, ArrayLength("hest"));
diff --git a/test/mjsunit/compiler/assignment-deopt.js b/test/mjsunit/compiler/assignment-deopt.js
index 74f185b..2b00625 100644
--- a/test/mjsunit/compiler/assignment-deopt.js
+++ b/test/mjsunit/compiler/assignment-deopt.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test deopt with count operation on parameter.
 var max_smi = 1073741823;
 var o = {x:0};
@@ -44,12 +46,15 @@
 assign2(o);
 assertEquals("421", o.x);
 
-var s = max_smi - 10000;
+var s = max_smi - 10;
 o.x = s;
-for(var i = 0; i < 20000; i++) {
+for(var i = 0; i < 20; i++) {
   assign2(o);
+  if (i == 4) {
+    %OptimizeFunctionOnNextCall(assign2);
+  }
 }
-assertEquals(max_smi + 10000, o.x);
+assertEquals(max_smi + 10, o.x);
 
 
 // Test deopt with count operation on keyed property.
@@ -59,36 +64,48 @@
 assign3(o, 0);
 assertEquals("421", o[0]);
 
-var s = max_smi - 10000;
+var s = max_smi - 10;
 o[0] = s;
-for(var i = 0; i < 20000; i++) {
+for(var i = 0; i < 20; i++) {
   assign3(o, 0);
+  if (i == 4) {
+    %OptimizeFunctionOnNextCall(assign3);
+  }
 }
-assertEquals(max_smi + 10000, o[0]);
+assertEquals(max_smi + 10, o[0]);
 
-assign3(o,"0");
+assign3(o, "0");
 
-assertEquals(max_smi + 10001, o[0]);
+assertEquals(max_smi + 11, o[0]);
 
 // Test bailout when accessing a non-existing array element.
 o[0] = 0;
-for(var i = 0; i < 10000; i++) {
+for(var i = 0; i < 5; i++) {
   assign3(o, 0);
 }
-assign3(o,1);
+%OptimizeFunctionOnNextCall(assign3);
+assign3(o, 0);
+assign3(o, 1);
 
 // Test bailout with count operation in a value context.
 function assign5(x,y) { return (x += 1) + y; }
-for (var i = 0; i < 10000; ++i) assertEquals(4, assign5(2, 1));
+for (var i = 0; i < 5; ++i) assertEquals(4, assign5(2, 1));
+%OptimizeFunctionOnNextCall(assign5);
+assertEquals(4, assign5(2, 1));
+
 assertEquals(4.1, assign5(2, 1.1));
 assertEquals(4.1, assign5(2.1, 1));
 
 function assign7(o,y) { return (o.x += 1) + y; }
 o = {x:0};
-for (var i = 0; i < 10000; ++i) {
+for (var i = 0; i < 5; ++i) {
   o.x = 42;
   assertEquals(44, assign7(o, 1));
 }
+%OptimizeFunctionOnNextCall(assign7);
+o.x = 42;
+assertEquals(44, assign7(o, 1));
+
 o.x = 42;
 assertEquals(44.1, assign7(o, 1.1));
 o.x = 42.1;
@@ -96,10 +113,14 @@
 
 function assign9(o,y) { return (o[0] += 1) + y; }
 q = [0];
-for (var i = 0; i < 10000; ++i) {
+for (var i = 0; i < 5; ++i) {
   q[0] = 42;
   assertEquals(44, assign9(q, 1));
 }
+%OptimizeFunctionOnNextCall(assign9);
+q[0] = 42;
+assertEquals(44, assign9(q, 1));
+
 q[0] = 42;
 assertEquals(44.1, assign9(q, 1.1));
 q[0] = 42.1;
@@ -109,11 +130,16 @@
 function assign10(p) { return p.x += 1 }
 var g1 = {x:0};
 var g2 = {y:0, x:42};
-for (var i = 0; i < 10000; ++i) {
+for (var i = 0; i < 5; ++i) {
   g1.x = 42;
   assertEquals(43, assign10(g1));
   assertEquals(43, g1.x);
 }
+%OptimizeFunctionOnNextCall(assign10);
+g1.x = 42;
+assertEquals(43, assign10(g1));
+assertEquals(43, g1.x);
+
 assertEquals(43, assign10(g2));
 assertEquals(43, g2.x);
 
@@ -123,10 +149,14 @@
 var g3 = { valueOf: function() { o.y = "bar"; return 42; }};
 function assign11(p) { return p.x += 1; }
 
-for (var i = 0; i < 10000; i++) {
+for (var i = 0; i < 5; i++) {
   o.x = "a";
   assign11(o);
 }
+%OptimizeFunctionOnNextCall(assign11);
+o.x = "a";
+assign11(o);
+
 assertEquals("a11", assign11(o));
 o.x = g3;
 assertEquals(43, assign11(o));
@@ -136,10 +166,14 @@
 var g4 = { valueOf: function() { o.y = "bar"; return 42; }};
 function assign12(p) { return p[0] += 1; }
 
-for (var i = 0; i < 1000000; i++) {
+for (var i = 0; i < 5; i++) {
   o[0] = "a";
   assign12(o);
 }
+%OptimizeFunctionOnNextCall(assign12);
+o[0] = "a";
+assign12(o);
+
 assertEquals("a11", assign12(o));
 o[0] = g4;
 assertEquals(43, assign12(o));
diff --git a/test/mjsunit/compiler/count-deopt.js b/test/mjsunit/compiler/count-deopt.js
index dcd82f8..415dadc 100644
--- a/test/mjsunit/compiler/count-deopt.js
+++ b/test/mjsunit/compiler/count-deopt.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test deopt with count operation on parameter.
 var max_smi = 1073741823;
 var o = {x:0};
@@ -44,12 +46,15 @@
 inc2(o);
 assertEquals(43, o.x);
 
-var s = max_smi - 10000;
+var s = max_smi - 10;
 o.x = s;
-for(var i = 0; i < 20000; i++) {
+for(var i = 0; i < 20; i++) {
   inc2(o);
+  if (i == 4) {
+    %OptimizeFunctionOnNextCall(inc2);
+  }
 }
-assertEquals(max_smi + 10000, o.x);
+assertEquals(max_smi + 10, o.x);
 
 
 // Test deopt with count operation on keyed property.
@@ -59,40 +64,52 @@
 inc3(o, 0);
 assertEquals(43, o[0]);
 
-var s = max_smi - 10000;
+var s = max_smi - 10;
 o[0] = s;
-for(var i = 0; i < 20000; i++) {
+for(var i = 0; i < 20; i++) {
   inc3(o, 0);
+  if (i == 4) {
+    %OptimizeFunctionOnNextCall(inc3);
+  }
 }
-assertEquals(max_smi + 10000, o[0]);
+assertEquals(max_smi + 10, o[0]);
 
 inc3(o,"0");
 
-assertEquals(max_smi + 10001, o[0]);
+assertEquals(max_smi + 11, o[0]);
 
 // Test bailout when accessing a non-existing array element.
 o[0] = 0;
-for(var i = 0; i < 10000; i++) {
+for(var i = 0; i < 5; i++) {
   inc3(o, 0);
 }
-inc3(o,1);
+%OptimizeFunctionOnNextCall(inc3);
+inc3(o, 0);
+inc3(o, 1);
 
 // Test bailout with count operation in a value context.
 function inc4(x,y) { return (x++) + y; }
-for (var i = 0; i < 100000; ++i) assertEquals(3, inc4(2, 1));
+for (var i = 0; i < 5; ++i) assertEquals(3, inc4(2, 1));
+%OptimizeFunctionOnNextCall(inc4);
+inc4(2, 1);
 assertEquals(3.1, inc4(2, 1.1));
 
 function inc5(x,y) { return (++x) + y; }
-for (var i = 0; i < 100000; ++i) assertEquals(4, inc5(2, 1));
+for (var i = 0; i < 5; ++i) assertEquals(4, inc5(2, 1));
+%OptimizeFunctionOnNextCall(inc5);
+assertEquals(4, inc5(2, 1));
 assertEquals(4.1, inc5(2, 1.1));
 assertEquals(4.1, inc5(2.1, 1));
 
 function inc6(o,y) { return (o.x++) + y; }
 o = {x:0};
-for (var i = 0; i < 10000; ++i) {
+for (var i = 0; i < 5; ++i) {
   o.x = 42;
   assertEquals(43, inc6(o, 1));
 }
+%OptimizeFunctionOnNextCall(inc6);
+o.x = 42;
+assertEquals(43, inc6(o, 1));
 o.x = 42;
 assertEquals(43.1, inc6(o, 1.1));
 o.x = 42.1;
@@ -100,10 +117,13 @@
 
 function inc7(o,y) { return (++o.x) + y; }
 o = {x:0};
-for (var i = 0; i < 10000; ++i) {
+for (var i = 0; i < 5; ++i) {
   o.x = 42;
   assertEquals(44, inc7(o, 1));
 }
+%OptimizeFunctionOnNextCall(inc7);
+o.x = 42;
+assertEquals(44, inc7(o, 1));
 o.x = 42;
 assertEquals(44.1, inc7(o, 1.1));
 o.x = 42.1;
@@ -111,10 +131,13 @@
 
 function inc8(o,y) { return (o[0]++) + y; }
 var q = [0];
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 5; ++i) {
   q[0] = 42;
   assertEquals(43, inc8(q, 1));
 }
+%OptimizeFunctionOnNextCall(inc8);
+q[0] = 42;
+assertEquals(43, inc8(q, 1));
 q[0] = 42;
 assertEquals(43.1, inc8(q, 1.1));
 q[0] = 42.1;
@@ -122,10 +145,13 @@
 
 function inc9(o,y) { return (++o[0]) + y; }
 q = [0];
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 5; ++i) {
   q[0] = 42;
   assertEquals(44, inc9(q, 1));
 }
+%OptimizeFunctionOnNextCall(inc9);
+q[0] = 42;
+assertEquals(44, inc9(q, 1));
 q[0] = 42;
 assertEquals(44.1, inc9(q, 1.1));
 q[0] = 42.1;
@@ -135,11 +161,15 @@
 function inc10(p) { return p.x++ }
 var g1 = {x:0};
 var g2 = {y:0, x:42}
-for (var i = 0; i < 10000; ++i) {
+for (var i = 0; i < 5; ++i) {
   g1.x = 42;
   assertEquals(42, inc10(g1));
   assertEquals(43, g1.x);
 }
+%OptimizeFunctionOnNextCall(inc10);
+g1.x = 42;
+assertEquals(42, inc10(g1));
+assertEquals(43, g1.x);
 assertEquals(42, inc10(g2));
 assertEquals(43, g2.x);
 
diff --git a/test/mjsunit/compiler/deopt-args.js b/test/mjsunit/compiler/deopt-args.js
index 780e2a2..17c397c 100644
--- a/test/mjsunit/compiler/deopt-args.js
+++ b/test/mjsunit/compiler/deopt-args.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 function g(x) {
   return x.f(0,1,2);
 }
@@ -35,9 +37,11 @@
 
 var object = { };
 object.f = f;
-for (var i = 0; i < 10000000; i++) {
+for (var i = 0; i < 5; i++) {
   assertEquals(42, g(object));
 }
+%OptimizeFunctionOnNextCall(g);
+g(object);
 
 object.f = function(a,b,c) { return 87; };
 assertEquals(87, g(object));
diff --git a/test/mjsunit/compiler/inline-compare.js b/test/mjsunit/compiler/inline-compare.js
index 6efe154..d97dce2 100644
--- a/test/mjsunit/compiler/inline-compare.js
+++ b/test/mjsunit/compiler/inline-compare.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test that we can inline a function that returns the result of
 // a compare operation.
 function TestInlineCompare(o) {
@@ -42,5 +44,7 @@
 
 var o = {};
 o.f = function() { return 0 === 1; };
-for (var i = 0; i < 10000000; i++) TestInlineCompare(o);
+for (var i = 0; i < 5; i++) TestInlineCompare(o);
+%OptimizeFunctionOnNextCall(TestInlineCompare);
+TestInlineCompare(o);
 TestInlineCompare({f: o.f});
diff --git a/test/mjsunit/compiler/inline-global-access.js b/test/mjsunit/compiler/inline-global-access.js
index 3795173..b52652a 100644
--- a/test/mjsunit/compiler/inline-global-access.js
+++ b/test/mjsunit/compiler/inline-global-access.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test that we can inline a function that returns the result of a
 // global variable load.
 var GLOBAL;
@@ -45,5 +47,7 @@
 
 var o = {};
 o.f = function() { return GLOBAL; };
-for (var i = 0; i < 10000000; i++) TestInlineGlobalLoad(o);
+for (var i = 0; i < 5; i++) TestInlineGlobalLoad(o);
+%OptimizeFunctionOnNextCall(TestInlineGlobalLoad);
+TestInlineGlobalLoad(o);
 TestInlineGlobalLoad({f: o.f});
diff --git a/test/mjsunit/compiler/inline-param.js b/test/mjsunit/compiler/inline-param.js
index 8e0933a..8fa8008 100644
--- a/test/mjsunit/compiler/inline-param.js
+++ b/test/mjsunit/compiler/inline-param.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test that we can inline a call with a parameter.
 function TestInlineOneParam(o, p) {
   // Effect context.
@@ -42,7 +44,9 @@
 var obj = {x:42};
 var o1 = {};
 o1.f = function(o) { return o.x; };
-for (var i = 0; i < 10000; i++) TestInlineOneParam(o1, obj);
+for (var i = 0; i < 5; i++) TestInlineOneParam(o1, obj);
+%OptimizeFunctionOnNextCall(TestInlineOneParam);
+TestInlineOneParam(o1, obj);
 TestInlineOneParam({f: o1.f}, {x:42});
 
 
@@ -76,5 +80,7 @@
 
 var o2 = {};
 o2.h = function(i, j) { return i < j; };
-for (var i = 0; i < 10000; i++) TestInlineTwoParams(o2, 42);
+for (var i = 0; i < 5; i++) TestInlineTwoParams(o2, 42);
+%OptimizeFunctionOnNextCall(TestInlineTwoParams);
+TestInlineTwoParams(o2, 42);
 TestInlineTwoParams({h: o2.h}, 42);
diff --git a/test/mjsunit/compiler/inline-two.js b/test/mjsunit/compiler/inline-two.js
index 30f579d..68372a9 100644
--- a/test/mjsunit/compiler/inline-two.js
+++ b/test/mjsunit/compiler/inline-two.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test that we can inline a function that calls another function.
 function TestInlineX(o) {
   // Effect context.
@@ -42,7 +44,9 @@
 var o2 = {};
 o2.size = function() { return 42; }
 o2.g = function() { return this.size(); };
-for (var i = 0; i < 10000; i++) TestInlineX(o2);
+for (var i = 0; i < 5; i++) TestInlineX(o2);
+%OptimizeFunctionOnNextCall(TestInlineX);
+TestInlineX(o2);
 TestInlineX({g: o2.g, size:o2.size});
 
 
@@ -65,7 +69,9 @@
 var o3 = {};
 o3.v = obj;
 o3.h = function() { return this.v.foo(); };
-for (var i = 0; i < 10000; i++) TestInlineX2(o3);
+for (var i = 0; i < 5; i++) TestInlineX2(o3);
+%OptimizeFunctionOnNextCall(TestInlineX2);
+TestInlineX2(o3);
 TestInlineX2({h: o3.h, v:obj});
 
 
@@ -89,5 +95,7 @@
 o3.v = obj;
 o3.f = function() { return this.v; }
 o3.h = function() { return this.f().g(); };
-for (var i = 0; i < 10000; i++) TestInlineFG(o3);
+for (var i = 0; i < 5; i++) TestInlineFG(o3);
+%OptimizeFunctionOnNextCall(TestInlineFG);
+TestInlineFG(o3);
 TestInlineFG({h: o3.h, f: o3.f, v:obj});
diff --git a/test/mjsunit/compiler/optimized-function-calls.js b/test/mjsunit/compiler/optimized-function-calls.js
index 1b5f3b0..c3e69d7 100644
--- a/test/mjsunit/compiler/optimized-function-calls.js
+++ b/test/mjsunit/compiler/optimized-function-calls.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --expose-gc
+// Flags: --allow-natives-syntax --expose-gc
 
 function f() {
   gc();
@@ -48,7 +48,9 @@
 function call_f(o) {
   return o.f();
 }
-for (var i = 0; i < 10000000; i++) call_f(object);
+for (var i = 0; i < 5; i++) call_f(object);
+%OptimizeFunctionOnNextCall(call_f);
+call_f(object);
 
 
 // Check that nested global function calls work.
diff --git a/test/mjsunit/compiler/pic.js b/test/mjsunit/compiler/pic.js
index 06f2b3e..f5b136c 100644
--- a/test/mjsunit/compiler/pic.js
+++ b/test/mjsunit/compiler/pic.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 function GetX(o) { return o.x; }
 function CallF(o) { return o.f(); }
 function SetX(o) { o.x = 42; }
@@ -53,11 +55,15 @@
 
 // Run the test until we're fairly sure we've optimized the
 // polymorphic property access.
-for (var i = 0; i < 100000; i++) {
+for (var i = 0; i < 5; i++) {
   Test(o1);
   Test(o2);
   Test(o3);
 }
+%OptimizeFunctionOnNextCall(Test);
+Test(o1);
+Test(o2);
+Test(o3);
 
 // Make sure that the following doesn't crash.
 GetX(0);
diff --git a/test/mjsunit/compiler/property-calls.js b/test/mjsunit/compiler/property-calls.js
index 3366971..ad5ca81 100644
--- a/test/mjsunit/compiler/property-calls.js
+++ b/test/mjsunit/compiler/property-calls.js
@@ -25,12 +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.
 
+// Flags: --allow-natives-syntax
+
 function f(o) { return o.g(); }
 function g() { return 42; }
 
 var object = { };
 object.g = g;
-for (var i = 0; i < 10000000; i++) f(object);
+for (var i = 0; i < 5; i++) f(object);
+%OptimizeFunctionOnNextCall(f);
+f(object);
 assertEquals(42, f(object));
 
 object = { g: function() { return 87; } };
diff --git a/test/mjsunit/compiler/property-refs.js b/test/mjsunit/compiler/property-refs.js
index 3f6f793..6f1f19f 100644
--- a/test/mjsunit/compiler/property-refs.js
+++ b/test/mjsunit/compiler/property-refs.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 function Load(o) {
   return o.outer.x | o.outer.inner.y;
 }
@@ -45,7 +47,9 @@
   return Load(object);
 }
 
-for (var i = 0; i < 10000; i++) LoadXY(i, i);
+for (var i = 0; i < 5; i++) LoadXY(i, i);
+%OptimizeFunctionOnNextCall(LoadXY);
+LoadXY(6, 6);
 assertEquals(42 | 87, LoadXY(42, 87));
 assertEquals(42 | 87, LoadXY(42, 87));
 assertEquals(42 | 99, LoadXY(42, "99"));
diff --git a/test/mjsunit/compiler/property-stores.js b/test/mjsunit/compiler/property-stores.js
index 0dec82a..4ffac07 100644
--- a/test/mjsunit/compiler/property-stores.js
+++ b/test/mjsunit/compiler/property-stores.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 var a = 42;
 
 var obj = {x: 0,
@@ -33,11 +35,17 @@
            h: function() { this.x = a; }};
 
 var i;
-for (i = 0; i < 10000; i++) { obj.f(); }
+for (i = 0; i < 5; i++) { obj.f(); }
+%OptimizeFunctionOnNextCall(obj.f);
+obj.f();
 assertEquals(7, obj.x);
 
-for (i = 0; i < 10000; i++) { obj.g(); }
+for (i = 0; i < 5; i++) { obj.g(); }
+%OptimizeFunctionOnNextCall(obj.g);
+obj.g();
 assertEquals(43, obj.x);
 
-for (i = 0; i < 10000; i++) { obj.h(); }
+for (i = 0; i < 5; i++) { obj.h(); }
+%OptimizeFunctionOnNextCall(obj.h);
+obj.h();
 assertEquals(42, obj.x);
diff --git a/test/mjsunit/compiler/recursive-deopt.js b/test/mjsunit/compiler/recursive-deopt.js
index 366f59a..c921ade 100644
--- a/test/mjsunit/compiler/recursive-deopt.js
+++ b/test/mjsunit/compiler/recursive-deopt.js
@@ -25,6 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
 
 function f(n) {
   // Force deopt in both leaf case and when returning. To make
@@ -34,15 +35,11 @@
   return f(n - 1) << one;
 }
 
-function RunTests() {
-  assertEquals(1 << 1, f(0));
-  assertEquals(1 << 2, f(1));
-  assertEquals(1 << 5, f(4));
-}
-
 
 var one = 1;
-for (var i = 0; i < 1000000; i++) RunTests();
+for (var i = 0; i < 5; i++) assertEquals(1 << 5, f(4));
+%OptimizeFunctionOnNextCall(f);
+assertEquals(1 << 5, f(4));
 
 var one = { valueOf: function() { return 1; } };
-for (var j = 0; j < 100000; j++) RunTests();
+assertEquals(1 << 5, f(4));
diff --git a/test/mjsunit/compiler/regress-3218915.js b/test/mjsunit/compiler/regress-3218915.js
index d27c319..dfce815 100644
--- a/test/mjsunit/compiler/regress-3218915.js
+++ b/test/mjsunit/compiler/regress-3218915.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Regression test for failure to deoptimize properly when the most recent
 // side effect occurred in a comma expression in an effect context.
 
@@ -40,7 +42,9 @@
 function test(x) { return observe(this, ((0, side_effect()), x + 1)); }
 
 // Run test enough times to get it optimized.
-for (var i = 0; i < 1000000; ++i) test(0);
+for (var i = 0; i < 5; ++i) test(0);
+%OptimizeFunctionOnNextCall(test);
+test(0);
 
 // Force test to deopt.  If it behaves normally, it should return the global
 // object.  If the value of the call to side_effect() is lingering after the
diff --git a/test/mjsunit/compiler/regress-loadfield.js b/test/mjsunit/compiler/regress-loadfield.js
index a202891..a3da156 100644
--- a/test/mjsunit/compiler/regress-loadfield.js
+++ b/test/mjsunit/compiler/regress-loadfield.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Regression test for GVN on field loads.
 
 function bar() {}
@@ -58,8 +60,10 @@
 a.p10 = "";
 a.p11 = "";
 a.foo = "foo";
-for (var i = 0; i < 100000; i++) {
+for (var i = 0; i < 5; i++) {
  test(a);
 }
+%OptimizeFunctionOnNextCall(test);
+test(a);
 
 test("");
diff --git a/test/mjsunit/compiler/regress-max.js b/test/mjsunit/compiler/regress-max.js
index 94c543a..ee2fd58 100644
--- a/test/mjsunit/compiler/regress-max.js
+++ b/test/mjsunit/compiler/regress-max.js
@@ -25,10 +25,12 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --allow-natives-syntax
+
 // Test Math.max with negative zero as input.
-function f(x, y) { return Math.max(x, y) }
+for (var i = 0; i < 5; i++) Math.max(0, 0);
+%OptimizeFunctionOnNextCall(Math.max);
+Math.max(0, 0);
 
-for (var i = 0; i < 1000000; i++) f(0, 0);
-
-var r = f(-0, -0);
+var r = Math.max(-0, -0);
 assertEquals(-Infinity, 1 / r);
diff --git a/test/mjsunit/compiler/regress-stacktrace-methods.js b/test/mjsunit/compiler/regress-stacktrace-methods.js
index 4900ccf..4d28727 100644
--- a/test/mjsunit/compiler/regress-stacktrace-methods.js
+++ b/test/mjsunit/compiler/regress-stacktrace-methods.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test stack traces with method calls.
 function Hest() {}
 function Svin() {}
@@ -39,9 +41,12 @@
 var s = new Svin();
 var v = 0;
 
-for (var i = 0; i < 1000000; i++) {
+for (var i = 0; i < 5; i++) {
   o.one(s);
 }
+%OptimizeFunctionOnNextCall(Hest.prototype.one);
+%OptimizeFunctionOnNextCall(Hest.prototype.three);
+o.one(s);
 
 v = 42;
 
@@ -57,8 +62,8 @@
   assertTrue(p1 != -1);
   assertTrue(p3 < p2);
   assertTrue(p2 < p1);
-  assertTrue(stack.indexOf("36:56") != -1);
-  assertTrue(stack.indexOf("32:51") != -1);
-  assertTrue(stack.indexOf("34:38") != -1);
-  assertTrue(stack.indexOf("49:5") != -1);
+  assertTrue(stack.indexOf("38:56") != -1);
+  assertTrue(stack.indexOf("34:51") != -1);
+  assertTrue(stack.indexOf("36:38") != -1);
+  assertTrue(stack.indexOf("54:5") != -1);
 }
diff --git a/test/mjsunit/compiler/simple-deopt.js b/test/mjsunit/compiler/simple-deopt.js
index 8befd9f..7f985ac 100644
--- a/test/mjsunit/compiler/simple-deopt.js
+++ b/test/mjsunit/compiler/simple-deopt.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 function f(x) {
   return ~x;
 }
@@ -59,7 +61,9 @@
 function k(o) {
   return o.g();
 }
-for (var i = 0; i < 1000000; i++) k(obj);
+for (var i = 0; i < 5; i++) k(obj);
+%OptimizeFunctionOnNextCall(k);
+k(obj);
 assertEquals(42, k(obj));
 assertEquals(87, k({g: function() { return 87; }}));
 
@@ -88,9 +92,11 @@
 var str = "abc";
 var r;
 function CallCharAt(n) { return str.charAt(n); }
-for (var i = 0; i < 1000000; i++) {
+for (var i = 0; i < 5; i++) {
   r = CallCharAt(0);
 }
+%OptimizeFunctionOnNextCall(CallCharAt);
+r = CallCharAt(0);
 assertEquals("a", r);
 
 
diff --git a/test/mjsunit/compiler/simple-inlining.js b/test/mjsunit/compiler/simple-inlining.js
index 219580f..8bd37ea 100644
--- a/test/mjsunit/compiler/simple-inlining.js
+++ b/test/mjsunit/compiler/simple-inlining.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test that we can inline a function that returns a constant.
 function TestInlineConstant(o) {
   // Effect context.
@@ -41,7 +43,9 @@
 
 var o1 = {};
 o1.f = function() { return 42; };
-for (var i = 0; i < 10000; i++) TestInlineConstant(o1);
+for (var i = 0; i < 5; i++) TestInlineConstant(o1);
+%OptimizeFunctionOnNextCall(TestInlineConstant);
+TestInlineConstant(o1);
 TestInlineConstant({f: o1.f});
 
 
@@ -61,7 +65,9 @@
 
 var o2 = {};
 o2.g = function() { return this; };
-for (var i = 0; i < 10000; i++) TestInlineThis(o2);
+for (var i = 0; i < 5; i++) TestInlineThis(o2);
+%OptimizeFunctionOnNextCall(TestInlineThis);
+TestInlineThis(o2);
 TestInlineThis({g: o2.g});
 
 
@@ -81,7 +87,9 @@
 
 var o3 = {y:0,x:42};
 o3.h = function() { return this.x; };
-for (var i = 0; i < 10000; i++) TestInlineThisX(o3);
+for (var i = 0; i < 5; i++) TestInlineThisX(o3);
+%OptimizeFunctionOnNextCall(TestInlineThisX);
+TestInlineThisX(o3);
 TestInlineThisX({h: o3.h, x:42});
 
 
@@ -101,7 +109,9 @@
 
 var o4 = {x:[1,2,3]};
 o4.h = function() { return this.x.length; };
-for (var i = 0; i < 10000; i++) TestInlineThisXLength(o4);
+for (var i = 0; i < 5; i++) TestInlineThisXLength(o4);
+%OptimizeFunctionOnNextCall(TestInlineThisXLength);
+TestInlineThisXLength(o4);
 TestInlineThisXLength({h: o4.h, x:[1,2,3]});
 
 
@@ -122,7 +132,9 @@
 var o6 = {y:42}
 var o5 = {e:o6};
 o5.h = function() { return this.e.y; };
-for (var i = 0; i < 10000; i++) TestInlineThisXY(o5);
+for (var i = 0; i < 5; i++) TestInlineThisXY(o5);
+%OptimizeFunctionOnNextCall(TestInlineThisXY);
+TestInlineThisXY(o5);
 TestInlineThisXY({h: o5.h, e:o6});
 
 
@@ -142,5 +154,7 @@
 
 var o7 = {x:[42,43,44]};
 o7.foo = function() { return this.x[0]; };
-for (var i = 0; i < 10000; i++) TestInlineThisX0(o7);
+for (var i = 0; i < 5; i++) TestInlineThisX0(o7);
+%OptimizeFunctionOnNextCall(TestInlineThisX0);
+TestInlineThisX0(o7);
 TestInlineThisX0({foo: o7.foo, x:[42,0,0]});
diff --git a/test/mjsunit/compiler/switch-bailout.js b/test/mjsunit/compiler/switch-bailout.js
index 8011d44..084074e 100644
--- a/test/mjsunit/compiler/switch-bailout.js
+++ b/test/mjsunit/compiler/switch-bailout.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test that bailing out of the optimized compilation doesn't mess with
 // the labels in the AST.
 function f(x) {
@@ -35,5 +37,7 @@
   return 99;
 }
 
-for (var i = 0; i < 10000; i++) f("foo");
+for (var i = 0; i < 5; i++) f("foo");
+%OptimizeFunctionOnNextCall(f);
+f("foo");
 assertEquals(42, f("bar"));
diff --git a/test/mjsunit/const-eval-init.js b/test/mjsunit/const-eval-init.js
index 3f380d9..d350384 100644
--- a/test/mjsunit/const-eval-init.js
+++ b/test/mjsunit/const-eval-init.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test the handling of initialization of deleted const variables.
 // This only makes sense in local scopes since the declaration and
 // initialization of consts in the global scope happen at the same
@@ -67,9 +69,11 @@
   assertEquals(7, x);
 }
 
-for (var i = 0; i < 10000; i++) {
+for (var i = 0; i < 5; i++) {
   testAssignmentArgument();
 }
+%OptimizeFunctionOnNextCall(testAssignmentArgument);
+testAssignmentArgument();
 assertEquals(6, x);
 
 __defineSetter__('x', function() { throw 42; });
diff --git a/test/mjsunit/external-array.js b/test/mjsunit/external-array.js
index 228e8f0..45d8be5 100644
--- a/test/mjsunit/external-array.js
+++ b/test/mjsunit/external-array.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // This is a regression test for overlapping key and value registers.
 function f(a) {
   a[0] = 0;
@@ -32,9 +34,11 @@
 }
 
 var a = new Int32Array(2);
-for (var i = 0; i < 1000000; i++) {
+for (var i = 0; i < 5; i++) {
   f(a);
 }
+%OptimizeFunctionOnNextCall(f);
+f(a);
 
 assertEquals(0, a[0]);
 assertEquals(0, a[1]);
diff --git a/test/mjsunit/regress/regress-1079.js b/test/mjsunit/regress/regress-1079.js
index f3f3ce5..208dc5b 100644
--- a/test/mjsunit/regress/regress-1079.js
+++ b/test/mjsunit/regress/regress-1079.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Getting the arguments property of an optimized function should not crash,
 // even if called through our optimized version of Function.prototype.apply.
 
@@ -39,7 +41,8 @@
   }
 }
 
-for (var i = 0; i < 100000; ++i) {
+for (var i = 0; i < 5; ++i) {
   assertEquals(3, optimized(1, 2, 3).length);
 }
-
+%OptimizeFunctionOnNextCall(optimized);
+assertEquals(3, optimized(1, 2, 3).length);
diff --git a/test/mjsunit/regress/regress-1106.js b/test/mjsunit/regress/regress-1106.js
index 382fd1b..e462d5d 100644
--- a/test/mjsunit/regress/regress-1106.js
+++ b/test/mjsunit/regress/regress-1106.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Test for issue 1106, where the optimizing compiler broke when accessing
 // a property lying on a prototype of the global object, and that prototype
 // object was in dictionary mode.
@@ -37,14 +39,18 @@
 
 function f() { return foo; }
 
-for (i=0 ; i < 100000; ++i) {
+for (i=0 ; i < 5; ++i) {
   assertEquals(5, f());
 }
+%OptimizeFunctionOnNextCall(f);
+assertEquals(5, f());
 
 // Test calls on functions defined in the prototype of the global object.
 x.gee = function() { return 42; }
 function g() { return gee(); }
 
-for (i=0 ; i < 100000; ++i) {
+for (i=0 ; i < 5; ++i) {
   assertEquals(42, g());
 }
+%OptimizeFunctionOnNextCall(g);
+assertEquals(42, g());
diff --git a/test/mjsunit/regress/regress-1166.js b/test/mjsunit/regress/regress-1166.js
index d75d397..8278aba 100644
--- a/test/mjsunit/regress/regress-1166.js
+++ b/test/mjsunit/regress/regress-1166.js
@@ -25,11 +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.
 
+// Flags: --allow-natives-syntax
+
 // Deoptimization after a short-circuit logical operation in an effect
 // context should not see the value of the expression.
 function observe(x, y) { return x; }
 
 function test(x) { return observe(1, ((false || false), x + 1)); }
 
-for (var i = 0; i < 10000000; ++i) test(0);
+for (var i = 0; i < 5; ++i) test(0);
+%OptimizeFunctionOnNextCall(test);
+test(0);
+
 test("a");
diff --git a/test/mjsunit/regress/regress-1167.js b/test/mjsunit/regress/regress-1167.js
index 8437d83..2206f3d 100644
--- a/test/mjsunit/regress/regress-1167.js
+++ b/test/mjsunit/regress/regress-1167.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Deoptimization after a logical not in an effect context should not see a
 // value for the logical not expression.
 function test0(n) {
@@ -68,5 +70,7 @@
                   x + 1));
 }
 
-for (var i = 0; i < 1000000; ++i) test2(0);
+for (var i = 0; i < 5; ++i) test2(0);
+%OptimizeFunctionOnNextCall(test2);
+test2(0);
 test2(test2);
diff --git a/test/mjsunit/regress/regress-1210.js b/test/mjsunit/regress/regress-1210.js
index 9c708a5..7d4735a 100644
--- a/test/mjsunit/regress/regress-1210.js
+++ b/test/mjsunit/regress/regress-1210.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Deoptimization of the key expression in an arguments access should see
 // the arguments object as the value of the receiver.
 
@@ -43,6 +45,8 @@
 
 // Run enough to optimize assuming global 'a' is a smi.
 for (var i = 0; i < 1000000; ++i) test(0);
+%OptimizeFunctionOnNextCall(test);
+test(0);
 
 a = "hello";
 test(0);
diff --git a/test/mjsunit/regress/regress-1229.js b/test/mjsunit/regress/regress-1229.js
index 4afb964..e16d278 100644
--- a/test/mjsunit/regress/regress-1229.js
+++ b/test/mjsunit/regress/regress-1229.js
@@ -56,11 +56,17 @@
   return f(local_y, local_z); /* f should be inlined into h */
 }
 
-for (var i = 0; i < 100000; i++) f(2, 3);
+for (var i = 0; i < 5; i++) f(2, 3);
+%OptimizeFunctionOnNextCall(f);
+f(2, 3);
 
-for (var i = 0; i < 100000; i++) g(3, 2);
+for (var i = 0; i < 5; i++) g(3, 2);
+%OptimizeFunctionOnNextCall(g);
+g(3, 2);
 
-for (var i = 0; i < 100000; i++) h(6, 4);
+for (var i = 0; i < 5; i++) h(6, 4);
+%OptimizeFunctionOnNextCall(h);
+h(6, 4);
 
 // Check that %_IsConstructCall returns correct value when inlined
 var NON_CONSTRUCT_MARKER = {};
@@ -76,4 +82,6 @@
   assertEquals(construct, CONSTRUCT_MARKER);
 }
 
-for (var i = 0; i < 100000; i++) new bar(1, 2, 3);
+for (var i = 0; i < 5; i++) new bar(1, 2, 3);
+%OptimizeFunctionOnNextCall(bar);
+bar(1, 2, 3);
diff --git a/test/mjsunit/regress/regress-1237.js b/test/mjsunit/regress/regress-1237.js
index f97f978..111df80 100644
--- a/test/mjsunit/regress/regress-1237.js
+++ b/test/mjsunit/regress/regress-1237.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Deoptimization after a conditional expression in an effect context should
 // not see the value of the expression.
 function observe(x, y) { return x; }
@@ -32,5 +34,8 @@
   return observe(1, ((x? observe(observe.prototype.x): 'c'), x + 1));
 }
 
-for (var i = 0; i < 10000000; ++i) test(0);
+for (var i = 0; i < 5; ++i) test(0);
+%OptimizeFunctionOnNextCall(test);
+test(0);
+
 test("a");
diff --git a/test/mjsunit/regress/regress-1323.js b/test/mjsunit/regress/regress-1323.js
new file mode 100644
index 0000000..552a48d
--- /dev/null
+++ b/test/mjsunit/regress/regress-1323.js
@@ -0,0 +1,50 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Regression test for load/store operating with wrong number of bits.
+function get(a, index) {
+  return a[index];
+}
+
+var a = new Float32Array(2);
+a[0] = 2.5;
+a[1] = 3.5;
+for (var i = 0; i < 5; i++) get(a, 0);
+%OptimizeFunctionOnNextCall(get);
+assertEquals(2.5, get(a, 0));
+assertEquals(3.5, get(a, 1));
+
+function set(a, index, value) {
+  a[index] = value;
+}
+for (var i = 0; i < 5; i++) set(a, 0, 4.5);
+%OptimizeFunctionOnNextCall(set);
+set(a, 0, 4.5);
+assertEquals(4.5, a[0]);
+assertEquals(3.5, a[1]);
diff --git a/test/mjsunit/regress/regress-3218915.js b/test/mjsunit/regress/regress-3218915.js
index 5fcbcec..4b08a6e 100644
--- a/test/mjsunit/regress/regress-3218915.js
+++ b/test/mjsunit/regress/regress-3218915.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 // Checks that comma expression in conditional context is processed correctly.
 
 function withCommaExpressionInConditional(x) {
@@ -36,7 +38,9 @@
   return (y = x + 1, y > 1) ? 'medium' : 'small';
 }
 
-for (var i = 0; i < 10000; i++) {
+for (var i = 0; i < 5; i++) {
   withCommaExpressionInConditional(i);
 }
+%OptimizeFunctionOnNextCall(withCommaExpressionInConditional);
+withCommaExpressionInConditional(i);
 withCommaExpressionInConditional("1")
diff --git a/test/mjsunit/regress/regress-962.js b/test/mjsunit/regress/regress-962.js
index f9f46e1..85ada0c 100644
--- a/test/mjsunit/regress/regress-962.js
+++ b/test/mjsunit/regress/regress-962.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 function L(scope) { this.s = new Object(); }
 
 L.prototype.c = function() { return true; }
@@ -50,4 +52,6 @@
 
 var ctx = new F;
 
-for (var i = 0; i < 10000; i++) ctx.foo();
+for (var i = 0; i < 5; i++) ctx.foo();
+%OptimizeFunctionOnNextCall(F.prototype.foo);
+ctx.foo();
diff --git a/test/mjsunit/string-charcodeat.js b/test/mjsunit/string-charcodeat.js
index f18d0a5..8be6a09 100644
--- a/test/mjsunit/string-charcodeat.js
+++ b/test/mjsunit/string-charcodeat.js
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 /**
  * @fileoverview Check all sorts of borderline cases for charCodeAt.
  */
@@ -159,9 +161,11 @@
   assertTrue(isNaN(str.charCodeAt(0x7fffffff)));
 }
 
-for (var i = 0; i < 100000; i++) {
+for (var i = 0; i < 5; i++) {
   ConsNotSmiIndex();
 }
+%OptimizeFunctionOnNextCall(ConsNotSmiIndex);
+ConsNotSmiIndex();
 
 
 for (var i = 0; i != 10; i++) {
@@ -222,6 +226,8 @@
   assertEquals(99, "c".x(0));
 }
 
-for (var i = 0; i < 10000; i++) {
+for (var i = 0; i < 5; i++) {
   directlyOnPrototype();
 }
+%OptimizeFunctionOnNextCall(directlyOnPrototype);
+directlyOnPrototype();
diff --git a/test/mjsunit/sum-0-plus-undefined-is-NaN.js b/test/mjsunit/sum-0-plus-undefined-is-NaN.js
index fb98d0c..5d662d1 100644
--- a/test/mjsunit/sum-0-plus-undefined-is-NaN.js
+++ b/test/mjsunit/sum-0-plus-undefined-is-NaN.js
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -25,6 +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.
 
+// Flags: --allow-natives-syntax
+
 /**
  * @fileoverview Test addition of 0 and undefined.
  */
@@ -32,9 +34,11 @@
 function sum(a, b) { return a + b; }
 
 function test(x, y, expectNaN) {
-  for (var i = 0; i < 1000; i++) {
+  for (var i = 0; i < 5; i++) {
     assertEquals(expectNaN, isNaN(sum(x, y)));
   }
+  %OptimizeFunctionOnNextCall(sum);
+  assertEquals(expectNaN, isNaN(sum(x, y)));
 }
 
 test(0, 1, false);
diff --git a/test/test262/harness-adapt.js b/test/test262/harness-adapt.js
index b52afdb..bc10a9d 100644
--- a/test/test262/harness-adapt.js
+++ b/test/test262/harness-adapt.js
@@ -43,7 +43,7 @@
   }
 
   Test262Error.prototype.toString = function() {
-    return this.result;
+    return this.result + " " + error;
   }
 
   function registerTest(test) {
@@ -52,22 +52,24 @@
       try {
         var res = test.test.call($this);
       } catch(e) {
-        print(e);
-        res = 'fail'; error = e;
+        res = 'fail';
+        error = e;
       }
       var retVal = /^s/i.test(test.id)
           ? (res === true || typeof res == 'undefined' ? 'pass' : 'fail')
           : (res === true ? 'pass' : 'fail');
 
       if (retVal != 'pass') {
+         var precondition = (test.precondition !== undefined)
+             ? test.precondition.toString()
+             : '';
+
          throw new Test262Error(
             test.id,
             test.path,
             test.description,
             test.test.toString(),
-            (test.precondition !== undefined)
-                ? test.precondition.toString()
-                : '',
+            precondition,
             retVal,
             error);
       }
diff --git a/test/test262/test262.status b/test/test262/test262.status
index bdc8b9c..754984d 100644
--- a/test/test262/test262.status
+++ b/test/test262/test262.status
@@ -32,6 +32,20 @@
 
 prefix ietestcenter
 
+
+#
+# Deliberate differences for compatibility with other browsers
+#
+# 15.9.5.43-0-9 and 15.9.5.43-0-10. V8 doesn't throw RangeError
+# from Date.prototype.toISOString when string is not a finite number.
+# This is compatible with Firefox and Safari.
+15.9.5.43-0-9: PASS || FAIL
+15.9.5.43-0-10: PASS || FAIL
+
+#
+# Unanalyzed failures which may be bugs or deliberate differences
+#
+
 # BUG: 7.6 - SyntaxError expected: reserved words used as Identifier
 #      Names in UTF8: class (class)
 7.6-30: FAIL
@@ -913,66 +927,6 @@
 #      of 'O', and 'desc' is accessor descriptor, test updating multiple
 #      attribute values of 'P' (10.6 [[DefineOwnProperty]] step 3)
 15.2.3.7-6-a-292: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into the
-#      returned object
-15.2.3.10-3-2: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into a
-#      Function object
-15.2.3.10-3-3: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into an
-#      Array object
-15.2.3.10-3-4: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into a
-#      String object
-15.2.3.10-3-5-1: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into a
-#      Boolean object
-15.2.3.10-3-6: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into a
-#      Number object
-15.2.3.10-3-7: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into a Date
-#      object
-15.2.3.10-3-8: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into a
-#      RegExp object
-15.2.3.10-3-9: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into an
-#      Error object
-15.2.3.10-3-10: FAIL
-# Bug? Object.preventExtensions - indexed properties cannot be added into an
-#      Arguments object
-15.2.3.10-3-11: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into the
-#      returned object
-15.2.3.10-3-12: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into a
-#      Function object
-15.2.3.10-3-13: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into an Array
-#      object
-15.2.3.10-3-14: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into a String
-#      object
-15.2.3.10-3-15: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into a
-#      Boolean object
-15.2.3.10-3-16: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into a Number
-#      object
-15.2.3.10-3-17: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into a Date
-#      object
-15.2.3.10-3-18: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into a RegExp
-#      object
-15.2.3.10-3-19: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into an Error
-#      object
-15.2.3.10-3-20: FAIL
-# Bug? Object.preventExtensions - named properties cannot be added into an
-#      Arguments object
-15.2.3.10-3-21: FAIL
 # Bug? Object.prototype.toString - '[object Undefined]' will be returned when
 #      'this' value is undefined
 15.2.4.2-1-1: FAIL
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index 0d4420d..77ac2e1 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -856,6 +856,11 @@
 		89F3605A12DCDF6400ACF8A6 /* lithium-codegen-x64.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lithium-codegen-x64.cc"; path = "x64/lithium-codegen-x64.cc"; sourceTree = "<group>"; };
 		89FB0E360F8E531900B04B3C /* d8-posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-posix.cc"; path = "../src/d8-posix.cc"; sourceTree = "<group>"; };
 		89FB0E370F8E531900B04B3C /* d8-windows.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "d8-windows.cc"; path = "../src/d8-windows.cc"; sourceTree = "<group>"; };
+		89FE7C0513532165008662BD /* date.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = date.js; sourceTree = "<group>"; };
+		89FE7C0613532165008662BD /* debug-debugger.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "debug-debugger.js"; sourceTree = "<group>"; };
+		89FE7C0713532165008662BD /* liveedit-debugger.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "liveedit-debugger.js"; sourceTree = "<group>"; };
+		89FE7C0813532165008662BD /* mirror-debugger.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "mirror-debugger.js"; sourceTree = "<group>"; };
+		89FE7C0913532165008662BD /* regexp.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = regexp.js; sourceTree = "<group>"; };
 		9C1F8E1D133906180068B362 /* small-pointer-list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "small-pointer-list.h"; sourceTree = "<group>"; };
 		9C76176D133FB7740057370B /* platform-tls-mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "platform-tls-mac.h"; sourceTree = "<group>"; };
 		9C8E8061133CF772004058A5 /* platform-tls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "platform-tls.h"; sourceTree = "<group>"; };
@@ -1298,6 +1303,11 @@
 		897FF0D80E719ABA00D62E90 /* js */ = {
 			isa = PBXGroup;
 			children = (
+				89FE7C0513532165008662BD /* date.js */,
+				89FE7C0613532165008662BD /* debug-debugger.js */,
+				89FE7C0713532165008662BD /* liveedit-debugger.js */,
+				89FE7C0813532165008662BD /* mirror-debugger.js */,
+				89FE7C0913532165008662BD /* regexp.js */,
 				897FF1A60E719BC100D62E90 /* apinatives.js */,
 				897FF1A70E719BC100D62E90 /* array.js */,
 				897FF1AA0E719BC100D62E90 /* math.js */,