Version 3.8.8

Limited number of loop iterations in Heap::ReserveSpace (Chromium issue 99027).

Fixed solaris build (VirtualMemory) (issue 1761).

Fixed strict vs. non-strict handling of function proxies in higher-order array and string methods.

Enabled asynchronous remote debugging with d8 (issue 1691).

Stability and performance improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@10476 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index 219d354..583453a 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -1031,14 +1031,25 @@
   __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift));
   __ ldr(r4, FieldMemOperand(r0, String::kHashFieldOffset));
   __ eor(r3, r3, Operand(r4, ASR, String::kHashShift));
-  __ And(r3, r3, Operand(KeyedLookupCache::kCapacityMask));
+  int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
+  __ And(r3, r3, Operand(mask));
 
   // Load the key (consisting of map and symbol) from the cache and
   // check for match.
+  Label try_second_entry, hit_on_first_entry, load_in_object_property;
   ExternalReference cache_keys =
       ExternalReference::keyed_lookup_cache_keys(isolate);
   __ mov(r4, Operand(cache_keys));
   __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1));
+  // Move r4 to second entry.
+  __ ldr(r5, MemOperand(r4, kPointerSize * 2, PostIndex));
+  __ cmp(r2, r5);
+  __ b(ne, &try_second_entry);
+  __ ldr(r5, MemOperand(r4, -kPointerSize));  // Load symbol
+  __ cmp(r0, r5);
+  __ b(eq, &hit_on_first_entry);
+
+  __ bind(&try_second_entry);
   __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex));  // Move r4 to symbol.
   __ cmp(r2, r5);
   __ b(ne, &slow);
@@ -1053,6 +1064,18 @@
   // r3     : lookup cache index
   ExternalReference cache_field_offsets =
       ExternalReference::keyed_lookup_cache_field_offsets(isolate);
+
+  // Hit on second entry.
+  __ mov(r4, Operand(cache_field_offsets));
+  __ add(r3, r3, Operand(1));
+  __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2));
+  __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset));
+  __ sub(r5, r5, r6, SetCC);
+  __ b(ge, &property_array_property);
+  __ jmp(&load_in_object_property);
+
+  // Hit on first entry.
+  __ bind(&hit_on_first_entry);
   __ mov(r4, Operand(cache_field_offsets));
   __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2));
   __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset));
@@ -1060,6 +1083,7 @@
   __ b(ge, &property_array_property);
 
   // Load in-object property.
+  __ bind(&load_in_object_property);
   __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset));
   __ add(r6, r6, r5);  // Index from start of object.
   __ sub(r1, r1, Operand(kHeapObjectTag));  // Remove the heap tag.
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 0e050fe..0807857 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2387,7 +2387,7 @@
                                                Handle<String> name) {
   LookupResult lookup(isolate());
   type->LookupInDescriptors(NULL, *name, &lookup);
-  ASSERT(lookup.IsProperty() &&
+  ASSERT(lookup.IsFound() &&
          (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
   if (lookup.type() == FIELD) {
     int index = lookup.GetLocalFieldIndexFromMap(*type);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index cf2d4e2..33fbee5 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -1179,7 +1179,7 @@
   // and CALLBACKS, so inline only them, other cases may be added
   // later.
   bool compile_followup_inline = false;
-  if (lookup->IsProperty() && lookup->IsCacheable()) {
+  if (lookup->IsFound() && lookup->IsCacheable()) {
     if (lookup->type() == FIELD) {
       compile_followup_inline = true;
     } else if (lookup->type() == CALLBACKS &&
diff --git a/src/ast.cc b/src/ast.cc
index 7c5e3a7..580a485 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -746,7 +746,7 @@
         && type->prototype()->IsJSObject()) {
       holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
       type = Handle<Map>(holder()->map());
-    } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
+    } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
       target_ = Handle<JSFunction>(lookup.GetConstantFunctionFromMap(*type));
       return true;
     } else {
@@ -760,7 +760,7 @@
                                LookupResult* lookup) {
   target_ = Handle<JSFunction>::null();
   cell_ = Handle<JSGlobalPropertyCell>::null();
-  ASSERT(lookup->IsProperty() &&
+  ASSERT(lookup->IsFound() &&
          lookup->type() == NORMAL &&
          lookup->holder() == *global);
   cell_ = Handle<JSGlobalPropertyCell>(global->GetPropertyCell(lookup));
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 752b220..cedb0ef 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1099,11 +1099,11 @@
 #ifdef DEBUG
     LookupResult lookup(isolate);
     result->LocalLookup(heap->callee_symbol(), &lookup);
-    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+    ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
 
     result->LocalLookup(heap->length_symbol(), &lookup);
-    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+    ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
 
     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
@@ -1197,7 +1197,7 @@
 #ifdef DEBUG
     LookupResult lookup(isolate);
     result->LocalLookup(heap->length_symbol(), &lookup);
-    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+    ASSERT(lookup.IsFound() && (lookup.type() == FIELD));
     ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
 
     ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index 1cbc0b3..de0faa8 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -310,9 +310,7 @@
   Handle<Value> request =
       Shell::DebugCommandToJSONRequest(String::New(command));
   if (try_catch.HasCaught()) {
-    v8::String::Utf8Value exception(try_catch.Exception());
-    const char* exception_string = Shell::ToCString(exception);
-    printf("%s\n", exception_string);
+    Shell::ReportException(&try_catch);
     PrintPrompt();
     return;
   }
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index 679c536..ed7721c 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -91,7 +91,11 @@
 
 
 Handle<String> ReadLineEditor::Prompt(const char* prompt) {
-  char* result = readline(prompt);
+  char* result = NULL;
+  {  // Release lock for blocking input.
+    Unlocker unlock(Isolate::GetCurrent());
+    result = readline(prompt);
+  }
   if (result != NULL) {
     AddHistory(result);
   } else {
diff --git a/src/d8.cc b/src/d8.cc
index b612c48..bfb9944 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -241,7 +241,12 @@
     // Continue reading if the line ends with an escape '\\' or the line has
     // not been fully read into the buffer yet (does not end with '\n').
     // If fgets gets an error, just give up.
-    if (fgets(buffer, kBufferSize, stdin) == NULL) return Handle<String>();
+    char* input = NULL;
+    {  // Release lock for blocking input.
+      Unlocker unlock(Isolate::GetCurrent());
+      input = fgets(buffer, kBufferSize, stdin);
+    }
+    if (input == NULL) return Handle<String>();
     length = static_cast<int>(strlen(buffer));
     if (length == 0) {
       return accumulator;
@@ -526,6 +531,10 @@
 
 void Shell::ReportException(v8::TryCatch* try_catch) {
   HandleScope handle_scope;
+#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+  bool enter_context = !Context::InContext();
+  if (enter_context) utility_context_->Enter();
+#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
   v8::String::Utf8Value exception(try_catch->Exception());
   const char* exception_string = ToCString(exception);
   Handle<Message> message = try_catch->Message();
@@ -560,6 +569,9 @@
     }
   }
   printf("\n");
+#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
+  if (enter_context) utility_context_->Exit();
+#endif  // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT
 }
 
 
@@ -597,6 +609,12 @@
   Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
   return val;
 }
+
+
+void Shell::DispatchDebugMessages() {
+  v8::Context::Scope scope(Shell::evaluation_context_);
+  v8::Debug::ProcessDebugMessages();
+}
 #endif  // ENABLE_DEBUGGER_SUPPORT
 #endif  // V8_SHARED
 
@@ -866,6 +884,7 @@
   // Start the debugger agent if requested.
   if (i::FLAG_debugger_agent) {
     v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
+    v8::Debug::SetDebugMessageDispatchHandler(DispatchDebugMessages, true);
   }
 #endif  // ENABLE_DEBUGGER_SUPPORT
 #endif  // V8_SHARED
diff --git a/src/d8.h b/src/d8.h
index e9b417b..60a8c1b 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -266,12 +266,13 @@
                                size_t buckets);
   static void AddHistogramSample(void* histogram, int sample);
   static void MapCounters(const char* name);
-#endif  // V8_SHARED
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   static Handle<Object> DebugMessageDetails(Handle<String> message);
   static Handle<Value> DebugCommandToJSONRequest(Handle<String> command);
-#endif
+  static void DispatchDebugMessages();
+#endif  // ENABLE_DEBUGGER_SUPPORT
+#endif  // V8_SHARED
 
 #ifdef WIN32
 #undef Yield
diff --git a/src/extensions/experimental/break-iterator.cc b/src/extensions/experimental/break-iterator.cc
deleted file mode 100644
index e695a3e..0000000
--- a/src/extensions/experimental/break-iterator.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-// 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.
-
-#include "src/extensions/experimental/break-iterator.h"
-
-#include <string.h>
-
-#include "unicode/brkiter.h"
-#include "unicode/locid.h"
-#include "unicode/rbbi.h"
-
-namespace v8 {
-namespace internal {
-
-v8::Persistent<v8::FunctionTemplate> BreakIterator::break_iterator_template_;
-
-icu::BreakIterator* BreakIterator::UnpackBreakIterator(
-    v8::Handle<v8::Object> obj) {
-  if (break_iterator_template_->HasInstance(obj)) {
-    return static_cast<icu::BreakIterator*>(
-        obj->GetPointerFromInternalField(0));
-  }
-
-  return NULL;
-}
-
-icu::UnicodeString* BreakIterator::ResetAdoptedText(
-    v8::Handle<v8::Object> obj, v8::Handle<v8::Value> value) {
-  // Get the previous value from the internal field.
-  icu::UnicodeString* text = static_cast<icu::UnicodeString*>(
-      obj->GetPointerFromInternalField(1));
-  delete text;
-
-  // Assign new value to the internal pointer.
-  v8::String::Value text_value(value);
-  text = new icu::UnicodeString(
-      reinterpret_cast<const UChar*>(*text_value), text_value.length());
-  obj->SetPointerInInternalField(1, text);
-
-  // Return new unicode string pointer.
-  return text;
-}
-
-void BreakIterator::DeleteBreakIterator(v8::Persistent<v8::Value> object,
-                                        void* param) {
-  v8::Persistent<v8::Object> persistent_object =
-      v8::Persistent<v8::Object>::Cast(object);
-
-  // First delete the hidden C++ object.
-  // Unpacking should never return NULL here. That would only happen if
-  // this method is used as the weak callback for persistent handles not
-  // pointing to a break iterator.
-  delete UnpackBreakIterator(persistent_object);
-
-  delete static_cast<icu::UnicodeString*>(
-      persistent_object->GetPointerFromInternalField(1));
-
-  // Then dispose of the persistent handle to JS object.
-  persistent_object.Dispose();
-}
-
-// Throws a JavaScript exception.
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
-  // Returns undefined, and schedules an exception to be thrown.
-  return v8::ThrowException(v8::Exception::Error(
-      v8::String::New("BreakIterator method called on an object "
-                      "that is not a BreakIterator.")));
-}
-
-v8::Handle<v8::Value> BreakIterator::BreakIteratorAdoptText(
-    const v8::Arguments& args) {
-  if (args.Length() != 1 || !args[0]->IsString()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Text input is required.")));
-  }
-
-  icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
-  if (!break_iterator) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  break_iterator->setText(*ResetAdoptedText(args.Holder(), args[0]));
-
-  return v8::Undefined();
-}
-
-v8::Handle<v8::Value> BreakIterator::BreakIteratorFirst(
-    const v8::Arguments& args) {
-  icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
-  if (!break_iterator) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  return v8::Int32::New(break_iterator->first());
-}
-
-v8::Handle<v8::Value> BreakIterator::BreakIteratorNext(
-    const v8::Arguments& args) {
-  icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
-  if (!break_iterator) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  return v8::Int32::New(break_iterator->next());
-}
-
-v8::Handle<v8::Value> BreakIterator::BreakIteratorCurrent(
-    const v8::Arguments& args) {
-  icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
-  if (!break_iterator) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  return v8::Int32::New(break_iterator->current());
-}
-
-v8::Handle<v8::Value> BreakIterator::BreakIteratorBreakType(
-    const v8::Arguments& args) {
-  icu::BreakIterator* break_iterator = UnpackBreakIterator(args.Holder());
-  if (!break_iterator) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
-  icu::RuleBasedBreakIterator* rule_based_iterator =
-      static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
-  int32_t status = rule_based_iterator->getRuleStatus();
-  // Keep return values in sync with JavaScript BreakType enum.
-  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
-    return v8::Int32::New(UBRK_WORD_NONE);
-  } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
-    return v8::Int32::New(UBRK_WORD_NUMBER);
-  } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
-    return v8::Int32::New(UBRK_WORD_LETTER);
-  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
-    return v8::Int32::New(UBRK_WORD_KANA);
-  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
-    return v8::Int32::New(UBRK_WORD_IDEO);
-  } else {
-    return v8::Int32::New(-1);
-  }
-}
-
-v8::Handle<v8::Value> BreakIterator::JSBreakIterator(
-    const v8::Arguments& args) {
-  v8::HandleScope handle_scope;
-
-  if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Locale and iterator type are required.")));
-  }
-
-  v8::String::Utf8Value locale(args[0]);
-  icu::Locale icu_locale(*locale);
-
-  UErrorCode status = U_ZERO_ERROR;
-  icu::BreakIterator* break_iterator = NULL;
-  v8::String::Utf8Value type(args[1]);
-  if (!strcmp(*type, "character")) {
-    break_iterator =
-        icu::BreakIterator::createCharacterInstance(icu_locale, status);
-  } else if (!strcmp(*type, "word")) {
-    break_iterator =
-        icu::BreakIterator::createWordInstance(icu_locale, status);
-  } else if (!strcmp(*type, "sentence")) {
-    break_iterator =
-        icu::BreakIterator::createSentenceInstance(icu_locale, status);
-  } else if (!strcmp(*type, "line")) {
-    break_iterator =
-        icu::BreakIterator::createLineInstance(icu_locale, status);
-  } else {
-    return v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Invalid iterator type.")));
-  }
-
-  if (U_FAILURE(status)) {
-    delete break_iterator;
-    return v8::ThrowException(v8::Exception::Error(
-        v8::String::New("Failed to create break iterator.")));
-  }
-
-  if (break_iterator_template_.IsEmpty()) {
-    v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
-
-    raw_template->SetClassName(v8::String::New("v8Locale.v8BreakIterator"));
-
-    // Define internal field count on instance template.
-    v8::Local<v8::ObjectTemplate> object_template =
-        raw_template->InstanceTemplate();
-
-    // Set aside internal fields for icu break iterator and adopted text.
-    object_template->SetInternalFieldCount(2);
-
-    // Define all of the prototype methods on prototype template.
-    v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
-    proto->Set(v8::String::New("adoptText"),
-               v8::FunctionTemplate::New(BreakIteratorAdoptText));
-    proto->Set(v8::String::New("first"),
-               v8::FunctionTemplate::New(BreakIteratorFirst));
-    proto->Set(v8::String::New("next"),
-               v8::FunctionTemplate::New(BreakIteratorNext));
-    proto->Set(v8::String::New("current"),
-               v8::FunctionTemplate::New(BreakIteratorCurrent));
-    proto->Set(v8::String::New("breakType"),
-               v8::FunctionTemplate::New(BreakIteratorBreakType));
-
-    break_iterator_template_ =
-        v8::Persistent<v8::FunctionTemplate>::New(raw_template);
-  }
-
-  // Create an empty object wrapper.
-  v8::Local<v8::Object> local_object =
-      break_iterator_template_->GetFunction()->NewInstance();
-  v8::Persistent<v8::Object> wrapper =
-      v8::Persistent<v8::Object>::New(local_object);
-
-  // Set break iterator as internal field of the resulting JS object.
-  wrapper->SetPointerInInternalField(0, break_iterator);
-  // Make sure that the pointer to adopted text is NULL.
-  wrapper->SetPointerInInternalField(1, NULL);
-
-  // Make object handle weak so we can delete iterator once GC kicks in.
-  wrapper.MakeWeak(NULL, DeleteBreakIterator);
-
-  return wrapper;
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/break-iterator.h b/src/extensions/experimental/break-iterator.h
deleted file mode 100644
index 73b9bbd..0000000
--- a/src/extensions/experimental/break-iterator.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
-
-#include "include/v8.h"
-
-#include "unicode/uversion.h"
-
-namespace U_ICU_NAMESPACE {
-class BreakIterator;
-class UnicodeString;
-}
-
-namespace v8 {
-namespace internal {
-
-class BreakIterator {
- public:
-  static v8::Handle<v8::Value> JSBreakIterator(const v8::Arguments& args);
-
-  // Helper methods for various bindings.
-
-  // Unpacks break iterator object from corresponding JavaScript object.
-  static icu::BreakIterator* UnpackBreakIterator(v8::Handle<v8::Object> obj);
-
-  // Deletes the old value and sets the adopted text in
-  // corresponding JavaScript object.
-  static icu::UnicodeString* ResetAdoptedText(v8::Handle<v8::Object> obj,
-                                              v8::Handle<v8::Value> text_value);
-
-  // Release memory we allocated for the BreakIterator once the JS object that
-  // holds the pointer gets garbage collected.
-  static void DeleteBreakIterator(v8::Persistent<v8::Value> object,
-                                  void* param);
-
-  // Assigns new text to the iterator.
-  static v8::Handle<v8::Value> BreakIteratorAdoptText(
-      const v8::Arguments& args);
-
-  // Moves iterator to the beginning of the string and returns new position.
-  static v8::Handle<v8::Value> BreakIteratorFirst(const v8::Arguments& args);
-
-  // Moves iterator to the next position and returns it.
-  static v8::Handle<v8::Value> BreakIteratorNext(const v8::Arguments& args);
-
-  // Returns current iterator's current position.
-  static v8::Handle<v8::Value> BreakIteratorCurrent(
-      const v8::Arguments& args);
-
-  // Returns type of the item from current position.
-  // This call is only valid for word break iterators. Others just return 0.
-  static v8::Handle<v8::Value> BreakIteratorBreakType(
-      const v8::Arguments& args);
-
- private:
-  BreakIterator() {}
-
-  static v8::Persistent<v8::FunctionTemplate> break_iterator_template_;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_BREAK_ITERATOR_H_
diff --git a/src/extensions/experimental/collator.cc b/src/extensions/experimental/collator.cc
deleted file mode 100644
index 5cf2192..0000000
--- a/src/extensions/experimental/collator.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-// 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.
-
-#include "src/extensions/experimental/collator.h"
-
-#include "unicode/coll.h"
-#include "unicode/locid.h"
-#include "unicode/ucol.h"
-
-namespace v8 {
-namespace internal {
-
-v8::Persistent<v8::FunctionTemplate> Collator::collator_template_;
-
-icu::Collator* Collator::UnpackCollator(v8::Handle<v8::Object> obj) {
-  if (collator_template_->HasInstance(obj)) {
-    return static_cast<icu::Collator*>(obj->GetPointerFromInternalField(0));
-  }
-
-  return NULL;
-}
-
-void Collator::DeleteCollator(v8::Persistent<v8::Value> object, void* param) {
-  v8::Persistent<v8::Object> persistent_object =
-      v8::Persistent<v8::Object>::Cast(object);
-
-  // First delete the hidden C++ object.
-  // Unpacking should never return NULL here. That would only happen if
-  // this method is used as the weak callback for persistent handles not
-  // pointing to a collator.
-  delete UnpackCollator(persistent_object);
-
-  // Then dispose of the persistent handle to JS object.
-  persistent_object.Dispose();
-}
-
-// Throws a JavaScript exception.
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
-  // Returns undefined, and schedules an exception to be thrown.
-  return v8::ThrowException(v8::Exception::Error(
-      v8::String::New("Collator method called on an object "
-                      "that is not a Collator.")));
-}
-
-// Extract a boolean option named in |option| and set it to |result|.
-// Return true if it's specified. Otherwise, return false.
-static bool ExtractBooleanOption(const v8::Local<v8::Object>& options,
-                                 const char* option,
-                                 bool* result) {
-  v8::HandleScope handle_scope;
-  v8::TryCatch try_catch;
-  v8::Handle<v8::Value> value = options->Get(v8::String::New(option));
-  if (try_catch.HasCaught()) {
-    return false;
-  }
-  // No need to check if |value| is empty because it's taken care of
-  // by TryCatch above.
-  if (!value->IsUndefined() && !value->IsNull()) {
-    if (value->IsBoolean()) {
-      *result = value->BooleanValue();
-      return true;
-    }
-  }
-  return false;
-}
-
-// When there's an ICU error, throw a JavaScript error with |message|.
-static v8::Handle<v8::Value> ThrowExceptionForICUError(const char* message) {
-  return v8::ThrowException(v8::Exception::Error(v8::String::New(message)));
-}
-
-v8::Handle<v8::Value> Collator::CollatorCompare(const v8::Arguments& args) {
-  if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsString()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Two string arguments are required.")));
-  }
-
-  icu::Collator* collator = UnpackCollator(args.Holder());
-  if (!collator) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  v8::String::Value string_value1(args[0]);
-  v8::String::Value string_value2(args[1]);
-  const UChar* string1 = reinterpret_cast<const UChar*>(*string_value1);
-  const UChar* string2 = reinterpret_cast<const UChar*>(*string_value2);
-  UErrorCode status = U_ZERO_ERROR;
-  UCollationResult result = collator->compare(
-      string1, string_value1.length(), string2, string_value2.length(), status);
-
-  if (U_FAILURE(status)) {
-    return ThrowExceptionForICUError(
-        "Unexpected failure in Collator.compare.");
-  }
-
-  return v8::Int32::New(result);
-}
-
-v8::Handle<v8::Value> Collator::JSCollator(const v8::Arguments& args) {
-  v8::HandleScope handle_scope;
-
-  if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsObject()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Locale and collation options are required.")));
-  }
-
-  v8::String::AsciiValue locale(args[0]);
-  icu::Locale icu_locale(*locale);
-
-  icu::Collator* collator = NULL;
-  UErrorCode status = U_ZERO_ERROR;
-  collator = icu::Collator::createInstance(icu_locale, status);
-
-  if (U_FAILURE(status)) {
-    delete collator;
-    return ThrowExceptionForICUError("Failed to create collator.");
-  }
-
-  v8::Local<v8::Object> options(args[1]->ToObject());
-
-  // Below, we change collation options that are explicitly specified
-  // by a caller in JavaScript. Otherwise, we don't touch because
-  // we don't want to change the locale-dependent default value.
-  // The three options below are very likely to have the same default
-  // across locales, but I haven't checked them all. Others we may add
-  // in the future have certainly locale-dependent default (e.g.
-  // caseFirst is upperFirst for Danish while is off for most other locales).
-
-  bool ignore_case, ignore_accents, numeric;
-
-  if (ExtractBooleanOption(options, "ignoreCase", &ignore_case)) {
-    // We need to explicitly set the level to secondary to get case ignored.
-    // The default L3 ignores UCOL_CASE_LEVEL == UCOL_OFF !
-    if (ignore_case) {
-      collator->setStrength(icu::Collator::SECONDARY);
-    }
-    collator->setAttribute(UCOL_CASE_LEVEL, ignore_case ? UCOL_OFF : UCOL_ON,
-                           status);
-    if (U_FAILURE(status)) {
-      delete collator;
-      return ThrowExceptionForICUError("Failed to set ignoreCase.");
-    }
-  }
-
-  // Accents are taken into account with strength secondary or higher.
-  if (ExtractBooleanOption(options, "ignoreAccents", &ignore_accents)) {
-    if (!ignore_accents) {
-      collator->setStrength(icu::Collator::SECONDARY);
-    } else {
-      collator->setStrength(icu::Collator::PRIMARY);
-    }
-  }
-
-  if (ExtractBooleanOption(options, "numeric", &numeric)) {
-    collator->setAttribute(UCOL_NUMERIC_COLLATION,
-                           numeric ? UCOL_ON : UCOL_OFF, status);
-    if (U_FAILURE(status)) {
-      delete collator;
-      return ThrowExceptionForICUError("Failed to set numeric sort option.");
-    }
-  }
-
-  if (collator_template_.IsEmpty()) {
-    v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
-    raw_template->SetClassName(v8::String::New("v8Locale.Collator"));
-
-    // Define internal field count on instance template.
-    v8::Local<v8::ObjectTemplate> object_template =
-        raw_template->InstanceTemplate();
-
-    // Set aside internal fields for icu collator.
-    object_template->SetInternalFieldCount(1);
-
-    // Define all of the prototype methods on prototype template.
-    v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
-    proto->Set(v8::String::New("compare"),
-               v8::FunctionTemplate::New(CollatorCompare));
-
-    collator_template_ =
-        v8::Persistent<v8::FunctionTemplate>::New(raw_template);
-  }
-
-  // Create an empty object wrapper.
-  v8::Local<v8::Object> local_object =
-      collator_template_->GetFunction()->NewInstance();
-  v8::Persistent<v8::Object> wrapper =
-      v8::Persistent<v8::Object>::New(local_object);
-
-  // Set collator as internal field of the resulting JS object.
-  wrapper->SetPointerInInternalField(0, collator);
-
-  // Make object handle weak so we can delete iterator once GC kicks in.
-  wrapper.MakeWeak(NULL, DeleteCollator);
-
-  return wrapper;
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/collator.h b/src/extensions/experimental/collator.h
deleted file mode 100644
index ca7e4dc..0000000
--- a/src/extensions/experimental/collator.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_COLLATOR_H
-#define V8_EXTENSIONS_EXPERIMENTAL_COLLATOR_H_
-
-#include "include/v8.h"
-
-#include "unicode/uversion.h"
-
-namespace U_ICU_NAMESPACE {
-class Collator;
-class UnicodeString;
-}
-
-namespace v8 {
-namespace internal {
-
-class Collator {
- public:
-  static v8::Handle<v8::Value> JSCollator(const v8::Arguments& args);
-
-  // Helper methods for various bindings.
-
-  // Unpacks collator object from corresponding JavaScript object.
-  static icu::Collator* UnpackCollator(v8::Handle<v8::Object> obj);
-
-  // Release memory we allocated for the Collator once the JS object that
-  // holds the pointer gets garbage collected.
-  static void DeleteCollator(v8::Persistent<v8::Value> object, void* param);
-
-  // Compare two strings and returns -1, 0 and 1 depending on
-  // whether string1 is smaller than, equal to or larger than string2.
-  static v8::Handle<v8::Value> CollatorCompare(const v8::Arguments& args);
-
- private:
-  Collator() {}
-
-  static v8::Persistent<v8::FunctionTemplate> collator_template_;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_COLLATOR
diff --git a/src/extensions/experimental/datetime-format.cc b/src/extensions/experimental/datetime-format.cc
deleted file mode 100644
index 94a29ac..0000000
--- a/src/extensions/experimental/datetime-format.cc
+++ /dev/null
@@ -1,384 +0,0 @@
-// 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.
-
-#include "src/extensions/experimental/datetime-format.h"
-
-#include <string.h>
-
-#include "src/extensions/experimental/i18n-utils.h"
-#include "unicode/dtfmtsym.h"
-#include "unicode/dtptngen.h"
-#include "unicode/locid.h"
-#include "unicode/smpdtfmt.h"
-
-namespace v8 {
-namespace internal {
-
-v8::Persistent<v8::FunctionTemplate> DateTimeFormat::datetime_format_template_;
-
-static icu::DateFormat* CreateDateTimeFormat(v8::Handle<v8::String>,
-                                             v8::Handle<v8::Object>);
-static v8::Handle<v8::Value> GetSymbols(
-    const v8::Arguments&,
-    const icu::UnicodeString*, int32_t,
-    const icu::UnicodeString*, int32_t,
-    const icu::UnicodeString*, int32_t);
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError();
-static icu::DateFormat::EStyle GetDateTimeStyle(const icu::UnicodeString&);
-
-icu::SimpleDateFormat* DateTimeFormat::UnpackDateTimeFormat(
-    v8::Handle<v8::Object> obj) {
-  if (datetime_format_template_->HasInstance(obj)) {
-    return static_cast<icu::SimpleDateFormat*>(
-        obj->GetPointerFromInternalField(0));
-  }
-
-  return NULL;
-}
-
-void DateTimeFormat::DeleteDateTimeFormat(v8::Persistent<v8::Value> object,
-                                          void* param) {
-  v8::Persistent<v8::Object> persistent_object =
-      v8::Persistent<v8::Object>::Cast(object);
-
-  // First delete the hidden C++ object.
-  // Unpacking should never return NULL here. That would only happen if
-  // this method is used as the weak callback for persistent handles not
-  // pointing to a date time formatter.
-  delete UnpackDateTimeFormat(persistent_object);
-
-  // Then dispose of the persistent handle to JS object.
-  persistent_object.Dispose();
-}
-
-v8::Handle<v8::Value> DateTimeFormat::Format(const v8::Arguments& args) {
-  v8::HandleScope handle_scope;
-
-  double millis = 0.0;
-  if (args.Length() != 1 || !args[0]->IsDate()) {
-    // Create a new date.
-    v8::TryCatch try_catch;
-    v8::Local<v8::Script> date_script =
-        v8::Script::Compile(v8::String::New("eval('new Date()')"));
-    millis = date_script->Run()->NumberValue();
-    if (try_catch.HasCaught()) {
-      return try_catch.ReThrow();
-    }
-  } else {
-    millis = v8::Date::Cast(*args[0])->NumberValue();
-  }
-
-  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
-  if (!date_format) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  icu::UnicodeString result;
-  date_format->format(millis, result);
-
-  return v8::String::New(
-      reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length());
-}
-
-v8::Handle<v8::Value> DateTimeFormat::GetMonths(const v8::Arguments& args) {
-  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
-  if (!date_format) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
-
-  int32_t narrow_count;
-  const icu::UnicodeString* narrow = symbols->getMonths(
-      narrow_count,
-      icu::DateFormatSymbols::STANDALONE,
-      icu::DateFormatSymbols::NARROW);
-  int32_t abbrev_count;
-  const icu::UnicodeString* abbrev = symbols->getMonths(
-      abbrev_count,
-      icu::DateFormatSymbols::STANDALONE,
-      icu::DateFormatSymbols::ABBREVIATED);
-  int32_t wide_count;
-  const icu::UnicodeString* wide = symbols->getMonths(
-      wide_count,
-      icu::DateFormatSymbols::STANDALONE,
-      icu::DateFormatSymbols::WIDE);
-
-  return GetSymbols(
-      args, narrow, narrow_count, abbrev, abbrev_count, wide, wide_count);
-}
-
-v8::Handle<v8::Value> DateTimeFormat::GetWeekdays(const v8::Arguments& args) {
-  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
-  if (!date_format) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
-
-  int32_t narrow_count;
-  const icu::UnicodeString* narrow = symbols->getWeekdays(
-      narrow_count,
-      icu::DateFormatSymbols::STANDALONE,
-      icu::DateFormatSymbols::NARROW);
-  int32_t abbrev_count;
-  const icu::UnicodeString* abbrev = symbols->getWeekdays(
-      abbrev_count,
-      icu::DateFormatSymbols::STANDALONE,
-      icu::DateFormatSymbols::ABBREVIATED);
-  int32_t wide_count;
-  const icu::UnicodeString* wide = symbols->getWeekdays(
-      wide_count,
-      icu::DateFormatSymbols::STANDALONE,
-      icu::DateFormatSymbols::WIDE);
-
-  // getXXXWeekdays always returns 8 elements - ICU stable API.
-  // We can't use ASSERT_EQ(8, narrow_count) because ASSERT is internal to v8.
-  if (narrow_count != 8 || abbrev_count != 8 || wide_count != 8) {
-    return v8::ThrowException(v8::Exception::Error(
-        v8::String::New("Failed to get weekday information.")));
-  }
-
-  // ICU documentation says we should ignore element 0 of the returned array.
-  return GetSymbols(args, narrow + 1, narrow_count - 1, abbrev + 1,
-                    abbrev_count -1 , wide + 1, wide_count - 1);
-}
-
-v8::Handle<v8::Value> DateTimeFormat::GetEras(const v8::Arguments& args) {
-  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
-  if (!date_format) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
-
-  int32_t narrow_count;
-  const icu::UnicodeString* narrow = symbols->getNarrowEras(narrow_count);
-  int32_t abbrev_count;
-  const icu::UnicodeString* abbrev = symbols->getEras(abbrev_count);
-  int32_t wide_count;
-  const icu::UnicodeString* wide = symbols->getEraNames(wide_count);
-
-  return GetSymbols(
-      args, narrow, narrow_count, abbrev, abbrev_count, wide, wide_count);
-}
-
-v8::Handle<v8::Value> DateTimeFormat::GetAmPm(const v8::Arguments& args) {
-  icu::SimpleDateFormat* date_format = UnpackDateTimeFormat(args.Holder());
-  if (!date_format) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  const icu::DateFormatSymbols* symbols = date_format->getDateFormatSymbols();
-
-  // In this case narrow == abbreviated == wide
-  int32_t count;
-  const icu::UnicodeString* wide = symbols->getAmPmStrings(count);
-
-  return GetSymbols(args, wide, count, wide, count, wide, count);
-}
-
-v8::Handle<v8::Value> DateTimeFormat::JSDateTimeFormat(
-    const v8::Arguments& args) {
-  v8::HandleScope handle_scope;
-
-  if (args.Length() != 2 || !args[0]->IsString() || !args[1]->IsObject()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Locale and date/time options are required.")));
-  }
-
-  icu::SimpleDateFormat* date_format = static_cast<icu::SimpleDateFormat*>(
-      CreateDateTimeFormat(args[0]->ToString(), args[1]->ToObject()));
-
-  if (datetime_format_template_.IsEmpty()) {
-    v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
-
-    raw_template->SetClassName(v8::String::New("v8Locale.DateTimeFormat"));
-
-    // Define internal field count on instance template.
-    v8::Local<v8::ObjectTemplate> object_template =
-        raw_template->InstanceTemplate();
-
-    // Set aside internal field for icu date time formatter.
-    object_template->SetInternalFieldCount(1);
-
-    // Define all of the prototype methods on prototype template.
-    v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
-    proto->Set(v8::String::New("format"),
-               v8::FunctionTemplate::New(Format));
-    proto->Set(v8::String::New("getMonths"),
-               v8::FunctionTemplate::New(GetMonths));
-    proto->Set(v8::String::New("getWeekdays"),
-               v8::FunctionTemplate::New(GetWeekdays));
-    proto->Set(v8::String::New("getEras"),
-               v8::FunctionTemplate::New(GetEras));
-    proto->Set(v8::String::New("getAmPm"),
-               v8::FunctionTemplate::New(GetAmPm));
-
-    datetime_format_template_ =
-        v8::Persistent<v8::FunctionTemplate>::New(raw_template);
-  }
-
-  // Create an empty object wrapper.
-  v8::Local<v8::Object> local_object =
-      datetime_format_template_->GetFunction()->NewInstance();
-  v8::Persistent<v8::Object> wrapper =
-      v8::Persistent<v8::Object>::New(local_object);
-
-  // Set date time formatter as internal field of the resulting JS object.
-  wrapper->SetPointerInInternalField(0, date_format);
-
-  // Set resolved pattern in options.pattern.
-  icu::UnicodeString pattern;
-  date_format->toPattern(pattern);
-  v8::Local<v8::Object> options = v8::Object::New();
-  options->Set(v8::String::New("pattern"),
-               v8::String::New(reinterpret_cast<const uint16_t*>(
-                   pattern.getBuffer()), pattern.length()));
-  wrapper->Set(v8::String::New("options"), options);
-
-  // Make object handle weak so we can delete iterator once GC kicks in.
-  wrapper.MakeWeak(NULL, DeleteDateTimeFormat);
-
-  return wrapper;
-}
-
-// Returns SimpleDateFormat.
-static icu::DateFormat* CreateDateTimeFormat(
-    v8::Handle<v8::String> locale, v8::Handle<v8::Object> settings) {
-  v8::HandleScope handle_scope;
-
-  v8::String::AsciiValue ascii_locale(locale);
-  icu::Locale icu_locale(*ascii_locale);
-
-  // Make formatter from skeleton.
-  icu::SimpleDateFormat* date_format = NULL;
-  UErrorCode status = U_ZERO_ERROR;
-  icu::UnicodeString skeleton;
-  if (I18NUtils::ExtractStringSetting(settings, "skeleton", &skeleton)) {
-    v8::Local<icu::DateTimePatternGenerator> generator(
-        icu::DateTimePatternGenerator::createInstance(icu_locale, status));
-    icu::UnicodeString pattern =
-        generator->getBestPattern(skeleton, status);
-
-    date_format = new icu::SimpleDateFormat(pattern, icu_locale, status);
-    if (U_SUCCESS(status)) {
-      return date_format;
-    } else {
-      delete date_format;
-    }
-  }
-
-  // Extract date style and time style from settings.
-  icu::UnicodeString date_style;
-  icu::DateFormat::EStyle icu_date_style = icu::DateFormat::kNone;
-  if (I18NUtils::ExtractStringSetting(settings, "dateStyle", &date_style)) {
-    icu_date_style = GetDateTimeStyle(date_style);
-  }
-
-  icu::UnicodeString time_style;
-  icu::DateFormat::EStyle icu_time_style = icu::DateFormat::kNone;
-  if (I18NUtils::ExtractStringSetting(settings, "timeStyle", &time_style)) {
-    icu_time_style = GetDateTimeStyle(time_style);
-  }
-
-  // Try all combinations of date/time styles.
-  if (icu_date_style == icu::DateFormat::kNone &&
-      icu_time_style == icu::DateFormat::kNone) {
-    // Return default short date, short
-    return icu::DateFormat::createDateTimeInstance(
-        icu::DateFormat::kShort, icu::DateFormat::kShort, icu_locale);
-  } else if (icu_date_style != icu::DateFormat::kNone &&
-             icu_time_style != icu::DateFormat::kNone) {
-    return icu::DateFormat::createDateTimeInstance(
-        icu_date_style, icu_time_style, icu_locale);
-  } else if (icu_date_style != icu::DateFormat::kNone) {
-    return icu::DateFormat::createDateInstance(icu_date_style, icu_locale);
-  } else {
-    // icu_time_style != icu::DateFormat::kNone
-    return icu::DateFormat::createTimeInstance(icu_time_style, icu_locale);
-  }
-}
-
-// Creates a v8::Array of narrow, abbrev or wide symbols.
-static v8::Handle<v8::Value> GetSymbols(const v8::Arguments& args,
-                                        const icu::UnicodeString* narrow,
-                                        int32_t narrow_count,
-                                        const icu::UnicodeString* abbrev,
-                                        int32_t abbrev_count,
-                                        const icu::UnicodeString* wide,
-                                        int32_t wide_count) {
-  v8::HandleScope handle_scope;
-
-  // Make wide width default.
-  const icu::UnicodeString* result = wide;
-  int32_t count = wide_count;
-
-  if (args.Length() == 1 && args[0]->IsString()) {
-    v8::String::AsciiValue ascii_value(args[0]);
-    if (strcmp(*ascii_value, "abbreviated") == 0) {
-      result = abbrev;
-      count = abbrev_count;
-    } else if (strcmp(*ascii_value, "narrow") == 0) {
-      result = narrow;
-      count = narrow_count;
-    }
-  }
-
-  v8::Handle<v8::Array> symbols = v8::Array::New();
-  for (int32_t i = 0; i < count; ++i) {
-    symbols->Set(i, v8::String::New(
-        reinterpret_cast<const uint16_t*>(result[i].getBuffer()),
-        result[i].length()));
-  }
-
-  return handle_scope.Close(symbols);
-}
-
-// Throws a JavaScript exception.
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
-  // Returns undefined, and schedules an exception to be thrown.
-  return v8::ThrowException(v8::Exception::Error(
-      v8::String::New("DateTimeFormat method called on an object "
-                      "that is not a DateTimeFormat.")));
-}
-
-// Returns icu date/time style.
-static icu::DateFormat::EStyle GetDateTimeStyle(
-    const icu::UnicodeString& type) {
-  if (type == UNICODE_STRING_SIMPLE("medium")) {
-    return icu::DateFormat::kMedium;
-  } else if (type == UNICODE_STRING_SIMPLE("long")) {
-    return icu::DateFormat::kLong;
-  } else if (type == UNICODE_STRING_SIMPLE("full")) {
-    return icu::DateFormat::kFull;
-  }
-
-  return icu::DateFormat::kShort;
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/datetime-format.h b/src/extensions/experimental/datetime-format.h
deleted file mode 100644
index a6a228c..0000000
--- a/src/extensions/experimental/datetime-format.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
-
-#include "include/v8.h"
-
-#include "unicode/uversion.h"
-
-namespace U_ICU_NAMESPACE {
-class SimpleDateFormat;
-}
-
-namespace v8 {
-namespace internal {
-
-class DateTimeFormat {
- public:
-  static v8::Handle<v8::Value> JSDateTimeFormat(const v8::Arguments& args);
-
-  // Helper methods for various bindings.
-
-  // Unpacks date format object from corresponding JavaScript object.
-  static icu::SimpleDateFormat* UnpackDateTimeFormat(
-      v8::Handle<v8::Object> obj);
-
-  // Release memory we allocated for the DateFormat once the JS object that
-  // holds the pointer gets garbage collected.
-  static void DeleteDateTimeFormat(v8::Persistent<v8::Value> object,
-                                   void* param);
-
-  // Formats date and returns corresponding string.
-  static v8::Handle<v8::Value> Format(const v8::Arguments& args);
-
-  // All date time symbol methods below return stand-alone names in
-  // either narrow, abbreviated or wide width.
-
-  // Get list of months.
-  static v8::Handle<v8::Value> GetMonths(const v8::Arguments& args);
-
-  // Get list of weekdays.
-  static v8::Handle<v8::Value> GetWeekdays(const v8::Arguments& args);
-
-  // Get list of eras.
-  static v8::Handle<v8::Value> GetEras(const v8::Arguments& args);
-
-  // Get list of day periods.
-  static v8::Handle<v8::Value> GetAmPm(const v8::Arguments& args);
-
- private:
-  DateTimeFormat();
-
-  static v8::Persistent<v8::FunctionTemplate> datetime_format_template_;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_DATETIME_FORMAT_H_
diff --git a/src/extensions/experimental/experimental.gyp b/src/extensions/experimental/experimental.gyp
deleted file mode 100644
index 24fb683..0000000
--- a/src/extensions/experimental/experimental.gyp
+++ /dev/null
@@ -1,105 +0,0 @@
-# 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.
-
-{
-  'variables': {
-    # TODO(cira): Find out how to pass this value for arbitrary embedder.
-    # Chromium sets it in common.gypi and does force include of that file for
-    # all sub projects.
-    'icu_src_dir%': '../../../../third_party/icu',
-  },
-  'targets': [
-    {
-      'target_name': 'i18n_api',
-      'type': 'static_library',
-      'sources': [
-        'break-iterator.cc',
-        'break-iterator.h',
-        'collator.cc',
-        'collator.h',
-        'datetime-format.cc',
-        'datetime-format.h',
-        'i18n-extension.cc',
-        'i18n-extension.h',
-        'i18n-locale.cc',
-        'i18n-locale.h',
-        'i18n-natives.h',
-        'i18n-utils.cc',
-        'i18n-utils.h',
-        'language-matcher.cc',
-        'language-matcher.h',
-        'number-format.cc',
-        'number-format.h',
-        '<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
-      ],
-      'include_dirs': [
-        '<(icu_src_dir)/public/common',
-        # v8/ is root for all includes.
-        '../../..'
-      ],
-      'dependencies': [
-        '<(icu_src_dir)/icu.gyp:*',
-        'js2c_i18n#host',
-        '../../../tools/gyp/v8.gyp:v8',
-      ],
-      'direct_dependent_settings': {
-        # Adds -Iv8 for embedders.
-        'include_dirs': [
-          '../../..'
-        ],
-      },
-    },
-    {
-      'target_name': 'js2c_i18n',
-      'type': 'none',
-      'toolsets': ['host'],
-      'variables': {
-        'js_files': [
-          'i18n.js'
-        ],
-      },
-      'actions': [
-        {
-          'action_name': 'js2c_i18n',
-          'inputs': [
-            'i18n-js2c.py',
-            '<@(js_files)',
-          ],
-          'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
-          ],
-          'action': [
-            'python',
-            'i18n-js2c.py',
-            '<@(_outputs)',
-            '<@(js_files)'
-          ],
-        },
-      ],
-    },
-  ],  # targets
-}
diff --git a/src/extensions/experimental/i18n-extension.cc b/src/extensions/experimental/i18n-extension.cc
deleted file mode 100644
index c5afcf0..0000000
--- a/src/extensions/experimental/i18n-extension.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-#include "src/extensions/experimental/i18n-extension.h"
-
-#include "src/extensions/experimental/break-iterator.h"
-#include "src/extensions/experimental/collator.h"
-#include "src/extensions/experimental/datetime-format.h"
-#include "src/extensions/experimental/i18n-locale.h"
-#include "src/extensions/experimental/i18n-natives.h"
-#include "src/extensions/experimental/number-format.h"
-
-namespace v8 {
-namespace internal {
-
-I18NExtension* I18NExtension::extension_ = NULL;
-
-I18NExtension::I18NExtension()
-    : v8::Extension("v8/i18n", I18Natives::GetScriptSource()) {
-}
-
-v8::Handle<v8::FunctionTemplate> I18NExtension::GetNativeFunction(
-    v8::Handle<v8::String> name) {
-  if (name->Equals(v8::String::New("NativeJSLocale"))) {
-    return v8::FunctionTemplate::New(I18NLocale::JSLocale);
-  } else if (name->Equals(v8::String::New("NativeJSBreakIterator"))) {
-    return v8::FunctionTemplate::New(BreakIterator::JSBreakIterator);
-  } else if (name->Equals(v8::String::New("NativeJSCollator"))) {
-    return v8::FunctionTemplate::New(Collator::JSCollator);
-  } else if (name->Equals(v8::String::New("NativeJSDateTimeFormat"))) {
-    return v8::FunctionTemplate::New(DateTimeFormat::JSDateTimeFormat);
-  } else if (name->Equals(v8::String::New("NativeJSNumberFormat"))) {
-    return v8::FunctionTemplate::New(NumberFormat::JSNumberFormat);
-  }
-
-  return v8::Handle<v8::FunctionTemplate>();
-}
-
-I18NExtension* I18NExtension::get() {
-  if (!extension_) {
-    extension_ = new I18NExtension();
-  }
-  return extension_;
-}
-
-void I18NExtension::Register() {
-  static v8::DeclareExtension i18n_extension_declaration(I18NExtension::get());
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/i18n-extension.h b/src/extensions/experimental/i18n-extension.h
deleted file mode 100644
index 5401f25..0000000
--- a/src/extensions/experimental/i18n-extension.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
-
-#include "include/v8.h"
-
-namespace v8 {
-namespace internal {
-
-
-class I18NExtension : public v8::Extension {
- public:
-  I18NExtension();
-
-  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
-      v8::Handle<v8::String> name);
-
-  // V8 code prefers Register, while Chrome and WebKit use get kind of methods.
-  static void Register();
-  static I18NExtension* get();
-
- private:
-  static I18NExtension* extension_;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_I18N_EXTENSION_H_
diff --git a/src/extensions/experimental/i18n-js2c.py b/src/extensions/experimental/i18n-js2c.py
deleted file mode 100644
index 9c3128b..0000000
--- a/src/extensions/experimental/i18n-js2c.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-#
-# 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.
-
-# This is a utility for converting I18N JavaScript source code into C-style
-# char arrays. It is used for embedded JavaScript code in the V8
-# library.
-# This is a pared down copy of v8/tools/js2c.py that avoids use of
-# v8/src/natives.h and produces different cc template.
-
-import os, re, sys, string
-
-
-def ToCArray(lines):
-  result = []
-  for chr in lines:
-    value = ord(chr)
-    assert value < 128
-    result.append(str(value))
-  result.append("0")
-  return ", ".join(result)
-
-
-def RemoveCommentsAndTrailingWhitespace(lines):
-  lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments
-  lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments.
-  lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace
-  return lines
-
-
-def ReadFile(filename):
-  file = open(filename, "rt")
-  try:
-    lines = file.read()
-  finally:
-    file.close()
-  return lines
-
-
-EVAL_PATTERN = re.compile(r'\beval\s*\(');
-WITH_PATTERN = re.compile(r'\bwith\s*\(');
-
-
-def Validate(lines, file):
-  lines = RemoveCommentsAndTrailingWhitespace(lines)
-  # Because of simplified context setup, eval and with is not
-  # allowed in the natives files.
-  eval_match = EVAL_PATTERN.search(lines)
-  if eval_match:
-    raise ("Eval disallowed in natives: %s" % file)
-  with_match = WITH_PATTERN.search(lines)
-  if with_match:
-    raise ("With statements disallowed in natives: %s" % file)
-
-
-HEADER_TEMPLATE = """\
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-// This file was generated from .js source files by gyp.  If you
-// want to make changes to this file you should either change the
-// javascript source files or the i18n-js2c.py script.
-
-#include "src/extensions/experimental/i18n-natives.h"
-
-namespace v8 {
-namespace internal {
-
-// static
-const char* I18Natives::GetScriptSource() {
-  // JavaScript source gets injected here.
-  static const char i18n_source[] = {%s};
-
-  return i18n_source;
-}
-
-}  // internal
-}  // v8
-"""
-
-
-def JS2C(source, target):
-  filename = str(source)
-
-  lines = ReadFile(filename)
-  Validate(lines, filename)
-  data = ToCArray(lines)
-
-  # Emit result
-  output = open(target, "w")
-  output.write(HEADER_TEMPLATE % data)
-  output.close()
-
-
-def main():
-  target = sys.argv[1]
-  source = sys.argv[2]
-  JS2C(source, target)
-
-
-if __name__ == "__main__":
-  main()
diff --git a/src/extensions/experimental/i18n-locale.cc b/src/extensions/experimental/i18n-locale.cc
deleted file mode 100644
index 46a5f87..0000000
--- a/src/extensions/experimental/i18n-locale.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-#include "src/extensions/experimental/i18n-locale.h"
-
-#include "src/extensions/experimental/i18n-utils.h"
-#include "src/extensions/experimental/language-matcher.h"
-#include "unicode/locid.h"
-#include "unicode/uloc.h"
-
-namespace v8 {
-namespace internal {
-
-const char* const I18NLocale::kLocaleID = "localeID";
-const char* const I18NLocale::kRegionID = "regionID";
-const char* const I18NLocale::kICULocaleID = "icuLocaleID";
-
-v8::Handle<v8::Value> I18NLocale::JSLocale(const v8::Arguments& args) {
-  v8::HandleScope handle_scope;
-
-  if (args.Length() != 1 || !args[0]->IsObject()) {
-    return v8::Undefined();
-  }
-
-  v8::Local<v8::Object> settings = args[0]->ToObject();
-
-  // Get best match for locale.
-  v8::TryCatch try_catch;
-  v8::Handle<v8::Value> locale_id = settings->Get(v8::String::New(kLocaleID));
-  if (try_catch.HasCaught()) {
-    return v8::Undefined();
-  }
-
-  LocaleIDMatch result;
-  if (locale_id->IsArray()) {
-    LanguageMatcher::GetBestMatchForPriorityList(
-        v8::Handle<v8::Array>::Cast(locale_id), &result);
-  } else if (locale_id->IsString()) {
-    LanguageMatcher::GetBestMatchForString(locale_id->ToString(), &result);
-  } else {
-    LanguageMatcher::GetBestMatchForString(v8::String::New(""), &result);
-  }
-
-  // Get best match for region.
-  char region_id[ULOC_COUNTRY_CAPACITY];
-  I18NUtils::StrNCopy(region_id, ULOC_COUNTRY_CAPACITY, "");
-
-  v8::Handle<v8::Value> region = settings->Get(v8::String::New(kRegionID));
-  if (try_catch.HasCaught()) {
-    return v8::Undefined();
-  }
-
-  if (!GetBestMatchForRegionID(result.icu_id, region, region_id)) {
-    // Set region id to empty string because region couldn't be inferred.
-    I18NUtils::StrNCopy(region_id, ULOC_COUNTRY_CAPACITY, "");
-  }
-
-  // Build JavaScript object that contains bcp and icu locale ID and region ID.
-  v8::Handle<v8::Object> locale = v8::Object::New();
-  locale->Set(v8::String::New(kLocaleID), v8::String::New(result.bcp47_id));
-  locale->Set(v8::String::New(kICULocaleID), v8::String::New(result.icu_id));
-  locale->Set(v8::String::New(kRegionID), v8::String::New(region_id));
-
-  return handle_scope.Close(locale);
-}
-
-bool I18NLocale::GetBestMatchForRegionID(
-    const char* locale_id, v8::Handle<v8::Value> region_id, char* result) {
-  if (region_id->IsString() && region_id->ToString()->Length() != 0) {
-    icu::Locale user_locale(
-        icu::Locale("und", *v8::String::Utf8Value(region_id->ToString())));
-    I18NUtils::StrNCopy(
-        result, ULOC_COUNTRY_CAPACITY, user_locale.getCountry());
-    return true;
-  }
-  // Maximize locale_id to infer the region (e.g. expand "de" to "de-Latn-DE"
-  // and grab "DE" from the result).
-  UErrorCode status = U_ZERO_ERROR;
-  char maximized_locale[ULOC_FULLNAME_CAPACITY];
-  uloc_addLikelySubtags(
-      locale_id, maximized_locale, ULOC_FULLNAME_CAPACITY, &status);
-  uloc_getCountry(maximized_locale, result, ULOC_COUNTRY_CAPACITY, &status);
-
-  return !U_FAILURE(status);
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/i18n-locale.h b/src/extensions/experimental/i18n-locale.h
deleted file mode 100644
index 607818c..0000000
--- a/src/extensions/experimental/i18n-locale.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
-
-#include "include/v8.h"
-
-namespace v8 {
-namespace internal {
-
-class I18NLocale {
- public:
-  I18NLocale() {}
-
-  // Implementations of window.Locale methods.
-  static v8::Handle<v8::Value> JSLocale(const v8::Arguments& args);
-
-  // Infers region id given the locale id, or uses user specified region id.
-  // Result is canonicalized.
-  // Returns status of ICU operation (maximizing locale or get region call).
-  static bool GetBestMatchForRegionID(
-      const char* locale_id, v8::Handle<v8::Value> regions, char* result);
-
- private:
-  // Key name for localeID parameter.
-  static const char* const kLocaleID;
-  // Key name for regionID parameter.
-  static const char* const kRegionID;
-  // Key name for the icuLocaleID result.
-  static const char* const kICULocaleID;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_I18N_LOCALE_H_
diff --git a/src/extensions/experimental/i18n-natives.h b/src/extensions/experimental/i18n-natives.h
deleted file mode 100644
index 37362d0..0000000
--- a/src/extensions/experimental/i18n-natives.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
-
-namespace v8 {
-namespace internal {
-
-class I18Natives {
- public:
-  // Gets script source from generated file.
-  // Source is statically allocated string.
-  static const char* GetScriptSource();
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_I18N_NATIVES_H_
diff --git a/src/extensions/experimental/i18n-utils.cc b/src/extensions/experimental/i18n-utils.cc
deleted file mode 100644
index dc2be1a..0000000
--- a/src/extensions/experimental/i18n-utils.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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.
-
-#include "src/extensions/experimental/i18n-utils.h"
-
-#include <string.h>
-
-#include "unicode/unistr.h"
-
-namespace v8 {
-namespace internal {
-
-// static
-void I18NUtils::StrNCopy(char* dest, int length, const char* src) {
-  if (!dest || !src) return;
-
-  strncpy(dest, src, length);
-  dest[length - 1] = '\0';
-}
-
-// static
-bool I18NUtils::ExtractStringSetting(const v8::Handle<v8::Object>& settings,
-                                     const char* setting,
-                                     icu::UnicodeString* result) {
-  if (!setting || !result) return false;
-
-  v8::HandleScope handle_scope;
-  v8::TryCatch try_catch;
-  v8::Handle<v8::Value> value = settings->Get(v8::String::New(setting));
-  if (try_catch.HasCaught()) {
-    return false;
-  }
-  // No need to check if |value| is empty because it's taken care of
-  // by TryCatch above.
-  if (!value->IsUndefined() && !value->IsNull() && value->IsString()) {
-    v8::String::Utf8Value utf8_value(value);
-    if (*utf8_value == NULL) return false;
-    result->setTo(icu::UnicodeString::fromUTF8(*utf8_value));
-    return true;
-  }
-  return false;
-}
-
-// static
-void I18NUtils::AsciiToUChar(const char* source,
-                             int32_t source_length,
-                             UChar* target,
-                             int32_t target_length) {
-  int32_t length =
-      source_length < target_length ? source_length : target_length;
-
-  if (length <= 0) {
-    return;
-  }
-
-  for (int32_t i = 0; i < length - 1; ++i) {
-    target[i] = static_cast<UChar>(source[i]);
-  }
-
-  target[length - 1] = 0x0u;
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/i18n-utils.h b/src/extensions/experimental/i18n-utils.h
deleted file mode 100644
index 7c31528..0000000
--- a/src/extensions/experimental/i18n-utils.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
-
-#include "include/v8.h"
-
-#include "unicode/uversion.h"
-
-namespace U_ICU_NAMESPACE {
-class UnicodeString;
-}
-
-namespace v8 {
-namespace internal {
-
-class I18NUtils {
- public:
-  // Safe string copy. Null terminates the destination. Copies at most
-  // (length - 1) bytes.
-  // We can't use snprintf since it's not supported on all relevant platforms.
-  // We can't use OS::SNPrintF, it's only for internal code.
-  static void StrNCopy(char* dest, int length, const char* src);
-
-  // Extract a string setting named in |settings| and set it to |result|.
-  // Return true if it's specified. Otherwise, return false.
-  static bool ExtractStringSetting(const v8::Handle<v8::Object>& settings,
-                                   const char* setting,
-                                   icu::UnicodeString* result);
-
-  // Converts ASCII array into UChar array.
-  // Target is always \0 terminated.
-  static void AsciiToUChar(const char* source,
-                           int32_t source_length,
-                           UChar* target,
-                           int32_t target_length);
-
- private:
-  I18NUtils() {}
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_I18N_UTILS_H_
diff --git a/src/extensions/experimental/i18n.js b/src/extensions/experimental/i18n.js
deleted file mode 100644
index 56bcf9e..0000000
--- a/src/extensions/experimental/i18n.js
+++ /dev/null
@@ -1,380 +0,0 @@
-// 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): Rename v8Locale into LocaleInfo once we have stable API.
-/**
- * LocaleInfo class is an aggregate class of all i18n API calls.
- * @param {Object} settings - localeID and regionID to create LocaleInfo from.
- *   {Array.<string>|string} settings.localeID -
- *     Unicode identifier of the locale.
- *     See http://unicode.org/reports/tr35/#BCP_47_Conformance
- *   {string} settings.regionID - ISO3166 region ID with addition of
- *     invalid, undefined and reserved region codes.
- * @constructor
- */
-v8Locale = function(settings) {
-  native function NativeJSLocale();
-
-  // Assume user wanted to do v8Locale("sr");
-  if (typeof(settings) === "string") {
-    settings = {'localeID': settings};
-  }
-
-  var properties = NativeJSLocale(
-      v8Locale.__createSettingsOrDefault(settings, {'localeID': 'root'}));
-
-  // Keep the resolved ICU locale ID around to avoid resolving localeID to
-  // ICU locale ID every time BreakIterator, Collator and so forth are called.
-  this.__icuLocaleID = properties.icuLocaleID;
-  this.options = {'localeID': properties.localeID,
-                  'regionID': properties.regionID};
-};
-
-/**
- * Clones existing locale with possible overrides for some of the options.
- * @param {!Object} settings - overrides for current locale settings.
- * @returns {Object} - new LocaleInfo object.
- */
-v8Locale.prototype.derive = function(settings) {
-  return new v8Locale(
-      v8Locale.__createSettingsOrDefault(settings, this.options));
-};
-
-/**
- * v8BreakIterator class implements locale aware segmenatation.
- * It is not part of EcmaScript proposal.
- * @param {Object} locale - locale object to pass to break
- *   iterator implementation.
- * @param {string} type - type of segmenatation:
- *   - character
- *   - word
- *   - sentence
- *   - line
- * @private
- * @constructor
- */
-v8Locale.v8BreakIterator = function(locale, type) {
-  native function NativeJSBreakIterator();
-
-  locale = v8Locale.__createLocaleOrDefault(locale);
-  // BCP47 ID would work in this case, but we use ICU locale for consistency.
-  var iterator = NativeJSBreakIterator(locale.__icuLocaleID, type);
-  iterator.type = type;
-  return iterator;
-};
-
-/**
- * Type of the break we encountered during previous iteration.
- * @type{Enum}
- */
-v8Locale.v8BreakIterator.BreakType = {
-  'unknown': -1,
-  'none': 0,
-  'number': 100,
-  'word': 200,
-  'kana': 300,
-  'ideo': 400
-};
-
-/**
- * Creates new v8BreakIterator based on current locale.
- * @param {string} - type of segmentation. See constructor.
- * @returns {Object} - new v8BreakIterator object.
- */
-v8Locale.prototype.v8CreateBreakIterator = function(type) {
-  return new v8Locale.v8BreakIterator(this, type);
-};
-
-// TODO(jungshik): Set |collator.options| to actually recognized / resolved
-// values.
-/**
- * Collator class implements locale-aware sort.
- * @param {Object} locale - locale object to pass to collator implementation.
- * @param {Object} settings - collation flags:
- *   - ignoreCase
- *   - ignoreAccents
- *   - numeric
- * @private
- * @constructor
- */
-v8Locale.Collator = function(locale, settings) {
-  native function NativeJSCollator();
-
-  locale = v8Locale.__createLocaleOrDefault(locale);
-  var collator = NativeJSCollator(
-      locale.__icuLocaleID, v8Locale.__createSettingsOrDefault(settings, {}));
-  return collator;
-};
-
-/**
- * Creates new Collator based on current locale.
- * @param {Object} - collation flags. See constructor.
- * @returns {Object} - new Collator object.
- */
-v8Locale.prototype.createCollator = function(settings) {
-  return new v8Locale.Collator(this, settings);
-};
-
-/**
- * DateTimeFormat class implements locale-aware date and time formatting.
- * Constructor is not part of public API.
- * @param {Object} locale - locale object to pass to formatter.
- * @param {Object} settings - formatting flags:
- *   - skeleton
- *   - dateStyle
- *   - timeStyle
- * @private
- * @constructor
- */
-v8Locale.__DateTimeFormat = function(locale, settings) {
-  native function NativeJSDateTimeFormat();
-
-  settings = v8Locale.__createSettingsOrDefault(settings, {});
-
-  var cleanSettings = {};
-  if (settings.hasOwnProperty('skeleton')) {
-    cleanSettings['skeleton'] = settings['skeleton'];
-  } else {
-    cleanSettings = {};
-    if (settings.hasOwnProperty('dateStyle')) {
-      var ds = settings['dateStyle'];
-      if (!/^(short|medium|long|full)$/.test(ds)) ds = 'short';
-      cleanSettings['dateStyle'] = ds;
-    } else if (settings.hasOwnProperty('dateType')) {
-      // Obsolete. New spec requires dateStyle, but we'll keep this around
-      // for current users.
-      // TODO(cira): Remove when all internal users switch to dateStyle.
-      var dt = settings['dateType'];
-      if (!/^(short|medium|long|full)$/.test(dt)) dt = 'short';
-      cleanSettings['dateStyle'] = dt;
-    }
-
-    if (settings.hasOwnProperty('timeStyle')) {
-      var ts = settings['timeStyle'];
-      if (!/^(short|medium|long|full)$/.test(ts)) ts = 'short';
-      cleanSettings['timeStyle'] = ts;
-    } else if (settings.hasOwnProperty('timeType')) {
-      // TODO(cira): Remove when all internal users switch to timeStyle.
-      var tt = settings['timeType'];
-      if (!/^(short|medium|long|full)$/.test(tt)) tt = 'short';
-      cleanSettings['timeStyle'] = tt;
-    }
-  }
-
-  // Default is to show short date and time.
-  if (!cleanSettings.hasOwnProperty('skeleton') &&
-      !cleanSettings.hasOwnProperty('dateStyle') &&
-      !cleanSettings.hasOwnProperty('timeStyle')) {
-    cleanSettings = {'dateStyle': 'short',
-                     'timeStyle': 'short'};
-  }
-
-  locale = v8Locale.__createLocaleOrDefault(locale);
-  var formatter = NativeJSDateTimeFormat(locale.__icuLocaleID, cleanSettings);
-
-  // NativeJSDateTimeFormat creates formatter.options for us, we just need
-  // to append actual settings to it.
-  for (key in cleanSettings) {
-    formatter.options[key] = cleanSettings[key];
-  }
-
-  /**
-   * Clones existing date time format with possible overrides for some
-   * of the options.
-   * @param {!Object} overrideSettings - overrides for current format settings.
-   * @returns {Object} - new DateTimeFormat object.
-   * @public
-   */
-  formatter.derive = function(overrideSettings) {
-    // To remove a setting user can specify undefined as its value. We'll remove
-    // it from the map in that case.
-    for (var prop in overrideSettings) {
-      if (settings.hasOwnProperty(prop) && !overrideSettings[prop]) {
-        delete settings[prop];
-      }
-    }
-    return new v8Locale.__DateTimeFormat(
-        locale, v8Locale.__createSettingsOrDefault(overrideSettings, settings));
-  };
-
-  return formatter;
-};
-
-/**
- * Creates new DateTimeFormat based on current locale.
- * @param {Object} - formatting flags. See constructor.
- * @returns {Object} - new DateTimeFormat object.
- */
-v8Locale.prototype.createDateTimeFormat = function(settings) {
-  return new v8Locale.__DateTimeFormat(this, settings);
-};
-
-/**
- * NumberFormat class implements locale-aware number formatting.
- * Constructor is not part of public API.
- * @param {Object} locale - locale object to pass to formatter.
- * @param {Object} settings - formatting flags:
- *   - skeleton
- *   - pattern
- *   - style - decimal, currency, percent or scientific
- *   - currencyCode - ISO 4217 3-letter currency code
- * @private
- * @constructor
- */
-v8Locale.__NumberFormat = function(locale, settings) {
-  native function NativeJSNumberFormat();
-
-  settings = v8Locale.__createSettingsOrDefault(settings, {});
-
-  var cleanSettings = {};
-  if (settings.hasOwnProperty('skeleton')) {
-    // Assign skeleton to cleanSettings and fix invalid currency pattern
-    // if present - 'ooxo' becomes 'o'.
-    cleanSettings['skeleton'] =
-        settings['skeleton'].replace(/\u00a4+[^\u00a4]+\u00a4+/g, '\u00a4');
-  } else if (settings.hasOwnProperty('pattern')) {
-    cleanSettings['pattern'] = settings['pattern'];
-  } else if (settings.hasOwnProperty('style')) {
-    var style = settings['style'];
-    if (!/^(decimal|currency|percent|scientific)$/.test(style)) {
-      style = 'decimal';
-    }
-    cleanSettings['style'] = style;
-  }
-
-  // Default is to show decimal style.
-  if (!cleanSettings.hasOwnProperty('skeleton') &&
-      !cleanSettings.hasOwnProperty('pattern') &&
-      !cleanSettings.hasOwnProperty('style')) {
-    cleanSettings = {'style': 'decimal'};
-  }
-
-  // Add currency code if available and valid (3-letter ASCII code).
-  if (settings.hasOwnProperty('currencyCode') &&
-      /^[a-zA-Z]{3}$/.test(settings['currencyCode'])) {
-    cleanSettings['currencyCode'] = settings['currencyCode'].toUpperCase();
-  }
-
-  locale = v8Locale.__createLocaleOrDefault(locale);
-  // Pass in region ID for proper currency detection. Use ZZ if region is empty.
-  var region = locale.options.regionID !== '' ? locale.options.regionID : 'ZZ';
-  var formatter = NativeJSNumberFormat(
-      locale.__icuLocaleID, 'und_' + region, cleanSettings);
-
-  // ICU doesn't always uppercase the currency code.
-  if (formatter.options.hasOwnProperty('currencyCode')) {
-    formatter.options['currencyCode'] =
-        formatter.options['currencyCode'].toUpperCase();
-  }
-
-  for (key in cleanSettings) {
-    // Don't overwrite keys that are alredy in.
-    if (formatter.options.hasOwnProperty(key)) continue;
-
-    formatter.options[key] = cleanSettings[key];
-  }
-
-  /**
-   * Clones existing number format with possible overrides for some
-   * of the options.
-   * @param {!Object} overrideSettings - overrides for current format settings.
-   * @returns {Object} - new or cached NumberFormat object.
-   * @public
-   */
-  formatter.derive = function(overrideSettings) {
-    // To remove a setting user can specify undefined as its value. We'll remove
-    // it from the map in that case.
-    for (var prop in overrideSettings) {
-      if (settings.hasOwnProperty(prop) && !overrideSettings[prop]) {
-        delete settings[prop];
-      }
-    }
-    return new v8Locale.__NumberFormat(
-        locale, v8Locale.__createSettingsOrDefault(overrideSettings, settings));
-  };
-
-  return formatter;
-};
-
-/**
- * Creates new NumberFormat based on current locale.
- * @param {Object} - formatting flags. See constructor.
- * @returns {Object} - new or cached NumberFormat object.
- */
-v8Locale.prototype.createNumberFormat = function(settings) {
-  return new v8Locale.__NumberFormat(this, settings);
-};
-
-/**
- * Merges user settings and defaults.
- * Settings that are not of object type are rejected.
- * Actual property values are not validated, but whitespace is trimmed if they
- * are strings.
- * @param {!Object} settings - user provided settings.
- * @param {!Object} defaults - default values for this type of settings.
- * @returns {Object} - valid settings object.
- * @private
- */
-v8Locale.__createSettingsOrDefault = function(settings, defaults) {
-  if (!settings || typeof(settings) !== 'object' ) {
-    return defaults;
-  }
-  for (var key in defaults) {
-    if (!settings.hasOwnProperty(key)) {
-      settings[key] = defaults[key];
-    }
-  }
-  // Clean up settings.
-  for (var key in settings) {
-    // Trim whitespace.
-    if (typeof(settings[key]) === "string") {
-      settings[key] = settings[key].trim();
-    }
-    // Remove all properties that are set to undefined/null. This allows
-    // derive method to remove a setting we don't need anymore.
-    if (!settings[key]) {
-      delete settings[key];
-    }
-  }
-
-  return settings;
-};
-
-/**
- * If locale is valid (defined and of v8Locale type) we return it. If not
- * we create default locale and return it.
- * @param {!Object} locale - user provided locale.
- * @returns {Object} - v8Locale object.
- * @private
- */
-v8Locale.__createLocaleOrDefault = function(locale) {
-  if (!locale || !(locale instanceof v8Locale)) {
-    return new v8Locale();
-  } else {
-    return locale;
-  }
-};
diff --git a/src/extensions/experimental/language-matcher.cc b/src/extensions/experimental/language-matcher.cc
deleted file mode 100644
index 127e571..0000000
--- a/src/extensions/experimental/language-matcher.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-// 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.
-
-// TODO(cira): Remove LanguageMatcher from v8 when ICU implements
-// language matching API.
-
-#include "src/extensions/experimental/language-matcher.h"
-
-#include <string.h>
-
-#include "src/extensions/experimental/i18n-utils.h"
-#include "unicode/datefmt.h"  // For getAvailableLocales
-#include "unicode/locid.h"
-#include "unicode/uloc.h"
-
-namespace v8 {
-namespace internal {
-
-const unsigned int LanguageMatcher::kLanguageWeight = 75;
-const unsigned int LanguageMatcher::kScriptWeight = 20;
-const unsigned int LanguageMatcher::kRegionWeight = 5;
-const unsigned int LanguageMatcher::kThreshold = 50;
-const unsigned int LanguageMatcher::kPositionBonus = 1;
-const char* const LanguageMatcher::kDefaultLocale = "root";
-
-static const char* GetLanguageException(const char*);
-static bool BCP47ToICUFormat(const char*, char*);
-static int CompareLocaleSubtags(const char*, const char*);
-static bool BuildLocaleName(const char*, const char*, LocaleIDMatch*);
-
-LocaleIDMatch::LocaleIDMatch()
-    : score(-1) {
-  I18NUtils::StrNCopy(
-      bcp47_id, ULOC_FULLNAME_CAPACITY, LanguageMatcher::kDefaultLocale);
-
-  I18NUtils::StrNCopy(
-      icu_id, ULOC_FULLNAME_CAPACITY, LanguageMatcher::kDefaultLocale);
-}
-
-LocaleIDMatch& LocaleIDMatch::operator=(const LocaleIDMatch& rhs) {
-  I18NUtils::StrNCopy(this->bcp47_id, ULOC_FULLNAME_CAPACITY, rhs.bcp47_id);
-  I18NUtils::StrNCopy(this->icu_id, ULOC_FULLNAME_CAPACITY, rhs.icu_id);
-  this->score = rhs.score;
-
-  return *this;
-}
-
-// static
-void LanguageMatcher::GetBestMatchForPriorityList(
-    v8::Handle<v8::Array> locales, LocaleIDMatch* result) {
-  v8::HandleScope handle_scope;
-
-  unsigned int position_bonus = locales->Length() * kPositionBonus;
-
-  int max_score = 0;
-  LocaleIDMatch match;
-  for (unsigned int i = 0; i < locales->Length(); ++i) {
-    position_bonus -= kPositionBonus;
-
-    v8::TryCatch try_catch;
-    v8::Local<v8::Value> locale_id = locales->Get(v8::Integer::New(i));
-
-    // Return default if exception is raised when reading parameter.
-    if (try_catch.HasCaught()) break;
-
-    // JavaScript arrays can be heterogenous so check each item
-    // if it's a string.
-    if (!locale_id->IsString()) continue;
-
-    if (!CompareToSupportedLocaleIDList(locale_id->ToString(), &match)) {
-      continue;
-    }
-
-    // Skip items under threshold.
-    if (match.score < kThreshold) continue;
-
-    match.score += position_bonus;
-    if (match.score > max_score) {
-      *result = match;
-
-      max_score = match.score;
-    }
-  }
-}
-
-// static
-void LanguageMatcher::GetBestMatchForString(
-    v8::Handle<v8::String> locale, LocaleIDMatch* result) {
-  LocaleIDMatch match;
-
-  if (CompareToSupportedLocaleIDList(locale, &match) &&
-      match.score >= kThreshold) {
-    *result = match;
-  }
-}
-
-// static
-bool LanguageMatcher::CompareToSupportedLocaleIDList(
-    v8::Handle<v8::String> locale_id, LocaleIDMatch* result) {
-  static int32_t available_count = 0;
-  // Depending on how ICU data is built, locales returned by
-  // Locale::getAvailableLocale() are not guaranteed to support DateFormat,
-  // Collation and other services.  We can call getAvailableLocale() of all the
-  // services we want to support and take the intersection of them all, but
-  // using DateFormat::getAvailableLocales() should suffice.
-  // TODO(cira): Maybe make this thread-safe?
-  static const icu::Locale* available_locales =
-      icu::DateFormat::getAvailableLocales(available_count);
-
-  // Skip this locale_id if it's not in ASCII.
-  static LocaleIDMatch default_match;
-  v8::String::AsciiValue ascii_value(locale_id);
-  if (*ascii_value == NULL) return false;
-
-  char locale[ULOC_FULLNAME_CAPACITY];
-  if (!BCP47ToICUFormat(*ascii_value, locale)) return false;
-
-  icu::Locale input_locale(locale);
-
-  // Position of the best match locale in list of available locales.
-  int position = -1;
-  const char* language = GetLanguageException(input_locale.getLanguage());
-  const char* script = input_locale.getScript();
-  const char* region = input_locale.getCountry();
-  for (int32_t i = 0; i < available_count; ++i) {
-    int current_score = 0;
-    int sign =
-        CompareLocaleSubtags(language, available_locales[i].getLanguage());
-    current_score += sign * kLanguageWeight;
-
-    sign = CompareLocaleSubtags(script, available_locales[i].getScript());
-    current_score += sign * kScriptWeight;
-
-    sign = CompareLocaleSubtags(region, available_locales[i].getCountry());
-    current_score += sign * kRegionWeight;
-
-    if (current_score >= kThreshold && current_score > result->score) {
-      result->score = current_score;
-      position = i;
-    }
-  }
-
-  // Didn't find any good matches so use defaults.
-  if (position == -1) return false;
-
-  return BuildLocaleName(available_locales[position].getBaseName(),
-                         input_locale.getName(), result);
-}
-
-// For some unsupported language subtags it is better to fallback to related
-// language that is supported than to default.
-static const char* GetLanguageException(const char* language) {
-  // Serbo-croatian to Serbian.
-  if (!strcmp(language, "sh")) return "sr";
-
-  // Norweigan to Norweiaan to Norwegian Bokmal.
-  if (!strcmp(language, "no")) return "nb";
-
-  // Moldavian to Romanian.
-  if (!strcmp(language, "mo")) return "ro";
-
-  // Tagalog to Filipino.
-  if (!strcmp(language, "tl")) return "fil";
-
-  return language;
-}
-
-// Converts user input from BCP47 locale id format to ICU compatible format.
-// Returns false if uloc_forLanguageTag call fails or if extension is too long.
-static bool BCP47ToICUFormat(const char* locale_id, char* result) {
-  UErrorCode status = U_ZERO_ERROR;
-  int32_t locale_size = 0;
-
-  char locale[ULOC_FULLNAME_CAPACITY];
-  I18NUtils::StrNCopy(locale, ULOC_FULLNAME_CAPACITY, locale_id);
-
-  // uloc_forLanguageTag has a bug where long extension can crash the code.
-  // We need to check if extension part of language id conforms to the length.
-  // ICU bug: http://bugs.icu-project.org/trac/ticket/8519
-  const char* extension = strstr(locale_id, "-u-");
-  if (extension != NULL &&
-      strlen(extension) > ULOC_KEYWORD_AND_VALUES_CAPACITY) {
-    // Truncate to get non-crashing string, but still preserve base language.
-    int base_length = strlen(locale_id) - strlen(extension);
-    locale[base_length] = '\0';
-  }
-
-  uloc_forLanguageTag(locale, result, ULOC_FULLNAME_CAPACITY,
-                      &locale_size, &status);
-  return !U_FAILURE(status);
-}
-
-// Compares locale id subtags.
-// Returns 1 for match or -1 for mismatch.
-static int CompareLocaleSubtags(const char* lsubtag, const char* rsubtag) {
-  return strcmp(lsubtag, rsubtag) == 0 ? 1 : -1;
-}
-
-// Builds a BCP47 compliant locale id from base name of matched locale and
-// full user specified locale.
-// Returns false if uloc_toLanguageTag failed to convert locale id.
-// Example:
-//   base_name of matched locale (ICU ID): de_DE
-//   input_locale_name (ICU ID): de_AT@collation=phonebk
-//   result (ICU ID): de_DE@collation=phonebk
-//   result (BCP47 ID): de-DE-u-co-phonebk
-static bool BuildLocaleName(const char* base_name,
-                            const char* input_locale_name,
-                            LocaleIDMatch* result) {
-  I18NUtils::StrNCopy(result->icu_id, ULOC_LANG_CAPACITY, base_name);
-
-  // Get extensions (if any) from the original locale.
-  const char* extension = strchr(input_locale_name, ULOC_KEYWORD_SEPARATOR);
-  if (extension != NULL) {
-    I18NUtils::StrNCopy(result->icu_id + strlen(base_name),
-                        ULOC_KEYWORD_AND_VALUES_CAPACITY, extension);
-  } else {
-    I18NUtils::StrNCopy(result->icu_id, ULOC_LANG_CAPACITY, base_name);
-  }
-
-  // Convert ICU locale name into BCP47 format.
-  UErrorCode status = U_ZERO_ERROR;
-  uloc_toLanguageTag(result->icu_id, result->bcp47_id,
-                     ULOC_FULLNAME_CAPACITY, false, &status);
-  return !U_FAILURE(status);
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/language-matcher.h b/src/extensions/experimental/language-matcher.h
deleted file mode 100644
index dd29304..0000000
--- a/src/extensions/experimental/language-matcher.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
-
-#include "include/v8.h"
-
-#include "unicode/uloc.h"
-
-namespace v8 {
-namespace internal {
-
-struct LocaleIDMatch {
-  LocaleIDMatch();
-
-  LocaleIDMatch& operator=(const LocaleIDMatch& rhs);
-
-  // Bcp47 locale id - "de-Latn-DE-u-co-phonebk".
-  char bcp47_id[ULOC_FULLNAME_CAPACITY];
-
-  // ICU locale id - "de_Latn_DE@collation=phonebk".
-  char icu_id[ULOC_FULLNAME_CAPACITY];
-
-  // Score for this locale.
-  int score;
-};
-
-class LanguageMatcher {
- public:
-  // Default locale.
-  static const char* const kDefaultLocale;
-
-  // Finds best supported locale for a given a list of locale identifiers.
-  // It preserves the extension for the locale id.
-  static void GetBestMatchForPriorityList(
-      v8::Handle<v8::Array> locale_list, LocaleIDMatch* result);
-
-  // Finds best supported locale for a single locale identifier.
-  // It preserves the extension for the locale id.
-  static void GetBestMatchForString(
-      v8::Handle<v8::String> locale_id, LocaleIDMatch* result);
-
- private:
-  // If langauge subtags match add this amount to the score.
-  static const unsigned int kLanguageWeight;
-
-  // If script subtags match add this amount to the score.
-  static const unsigned int kScriptWeight;
-
-  // If region subtags match add this amount to the score.
-  static const unsigned int kRegionWeight;
-
-  // LocaleID match score has to be over this number to accept the match.
-  static const unsigned int kThreshold;
-
-  // For breaking ties in priority queue.
-  static const unsigned int kPositionBonus;
-
-  LanguageMatcher();
-
-  // Compares locale_id to the supported list of locales and returns best
-  // match.
-  // Returns false if it fails to convert locale id from ICU to BCP47 format.
-  static bool CompareToSupportedLocaleIDList(v8::Handle<v8::String> locale_id,
-                                             LocaleIDMatch* result);
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_LANGUAGE_MATCHER_H_
diff --git a/src/extensions/experimental/number-format.cc b/src/extensions/experimental/number-format.cc
deleted file mode 100644
index 2932c52..0000000
--- a/src/extensions/experimental/number-format.cc
+++ /dev/null
@@ -1,374 +0,0 @@
-// 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.
-
-#include "src/extensions/experimental/number-format.h"
-
-#include <string.h>
-
-#include "src/extensions/experimental/i18n-utils.h"
-#include "unicode/dcfmtsym.h"
-#include "unicode/decimfmt.h"
-#include "unicode/locid.h"
-#include "unicode/numfmt.h"
-#include "unicode/uchar.h"
-#include "unicode/ucurr.h"
-#include "unicode/unum.h"
-#include "unicode/uversion.h"
-
-namespace v8 {
-namespace internal {
-
-const int NumberFormat::kCurrencyCodeLength = 4;
-
-v8::Persistent<v8::FunctionTemplate> NumberFormat::number_format_template_;
-
-static icu::DecimalFormat* CreateNumberFormat(v8::Handle<v8::String>,
-                                              v8::Handle<v8::String>,
-                                              v8::Handle<v8::Object>);
-static icu::DecimalFormat* CreateFormatterFromSkeleton(
-    const icu::Locale&, const icu::UnicodeString&, UErrorCode*);
-static icu::DecimalFormatSymbols* GetFormatSymbols(const icu::Locale&);
-static bool GetCurrencyCode(const icu::Locale&,
-                            const char* const,
-                            v8::Handle<v8::Object>,
-                            UChar*);
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError();
-
-icu::DecimalFormat* NumberFormat::UnpackNumberFormat(
-    v8::Handle<v8::Object> obj) {
-  if (number_format_template_->HasInstance(obj)) {
-    return static_cast<icu::DecimalFormat*>(
-        obj->GetPointerFromInternalField(0));
-  }
-
-  return NULL;
-}
-
-void NumberFormat::DeleteNumberFormat(v8::Persistent<v8::Value> object,
-                                      void* param) {
-  v8::Persistent<v8::Object> persistent_object =
-      v8::Persistent<v8::Object>::Cast(object);
-
-  // First delete the hidden C++ object.
-  // Unpacking should never return NULL here. That would only happen if
-  // this method is used as the weak callback for persistent handles not
-  // pointing to a number formatter.
-  delete UnpackNumberFormat(persistent_object);
-
-  // Then dispose of the persistent handle to JS object.
-  persistent_object.Dispose();
-}
-
-v8::Handle<v8::Value> NumberFormat::Format(const v8::Arguments& args) {
-  v8::HandleScope handle_scope;
-
-  if (args.Length() != 1 || !args[0]->IsNumber()) {
-    // Just return NaN on invalid input.
-    return v8::String::New("NaN");
-  }
-
-  icu::DecimalFormat* number_format = UnpackNumberFormat(args.Holder());
-  if (!number_format) {
-    return ThrowUnexpectedObjectError();
-  }
-
-  // ICU will handle actual NaN value properly and return NaN string.
-  icu::UnicodeString result;
-  number_format->format(args[0]->NumberValue(), result);
-
-  return v8::String::New(
-      reinterpret_cast<const uint16_t*>(result.getBuffer()), result.length());
-}
-
-v8::Handle<v8::Value> NumberFormat::JSNumberFormat(const v8::Arguments& args) {
-  v8::HandleScope handle_scope;
-
-  // Expect locale id, region id and settings.
-  if (args.Length() != 3 ||
-      !args[0]->IsString() || !args[1]->IsString() || !args[2]->IsObject()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
-        v8::String::New("Locale, region and number settings are required.")));
-  }
-
-  icu::DecimalFormat* number_format = CreateNumberFormat(
-      args[0]->ToString(), args[1]->ToString(), args[2]->ToObject());
-
-  if (number_format_template_.IsEmpty()) {
-    v8::Local<v8::FunctionTemplate> raw_template(v8::FunctionTemplate::New());
-
-    raw_template->SetClassName(v8::String::New("v8Locale.NumberFormat"));
-
-    // Define internal field count on instance template.
-    v8::Local<v8::ObjectTemplate> object_template =
-        raw_template->InstanceTemplate();
-
-    // Set aside internal field for icu number formatter.
-    object_template->SetInternalFieldCount(1);
-
-    // Define all of the prototype methods on prototype template.
-    v8::Local<v8::ObjectTemplate> proto = raw_template->PrototypeTemplate();
-    proto->Set(v8::String::New("format"),
-               v8::FunctionTemplate::New(Format));
-
-    number_format_template_ =
-        v8::Persistent<v8::FunctionTemplate>::New(raw_template);
-  }
-
-  // Create an empty object wrapper.
-  v8::Local<v8::Object> local_object =
-      number_format_template_->GetFunction()->NewInstance();
-  v8::Persistent<v8::Object> wrapper =
-      v8::Persistent<v8::Object>::New(local_object);
-
-  // Set number formatter as internal field of the resulting JS object.
-  wrapper->SetPointerInInternalField(0, number_format);
-
-  // Create options key.
-  v8::Local<v8::Object> options = v8::Object::New();
-
-  // Show what ICU decided to use for easier problem tracking.
-  // Keep it as v8 specific extension.
-  icu::UnicodeString pattern;
-  number_format->toPattern(pattern);
-  options->Set(v8::String::New("v8ResolvedPattern"),
-               v8::String::New(reinterpret_cast<const uint16_t*>(
-                   pattern.getBuffer()), pattern.length()));
-
-  // Set resolved currency code in options.currency if not empty.
-  icu::UnicodeString currency(number_format->getCurrency());
-  if (!currency.isEmpty()) {
-    options->Set(v8::String::New("currencyCode"),
-                 v8::String::New(reinterpret_cast<const uint16_t*>(
-                     currency.getBuffer()), currency.length()));
-  }
-
-  wrapper->Set(v8::String::New("options"), options);
-
-  // Make object handle weak so we can delete iterator once GC kicks in.
-  wrapper.MakeWeak(NULL, DeleteNumberFormat);
-
-  return wrapper;
-}
-
-// Returns DecimalFormat.
-static icu::DecimalFormat* CreateNumberFormat(v8::Handle<v8::String> locale,
-                                              v8::Handle<v8::String> region,
-                                              v8::Handle<v8::Object> settings) {
-  v8::HandleScope handle_scope;
-
-  v8::String::AsciiValue ascii_locale(locale);
-  icu::Locale icu_locale(*ascii_locale);
-
-  // Make formatter from skeleton.
-  icu::DecimalFormat* number_format = NULL;
-  UErrorCode status = U_ZERO_ERROR;
-  icu::UnicodeString setting;
-
-  if (I18NUtils::ExtractStringSetting(settings, "skeleton", &setting)) {
-    // TODO(cira): Use ICU skeleton once
-    // http://bugs.icu-project.org/trac/ticket/8610 is resolved.
-    number_format = CreateFormatterFromSkeleton(icu_locale, setting, &status);
-  } else if (I18NUtils::ExtractStringSetting(settings, "pattern", &setting)) {
-    number_format =
-        new icu::DecimalFormat(setting, GetFormatSymbols(icu_locale), status);
-  } else if (I18NUtils::ExtractStringSetting(settings, "style", &setting)) {
-    if (setting == UNICODE_STRING_SIMPLE("currency")) {
-      number_format = static_cast<icu::DecimalFormat*>(
-          icu::NumberFormat::createCurrencyInstance(icu_locale, status));
-    } else if (setting == UNICODE_STRING_SIMPLE("percent")) {
-      number_format = static_cast<icu::DecimalFormat*>(
-          icu::NumberFormat::createPercentInstance(icu_locale, status));
-    } else if (setting == UNICODE_STRING_SIMPLE("scientific")) {
-      number_format = static_cast<icu::DecimalFormat*>(
-          icu::NumberFormat::createScientificInstance(icu_locale, status));
-    } else {
-      // Make it decimal in any other case.
-      number_format = static_cast<icu::DecimalFormat*>(
-          icu::NumberFormat::createInstance(icu_locale, status));
-    }
-  }
-
-  if (U_FAILURE(status)) {
-    delete number_format;
-    status = U_ZERO_ERROR;
-    number_format = static_cast<icu::DecimalFormat*>(
-        icu::NumberFormat::createInstance(icu_locale, status));
-  }
-
-  // Attach appropriate currency code to the formatter.
-  // It affects currency formatters only.
-  // Region is full language identifier in form 'und_' + region id.
-  v8::String::AsciiValue ascii_region(region);
-
-  UChar currency_code[NumberFormat::kCurrencyCodeLength];
-  if (GetCurrencyCode(icu_locale, *ascii_region, settings, currency_code)) {
-    number_format->setCurrency(currency_code, status);
-  }
-
-  return number_format;
-}
-
-// Generates ICU number format pattern from given skeleton.
-// TODO(cira): Remove once ICU includes equivalent method
-// (see http://bugs.icu-project.org/trac/ticket/8610).
-static icu::DecimalFormat* CreateFormatterFromSkeleton(
-    const icu::Locale& icu_locale,
-    const icu::UnicodeString& skeleton,
-    UErrorCode* status) {
-  icu::DecimalFormat skeleton_format(
-      skeleton, GetFormatSymbols(icu_locale), *status);
-
-  // Find out if skeleton contains currency or percent symbol and create
-  // proper instance to tweak.
-  icu::DecimalFormat* base_format = NULL;
-
-  // UChar representation of U+00A4 currency symbol.
-  const UChar currency_symbol = 0xA4u;
-
-  int32_t index = skeleton.indexOf(currency_symbol);
-  if (index != -1) {
-    // Find how many U+00A4 are there. There is at least one.
-    // Case of non-consecutive U+00A4 is taken care of in i18n.js.
-    int32_t end_index = skeleton.lastIndexOf(currency_symbol, index);
-
-#if (U_ICU_VERSION_MAJOR_NUM == 4) && (U_ICU_VERSION_MINOR_NUM <= 6)
-    icu::NumberFormat::EStyles style;
-    switch (end_index - index) {
-      case 0:
-        style = icu::NumberFormat::kCurrencyStyle;
-        break;
-      case 1:
-        style = icu::NumberFormat::kIsoCurrencyStyle;
-        break;
-      default:
-        style = icu::NumberFormat::kPluralCurrencyStyle;
-    }
-#else  // ICU version is 4.8 or above (we ignore versions below 4.0).
-    UNumberFormatStyle style;
-    switch (end_index - index) {
-      case 0:
-        style = UNUM_CURRENCY;
-        break;
-      case 1:
-        style = UNUM_CURRENCY_ISO;
-        break;
-      default:
-        style = UNUM_CURRENCY_PLURAL;
-    }
-#endif
-
-    base_format = static_cast<icu::DecimalFormat*>(
-        icu::NumberFormat::createInstance(icu_locale, style, *status));
-  } else if (skeleton.indexOf('%') != -1) {
-    base_format = static_cast<icu::DecimalFormat*>(
-        icu::NumberFormat::createPercentInstance(icu_locale, *status));
-  } else {
-    // TODO(cira): Handle scientific skeleton.
-    base_format = static_cast<icu::DecimalFormat*>(
-        icu::NumberFormat::createInstance(icu_locale, *status));
-  }
-
-  if (U_FAILURE(*status)) {
-    delete base_format;
-    return NULL;
-  }
-
-  // Copy important information from skeleton to the new formatter.
-  // TODO(cira): copy rounding information from skeleton?
-  base_format->setGroupingUsed(skeleton_format.isGroupingUsed());
-
-  base_format->setMinimumIntegerDigits(
-      skeleton_format.getMinimumIntegerDigits());
-
-  base_format->setMinimumFractionDigits(
-      skeleton_format.getMinimumFractionDigits());
-
-  base_format->setMaximumFractionDigits(
-      skeleton_format.getMaximumFractionDigits());
-
-  return base_format;
-}
-
-// Gets decimal symbols for a locale.
-static icu::DecimalFormatSymbols* GetFormatSymbols(
-    const icu::Locale& icu_locale) {
-  UErrorCode status = U_ZERO_ERROR;
-  icu::DecimalFormatSymbols* symbols =
-      new icu::DecimalFormatSymbols(icu_locale, status);
-
-  if (U_FAILURE(status)) {
-    delete symbols;
-    // Use symbols from default locale.
-    symbols = new icu::DecimalFormatSymbols(status);
-  }
-
-  return symbols;
-}
-
-// Gets currency ISO 4217 3-letter code.
-// Check currencyCode setting first, then @currency=code and in the end
-// try to infer currency code from locale in the form 'und_' + region id.
-// Returns false in case of error.
-static bool GetCurrencyCode(const icu::Locale& icu_locale,
-                            const char* const und_region_locale,
-                            v8::Handle<v8::Object> settings,
-                            UChar* code) {
-  UErrorCode status = U_ZERO_ERROR;
-
-  // If there is user specified currency code, use it.
-  icu::UnicodeString currency;
-  if (I18NUtils::ExtractStringSetting(settings, "currencyCode", &currency)) {
-    currency.extract(code, NumberFormat::kCurrencyCodeLength, status);
-    return true;
-  }
-
-  // If ICU locale has -cu- currency code use it.
-  char currency_code[NumberFormat::kCurrencyCodeLength];
-  int32_t length = icu_locale.getKeywordValue(
-      "currency", currency_code, NumberFormat::kCurrencyCodeLength, status);
-  if (length != 0) {
-    I18NUtils::AsciiToUChar(currency_code, length + 1,
-                            code, NumberFormat::kCurrencyCodeLength);
-    return true;
-  }
-
-  // Otherwise infer currency code from the region id.
-  ucurr_forLocale(
-      und_region_locale, code, NumberFormat::kCurrencyCodeLength, &status);
-
-  return !!U_SUCCESS(status);
-}
-
-// Throws a JavaScript exception.
-static v8::Handle<v8::Value> ThrowUnexpectedObjectError() {
-  // Returns undefined, and schedules an exception to be thrown.
-  return v8::ThrowException(v8::Exception::Error(
-      v8::String::New("NumberFormat method called on an object "
-                      "that is not a NumberFormat.")));
-}
-
-} }  // namespace v8::internal
diff --git a/src/extensions/experimental/number-format.h b/src/extensions/experimental/number-format.h
deleted file mode 100644
index bcfaed6..0000000
--- a/src/extensions/experimental/number-format.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// 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.
-
-#ifndef V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
-#define V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
-
-#include "include/v8.h"
-
-#include "unicode/uversion.h"
-
-namespace U_ICU_NAMESPACE {
-class DecimalFormat;
-}
-
-namespace v8 {
-namespace internal {
-
-class NumberFormat {
- public:
-  // 3-letter ISO 4217 currency code plus \0.
-  static const int kCurrencyCodeLength;
-
-  static v8::Handle<v8::Value> JSNumberFormat(const v8::Arguments& args);
-
-  // Helper methods for various bindings.
-
-  // Unpacks date format object from corresponding JavaScript object.
-  static icu::DecimalFormat* UnpackNumberFormat(
-      v8::Handle<v8::Object> obj);
-
-  // Release memory we allocated for the NumberFormat once the JS object that
-  // holds the pointer gets garbage collected.
-  static void DeleteNumberFormat(v8::Persistent<v8::Value> object,
-                                 void* param);
-
-  // Formats number and returns corresponding string.
-  static v8::Handle<v8::Value> Format(const v8::Arguments& args);
-
- private:
-  NumberFormat();
-
-  static v8::Persistent<v8::FunctionTemplate> number_format_template_;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_EXTENSIONS_EXPERIMENTAL_NUMBER_FORMAT_H_
diff --git a/src/full-codegen.h b/src/full-codegen.h
index a1368c2..0270e13 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -142,11 +142,13 @@
       return previous_;
     }
 
- protected:
+   protected:
     MacroAssembler* masm() { return codegen_->masm(); }
 
     FullCodeGenerator* codegen_;
     NestedStatement* previous_;
+
+   private:
     DISALLOW_COPY_AND_ASSIGN(NestedStatement);
   };
 
diff --git a/src/heap.cc b/src/heap.cc
index fff1319..d97f337 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -583,7 +583,9 @@
   PagedSpace* cell_space = Heap::cell_space();
   LargeObjectSpace* lo_space = Heap::lo_space();
   bool gc_performed = true;
-  while (gc_performed) {
+  int counter = 0;
+  static const int kThreshold = 20;
+  while (gc_performed && counter++ < kThreshold) {
     gc_performed = false;
     if (!new_space->ReserveSpace(new_space_size)) {
       Heap::CollectGarbage(NEW_SPACE);
@@ -622,6 +624,11 @@
       gc_performed = true;
     }
   }
+
+  if (gc_performed) {
+    // Failed to reserve the space after several attempts.
+    V8::FatalProcessOutOfMemory("Heap::ReserveSpace");
+  }
 }
 
 
@@ -6515,11 +6522,17 @@
 
 
 int KeyedLookupCache::Lookup(Map* map, String* name) {
-  int index = Hash(map, name);
+  int index = (Hash(map, name) & kHashMask);
   Key& key = keys_[index];
   if ((key.map == map) && key.name->Equals(name)) {
     return field_offsets_[index];
   }
+  ASSERT(kEntriesPerBucket == 2);  // There are two entries to check.
+  // First entry in the bucket missed, check the second.
+  Key& key2 = keys_[index + 1];
+  if ((key2.map == map) && key2.name->Equals(name)) {
+    return field_offsets_[index + 1];
+  }
   return kNotFound;
 }
 
@@ -6527,8 +6540,14 @@
 void KeyedLookupCache::Update(Map* map, String* name, int field_offset) {
   String* symbol;
   if (HEAP->LookupSymbolIfExists(name, &symbol)) {
-    int index = Hash(map, symbol);
+    int index = (Hash(map, symbol) & kHashMask);
     Key& key = keys_[index];
+    Key& key2 = keys_[index + 1];  // Second entry in the bucket.
+    // Demote the first entry to the second in the bucket.
+    key2.map = key.map;
+    key2.name = key.name;
+    field_offsets_[index + 1] = field_offsets_[index];
+    // Write the new first entry.
     key.map = map;
     key.name = symbol;
     field_offsets_[index] = field_offset;
diff --git a/src/heap.h b/src/heap.h
index 937b034..85df55e 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -2135,9 +2135,11 @@
   // Clear the cache.
   void Clear();
 
-  static const int kLength = 64;
+  static const int kLength = 128;
   static const int kCapacityMask = kLength - 1;
-  static const int kMapHashShift = 2;
+  static const int kMapHashShift = 5;
+  static const int kHashMask = -2;  // Zero the last bit.
+  static const int kEntriesPerBucket = 2;
   static const int kNotFound = -1;
 
  private:
@@ -2613,6 +2615,7 @@
 
   AssertNoAllocation no_alloc;  // i.e. no gc allowed.
 
+ private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer);
 };
 #endif  // DEBUG || LIVE_OBJECT_LIST
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 887e80a..2d32ad1 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -416,18 +416,18 @@
 
 
 void HValue::PrintChangesTo(StringStream* stream) {
-  int changes_flags = ChangesFlags();
-  if (changes_flags == 0) return;
+  GVNFlagSet changes_flags = ChangesFlags();
+  if (changes_flags.IsEmpty()) return;
   stream->Add(" changes[");
-  if (changes_flags == AllSideEffects()) {
+  if (changes_flags == AllSideEffectsFlagSet()) {
     stream->Add("*");
   } else {
     bool add_comma = false;
-#define PRINT_DO(type)                         \
-    if (changes_flags & (1 << kChanges##type)) { \
-      if (add_comma) stream->Add(",");           \
-      add_comma = true;                          \
-      stream->Add(#type);                        \
+#define PRINT_DO(type)                            \
+    if (changes_flags.Contains(kChanges##type)) { \
+      if (add_comma) stream->Add(",");            \
+      add_comma = true;                           \
+      stream->Add(#type);                         \
     }
     GVN_FLAG_LIST(PRINT_DO);
 #undef PRINT_DO
@@ -1408,21 +1408,21 @@
   SetOperandAt(0, context);
   SetOperandAt(1, object);
   set_representation(Representation::Tagged());
-  SetFlag(kDependsOnMaps);
+  SetGVNFlag(kDependsOnMaps);
   for (int i = 0;
        i < types->length() && types_.length() < kMaxLoadPolymorphism;
        ++i) {
     Handle<Map> map = types->at(i);
     LookupResult lookup(map->GetIsolate());
     map->LookupInDescriptors(NULL, *name, &lookup);
-    if (lookup.IsProperty()) {
+    if (lookup.IsFound()) {
       switch (lookup.type()) {
         case FIELD: {
           int index = lookup.GetLocalFieldIndexFromMap(*map);
           if (index < 0) {
-            SetFlag(kDependsOnInobjectFields);
+            SetGVNFlag(kDependsOnInobjectFields);
           } else {
-            SetFlag(kDependsOnBackingStoreFields);
+            SetGVNFlag(kDependsOnBackingStoreFields);
           }
           types_.Add(types->at(i));
           break;
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 5082e4d..9f661d6 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -492,18 +492,26 @@
 };
 
 
+// There must be one corresponding kDepends flag for every kChanges flag and
+// the order of the kChanges flags must be exactly the same as of the kDepends
+// flags.
+enum GVNFlag {
+  // Declare global value numbering flags.
+#define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
+  GVN_FLAG_LIST(DECLARE_FLAG)
+#undef DECLARE_FLAG
+  kAfterLastFlag,
+  kLastFlag = kAfterLastFlag - 1
+};
+
+typedef EnumSet<GVNFlag> GVNFlagSet;
+
+
 class HValue: public ZoneObject {
  public:
   static const int kNoNumber = -1;
 
-  // There must be one corresponding kDepends flag for every kChanges flag and
-  // the order of the kChanges flags must be exactly the same as of the kDepends
-  // flags.
   enum Flag {
-    // Declare global value numbering flags.
-  #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
-    GVN_FLAG_LIST(DECLARE_DO)
-  #undef DECLARE_DO
     kFlexibleRepresentation,
     // Participate in Global Value Numbering, i.e. elimination of
     // unnecessary recomputations. If an instruction sets this flag, it must
@@ -523,8 +531,8 @@
 
   static const int kChangesToDependsFlagsLeftShift = 1;
 
-  static int ConvertChangesToDependsFlags(int flags) {
-    return flags << kChangesToDependsFlagsLeftShift;
+  static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
+    return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
   }
 
   static HValue* cast(HValue* value) { return value; }
@@ -622,16 +630,32 @@
   void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
   bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
 
-  void SetAllSideEffects() { flags_ |= AllSideEffects(); }
-  void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
-  bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
+  GVNFlagSet gvn_flags() const { return gvn_flags_; }
+  void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
+  void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
+  bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
+  void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); }
+  void ClearAllSideEffects() {
+    gvn_flags_.Remove(AllSideEffectsFlagSet());
+  }
+  bool HasSideEffects() const {
+    return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
+  }
   bool HasObservableSideEffects() const {
-    return (flags_ & ObservableSideEffects()) != 0;
+    return gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
   }
 
-  int ChangesFlags() const { return flags_ & ChangesFlagsMask(); }
-  int ObservableChangesFlags() const {
-    return flags_ & ChangesFlagsMask() & ObservableSideEffects();
+  GVNFlagSet ChangesFlags() const {
+    GVNFlagSet result = gvn_flags_;
+    result.Intersect(AllChangesFlagSet());
+    return result;
+  }
+
+  GVNFlagSet ObservableChangesFlags() const {
+    GVNFlagSet result = gvn_flags_;
+    result.Intersect(AllChangesFlagSet());
+    result.Intersect(AllObservableSideEffectsFlagSet());
+    return result;
   }
 
   Range* range() const { return range_; }
@@ -697,25 +721,28 @@
     representation_ = r;
   }
 
- private:
-  static int ChangesFlagsMask() {
-    int result = 0;
+  static GVNFlagSet AllChangesFlagSet() {
+    GVNFlagSet result;
     // Create changes mask.
-#define ADD_FLAG(type) result |= (1 << kChanges##type);
+#define ADD_FLAG(type) result.Add(kChanges##type);
   GVN_FLAG_LIST(ADD_FLAG)
 #undef ADD_FLAG
     return result;
   }
 
   // A flag mask to mark an instruction as having arbitrary side effects.
-  static int AllSideEffects() {
-    return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
+  static GVNFlagSet AllSideEffectsFlagSet() {
+    GVNFlagSet result = AllChangesFlagSet();
+    result.Remove(kChangesOsrEntries);
+    return result;
   }
 
   // A flag mask of all side effects that can make observable changes in
   // an executing program (i.e. are not safe to repeat, move or remove);
-  static int ObservableSideEffects() {
-    return ChangesFlagsMask() & ~(1 << kChangesElementsKind);
+  static GVNFlagSet AllObservableSideEffectsFlagSet() {
+    GVNFlagSet result = AllChangesFlagSet();
+    result.Remove(kChangesElementsKind);
+    return result;
   }
 
   // Remove the matching use from the use list if present.  Returns the
@@ -735,6 +762,7 @@
   HUseListNode* use_list_;
   Range* range_;
   int flags_;
+  GVNFlagSet gvn_flags_;
 
   DISALLOW_COPY_AND_ASSIGN(HValue);
 };
@@ -772,7 +800,7 @@
       : next_(NULL),
         previous_(NULL),
         position_(RelocInfo::kNoPosition) {
-    SetFlag(kDependsOnOsrEntries);
+    SetGVNFlag(kDependsOnOsrEntries);
   }
 
   virtual void DeleteFromGraph() { Unlink(); }
@@ -1716,8 +1744,8 @@
     SetOperandAt(1, typecheck);
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnArrayLengths);
-    SetFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnArrayLengths);
+    SetGVNFlag(kDependsOnMaps);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -1741,7 +1769,7 @@
   explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnArrayLengths);
+    SetGVNFlag(kDependsOnArrayLengths);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -1760,7 +1788,7 @@
   explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnElementsKind);
+    SetGVNFlag(kDependsOnElementsKind);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -1886,8 +1914,8 @@
   explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
-    SetFlag(kDependsOnElementsKind);
+    SetGVNFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnElementsKind);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -1937,7 +1965,7 @@
     SetOperandAt(1, typecheck != NULL ? typecheck : value);
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnMaps);
     has_element_transitions_ =
         map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL ||
         map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL;
@@ -2105,7 +2133,7 @@
   HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
       : prototype_(prototype), holder_(holder) {
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnMaps);
   }
 
 #ifdef DEBUG
@@ -3255,7 +3283,7 @@
 class HOsrEntry: public HTemplateInstruction<0> {
  public:
   explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
-    SetFlag(kChangesOsrEntries);
+    SetGVNFlag(kChangesOsrEntries);
   }
 
   int ast_id() const { return ast_id_; }
@@ -3343,7 +3371,7 @@
       : cell_(cell), details_(details) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnGlobalVars);
+    SetGVNFlag(kDependsOnGlobalVars);
   }
 
   Handle<JSGlobalPropertyCell>  cell() const { return cell_; }
@@ -3422,7 +3450,7 @@
       : HUnaryOperation(value),
         cell_(cell),
         details_(details) {
-    SetFlag(kChangesGlobalVars);
+    SetGVNFlag(kChangesGlobalVars);
   }
 
   Handle<JSGlobalPropertyCell> cell() const { return cell_; }
@@ -3513,7 +3541,7 @@
     }
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnContextSlots);
+    SetGVNFlag(kDependsOnContextSlots);
   }
 
   int slot_index() const { return slot_index_; }
@@ -3566,7 +3594,7 @@
       : slot_index_(slot_index), mode_(mode) {
     SetOperandAt(0, context);
     SetOperandAt(1, value);
-    SetFlag(kChangesContextSlots);
+    SetGVNFlag(kChangesContextSlots);
   }
 
   HValue* context() { return OperandAt(0); }
@@ -3608,11 +3636,11 @@
         offset_(offset) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnMaps);
     if (is_in_object) {
-      SetFlag(kDependsOnInobjectFields);
+      SetGVNFlag(kDependsOnInobjectFields);
     } else {
-      SetFlag(kDependsOnBackingStoreFields);
+      SetGVNFlag(kDependsOnBackingStoreFields);
     }
   }
 
@@ -3706,7 +3734,7 @@
       : HUnaryOperation(function) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnCalls);
+    SetGVNFlag(kDependsOnCalls);
   }
 
   HValue* function() { return OperandAt(0); }
@@ -3728,7 +3756,7 @@
     SetOperandAt(0, obj);
     SetOperandAt(1, key);
     set_representation(Representation::Tagged());
-    SetFlag(kDependsOnArrayElements);
+    SetGVNFlag(kDependsOnArrayElements);
     SetFlag(kUseGVN);
   }
 
@@ -3759,7 +3787,7 @@
     SetOperandAt(0, elements);
     SetOperandAt(1, key);
     set_representation(Representation::Double());
-    SetFlag(kDependsOnDoubleArrayElements);
+    SetGVNFlag(kDependsOnDoubleArrayElements);
     SetFlag(kUseGVN);
   }
 
@@ -3796,9 +3824,9 @@
     } else {
       set_representation(Representation::Integer32());
     }
-    SetFlag(kDependsOnSpecializedArrayElements);
+    SetGVNFlag(kDependsOnSpecializedArrayElements);
     // Native code could change the specialized array.
-    SetFlag(kDependsOnCalls);
+    SetGVNFlag(kDependsOnCalls);
     SetFlag(kUseGVN);
   }
 
@@ -3868,9 +3896,9 @@
     SetOperandAt(0, obj);
     SetOperandAt(1, val);
     if (is_in_object_) {
-      SetFlag(kChangesInobjectFields);
+      SetGVNFlag(kChangesInobjectFields);
     } else {
-      SetFlag(kChangesBackingStoreFields);
+      SetGVNFlag(kChangesBackingStoreFields);
     }
   }
 
@@ -3945,7 +3973,7 @@
     SetOperandAt(0, obj);
     SetOperandAt(1, key);
     SetOperandAt(2, val);
-    SetFlag(kChangesArrayElements);
+    SetGVNFlag(kChangesArrayElements);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -3987,7 +4015,7 @@
     SetOperandAt(0, elements);
     SetOperandAt(1, key);
     SetOperandAt(2, val);
-    SetFlag(kChangesDoubleArrayElements);
+    SetGVNFlag(kChangesDoubleArrayElements);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -4021,7 +4049,7 @@
                                      HValue* val,
                                      ElementsKind elements_kind)
       : elements_kind_(elements_kind) {
-    SetFlag(kChangesSpecializedArrayElements);
+    SetGVNFlag(kChangesSpecializedArrayElements);
     SetOperandAt(0, external_elements);
     SetOperandAt(1, key);
     SetOperandAt(2, val);
@@ -4099,7 +4127,7 @@
         transitioned_map_(transitioned_map) {
     SetOperandAt(0, object);
     SetFlag(kUseGVN);
-    SetFlag(kChangesElementsKind);
+    SetGVNFlag(kChangesElementsKind);
     set_representation(Representation::Tagged());
   }
 
@@ -4134,7 +4162,7 @@
       : HBinaryOperation(context, left, right) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnMaps);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -4160,7 +4188,7 @@
     SetOperandAt(2, index);
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnMaps);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
@@ -4215,7 +4243,7 @@
   explicit HStringLength(HValue* string) : HUnaryOperation(string) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetFlag(kDependsOnMaps);
+    SetGVNFlag(kDependsOnMaps);
   }
 
   virtual Representation RequiredInputRepresentation(int index) {
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 56da2dc..1a63f1e 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1110,10 +1110,10 @@
 }
 
 
-void HValueMap::Kill(int flags) {
-  int depends_flags = HValue::ConvertChangesToDependsFlags(flags);
-  if ((present_flags_ & depends_flags) == 0) return;
-  present_flags_ = 0;
+void HValueMap::Kill(GVNFlagSet flags) {
+  GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(flags);
+  if (!present_flags_.ContainsAnyOf(depends_flags)) return;
+  present_flags_.RemoveAll();
   for (int i = 0; i < array_size_; ++i) {
     HValue* value = array_[i].value;
     if (value != NULL) {
@@ -1122,7 +1122,8 @@
       int next;
       for (int current = array_[i].next; current != kNil; current = next) {
         next = lists_[current].next;
-        if ((lists_[current].value->flags() & depends_flags) != 0) {
+        HValue* value = lists_[current].value;
+        if (value->gvn_flags().ContainsAnyOf(depends_flags)) {
           // Drop it.
           count_--;
           lists_[current].next = free_list_head_;
@@ -1131,13 +1132,14 @@
           // Keep it.
           lists_[current].next = kept;
           kept = current;
-          present_flags_ |= lists_[current].value->flags();
+          present_flags_.Add(value->gvn_flags());
         }
       }
       array_[i].next = kept;
 
       // Now possibly drop directly indexed element.
-      if ((array_[i].value->flags() & depends_flags) != 0) {  // Drop it.
+      value = array_[i].value;
+      if (value->gvn_flags().ContainsAnyOf(depends_flags)) {  // Drop it.
         count_--;
         int head = array_[i].next;
         if (head == kNil) {
@@ -1149,7 +1151,7 @@
           free_list_head_ = head;
         }
       } else {
-        present_flags_ |= array_[i].value->flags();  // Keep it.
+        present_flags_.Add(value->gvn_flags());  // Keep it.
       }
     }
   }
@@ -1356,8 +1358,8 @@
         loop_side_effects_(graph->blocks()->length()),
         visited_on_paths_(graph->zone(), graph->blocks()->length()) {
     ASSERT(info->isolate()->heap()->allow_allocation(false));
-    block_side_effects_.AddBlock(0, graph_->blocks()->length());
-    loop_side_effects_.AddBlock(0, graph_->blocks()->length());
+    block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length());
+    loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length());
   }
   ~HGlobalValueNumberer() {
     ASSERT(!info_->isolate()->heap()->allow_allocation(true));
@@ -1367,14 +1369,15 @@
   bool Analyze();
 
  private:
-  int CollectSideEffectsOnPathsToDominatedBlock(HBasicBlock* dominator,
-                                                HBasicBlock* dominated);
+  GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
+      HBasicBlock* dominator,
+      HBasicBlock* dominated);
   void AnalyzeBlock(HBasicBlock* block, HValueMap* map);
   void ComputeBlockSideEffects();
   void LoopInvariantCodeMotion();
   void ProcessLoopBlock(HBasicBlock* block,
                         HBasicBlock* before_loop,
-                        int loop_kills);
+                        GVNFlagSet loop_kills);
   bool AllowCodeMotion();
   bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
 
@@ -1387,10 +1390,10 @@
   bool removed_side_effects_;
 
   // A map of block IDs to their side effects.
-  ZoneList<int> block_side_effects_;
+  ZoneList<GVNFlagSet> block_side_effects_;
 
   // A map of loop header block IDs to their loop's side effects.
-  ZoneList<int> loop_side_effects_;
+  ZoneList<GVNFlagSet> loop_side_effects_;
 
   // Used when collecting side effects on paths from dominator to
   // dominated.
@@ -1415,23 +1418,24 @@
     HBasicBlock* block = graph_->blocks()->at(i);
     HInstruction* instr = block->first();
     int id = block->block_id();
-    int side_effects = 0;
+    GVNFlagSet side_effects;
     while (instr != NULL) {
-      side_effects |= instr->ChangesFlags();
+      side_effects.Add(instr->ChangesFlags());
       instr = instr->next();
     }
-    block_side_effects_[id] |= side_effects;
+    block_side_effects_[id].Add(side_effects);
 
     // Loop headers are part of their loop.
     if (block->IsLoopHeader()) {
-      loop_side_effects_[id] |= side_effects;
+      loop_side_effects_[id].Add(side_effects);
     }
 
     // Propagate loop side effects upwards.
     if (block->HasParentLoopHeader()) {
       int header_id = block->parent_loop_header()->block_id();
-      loop_side_effects_[header_id] |=
-          block->IsLoopHeader() ? loop_side_effects_[id] : side_effects;
+      loop_side_effects_[header_id].Add(block->IsLoopHeader()
+                                        ? loop_side_effects_[id]
+                                        : side_effects);
     }
   }
 }
@@ -1441,10 +1445,10 @@
   for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
     HBasicBlock* block = graph_->blocks()->at(i);
     if (block->IsLoopHeader()) {
-      int side_effects = loop_side_effects_[block->block_id()];
+      GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
       TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n",
                block->block_id(),
-               side_effects);
+               side_effects.ToIntegral());
 
       HBasicBlock* last = block->loop_information()->GetLastBackEdge();
       for (int j = block->block_id(); j <= last->block_id(); ++j) {
@@ -1457,17 +1461,17 @@
 
 void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block,
                                             HBasicBlock* loop_header,
-                                            int loop_kills) {
+                                            GVNFlagSet loop_kills) {
   HBasicBlock* pre_header = loop_header->predecessors()->at(0);
-  int depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
+  GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
   TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n",
            block->block_id(),
-           depends_flags);
+           depends_flags.ToIntegral());
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
     if (instr->CheckFlag(HValue::kUseGVN) &&
-        (instr->flags() & depends_flags) == 0) {
+        !instr->gvn_flags().ContainsAnyOf(depends_flags)) {
       TraceGVN("Checking instruction %d (%s)\n",
                instr->id(),
                instr->Mnemonic());
@@ -1503,20 +1507,20 @@
 }
 
 
-int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
+GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
     HBasicBlock* dominator, HBasicBlock* dominated) {
-  int side_effects = 0;
+  GVNFlagSet side_effects;
   for (int i = 0; i < dominated->predecessors()->length(); ++i) {
     HBasicBlock* block = dominated->predecessors()->at(i);
     if (dominator->block_id() < block->block_id() &&
         block->block_id() < dominated->block_id() &&
         visited_on_paths_.Add(block->block_id())) {
-      side_effects |= block_side_effects_[block->block_id()];
+      side_effects.Add(block_side_effects_[block->block_id()]);
       if (block->IsLoopHeader()) {
-        side_effects |= loop_side_effects_[block->block_id()];
+        side_effects.Add(loop_side_effects_[block->block_id()]);
       }
-      side_effects |= CollectSideEffectsOnPathsToDominatedBlock(
-          dominator, block);
+      side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock(
+          dominator, block));
     }
   }
   return side_effects;
@@ -1537,8 +1541,8 @@
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
-    int flags = instr->ChangesFlags();
-    if (flags != 0) {
+    GVNFlagSet flags = instr->ChangesFlags();
+    if (!flags.IsEmpty()) {
       // Clear all instructions in the map that are affected by side effects.
       map->Kill(flags);
       TraceGVN("Instruction %d kills\n", instr->id());
@@ -3203,7 +3207,7 @@
   }
   Handle<GlobalObject> global(info()->global_object());
   global->Lookup(*var->name(), lookup);
-  if (!lookup->IsProperty() ||
+  if (!lookup->IsFound() ||
       lookup->type() != NORMAL ||
       (is_store && lookup->IsReadOnly()) ||
       lookup->holder() != *global) {
@@ -3548,7 +3552,7 @@
                                Handle<String> name,
                                LookupResult* lookup) {
   type->LookupInDescriptors(NULL, *name, lookup);
-  if (!lookup->IsPropertyOrTransition()) return false;
+  if (!lookup->IsFound()) return false;
   if (lookup->type() == FIELD) return true;
   return (lookup->type() == MAP_TRANSITION) &&
       (type->unused_property_fields() > 0);
@@ -3597,7 +3601,7 @@
     instr->set_transition(transition);
     // TODO(fschneider): Record the new map type of the object in the IR to
     // enable elimination of redundant checks after the transition store.
-    instr->SetFlag(HValue::kChangesMaps);
+    instr->SetGVNFlag(kChangesMaps);
   }
   return instr;
 }
@@ -4155,13 +4159,13 @@
                                             Handle<String> name) {
   LookupResult lookup(isolate());
   map->LookupInDescriptors(NULL, *name, &lookup);
-  if (lookup.IsProperty() && lookup.type() == FIELD) {
+  if (lookup.IsFound() && lookup.type() == FIELD) {
     return BuildLoadNamedField(obj,
                                expr,
                                map,
                                &lookup,
                                true);
-  } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) {
+  } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
     AddInstruction(new(zone()) HCheckNonSmi(obj));
     AddInstruction(new(zone()) HCheckMap(obj, map, NULL,
                                          ALLOW_ELEMENT_TRANSITION_MAPS));
@@ -6249,7 +6253,7 @@
       Handle<GlobalObject> global(info()->global_object());
       LookupResult lookup(isolate());
       global->Lookup(*name, &lookup);
-      if (lookup.IsProperty() &&
+      if (lookup.IsFound() &&
           lookup.type() == NORMAL &&
           lookup.GetValue()->IsJSFunction()) {
         Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue()));
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 9705859..b77e975 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -1056,10 +1056,10 @@
     Resize(kInitialSize);
   }
 
-  void Kill(int flags);
+  void Kill(GVNFlagSet flags);
 
   void Add(HValue* value) {
-    present_flags_ |= value->flags();
+    present_flags_.Add(value->gvn_flags());
     Insert(value);
   }
 
@@ -1092,7 +1092,8 @@
   int array_size_;
   int lists_size_;
   int count_;  // The number of values stored in the HValueMap.
-  int present_flags_;  // All flags that are in any value in the HValueMap.
+  GVNFlagSet present_flags_;  // All flags that are in any value in the
+                              // HValueMap.
   HValueMapListElement* array_;  // Primary store - contains the first value
   // with a given hash.  Colliding elements are stored in linked lists.
   HValueMapListElement* lists_;  // The linked lists containing hash collisions.
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 82bb02a..bb1d678 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -473,7 +473,6 @@
   Counters* counters = isolate->counters();
   __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
   __ ret(0);
-
   __ bind(&check_number_dictionary);
   __ mov(ebx, eax);
   __ SmiUntag(ebx);
@@ -535,15 +534,25 @@
   __ mov(edi, FieldOperand(eax, String::kHashFieldOffset));
   __ shr(edi, String::kHashShift);
   __ xor_(ecx, edi);
-  __ and_(ecx, KeyedLookupCache::kCapacityMask);
+  __ and_(ecx, KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
 
   // Load the key (consisting of map and symbol) from the cache and
   // check for match.
+  Label try_second_entry, hit_on_first_entry, load_in_object_property;
   ExternalReference cache_keys =
       ExternalReference::keyed_lookup_cache_keys(masm->isolate());
   __ mov(edi, ecx);
   __ shl(edi, kPointerSizeLog2 + 1);
   __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys));
+  __ j(not_equal, &try_second_entry);
+  __ add(edi, Immediate(kPointerSize));
+  __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys));
+  __ j(equal, &hit_on_first_entry);
+
+  __ bind(&try_second_entry);
+  __ lea(edi, Operand(ecx, 1));
+  __ shl(edi, kPointerSizeLog2 + 1);
+  __ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys));
   __ j(not_equal, &slow);
   __ add(edi, Immediate(kPointerSize));
   __ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys));
@@ -556,6 +565,18 @@
   // ecx     : lookup cache index
   ExternalReference cache_field_offsets =
       ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
+
+  // Hit on second entry.
+  __ add(ecx, Immediate(1));
+  __ mov(edi,
+         Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
+  __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
+  __ sub(edi, ecx);
+  __ j(above_equal, &property_array_property);
+  __ jmp(&load_in_object_property);
+
+  // Hit on first entry.
+  __ bind(&hit_on_first_entry);
   __ mov(edi,
          Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
   __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
@@ -563,6 +584,7 @@
   __ j(above_equal, &property_array_property);
 
   // Load in-object property.
+  __ bind(&load_in_object_property);
   __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
   __ add(ecx, edi);
   __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index a5c96b0..976b234 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -2216,7 +2216,7 @@
                                                Handle<String> name) {
   LookupResult lookup(isolate());
   type->LookupInDescriptors(NULL, *name, &lookup);
-  ASSERT(lookup.IsProperty() &&
+  ASSERT(lookup.IsFound() &&
          (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
   if (lookup.type() == FIELD) {
     int index = lookup.GetLocalFieldIndexFromMap(*type);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 0adb101..f6f4241 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -1053,7 +1053,7 @@
   // and CALLBACKS, so inline only them, other cases may be added
   // later.
   bool compile_followup_inline = false;
-  if (lookup->IsProperty() && lookup->IsCacheable()) {
+  if (lookup->IsFound() && lookup->IsCacheable()) {
     if (lookup->type() == FIELD) {
       compile_followup_inline = true;
     } else if (lookup->type() == CALLBACKS &&
diff --git a/src/ic.cc b/src/ic.cc
index 4361ba2..b084109 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -860,7 +860,7 @@
   }
 
   PropertyAttributes attr;
-  if (lookup.IsProperty() &&
+  if (lookup.IsFound() &&
       (lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) {
     // Get the property.
     Handle<Object> result =
@@ -1083,7 +1083,7 @@
     }
 
     PropertyAttributes attr;
-    if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
+    if (lookup.IsFound() && lookup.type() == INTERCEPTOR) {
       // Get the property.
       Handle<Object> result =
           Object::GetProperty(object, object, &lookup, name, &attr);
@@ -1206,10 +1206,12 @@
 
 static bool StoreICableLookup(LookupResult* lookup) {
   // Bail out if we didn't find a result.
-  if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return false;
+  if (!lookup->IsFound() || lookup->type() == NULL_DESCRIPTOR) return false;
 
-  // If the property is read-only, we leave the IC in its current
-  // state.
+  // Bail out if inline caching is not allowed.
+  if (!lookup->IsCacheable()) return false;
+
+  // If the property is read-only, we leave the IC in its current state.
   if (lookup->IsReadOnly()) return false;
 
   return true;
diff --git a/src/isolate.h b/src/isolate.h
index 89793f8..7e6807b 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1071,6 +1071,7 @@
     Isolate* previous_isolate;
     EntryStackItem* previous_item;
 
+   private:
     DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
   };
 
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 96f406f..289e6b8 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -4252,7 +4252,7 @@
   const Register inline_site = t5;
   const Register scratch = a2;
 
-  const int32_t kDeltaToLoadBoolResult = 4 * kPointerSize;
+  const int32_t kDeltaToLoadBoolResult = 5 * kPointerSize;
 
   Label slow, loop, is_instance, is_not_instance, not_js_object;
 
@@ -4296,11 +4296,12 @@
     // Patch the (relocated) inlined map check.
 
     // The offset was stored in t0 safepoint slot.
-    // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal)
+    // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal).
     __ LoadFromSafepointRegisterSlot(scratch, t0);
     __ Subu(inline_site, ra, scratch);
-    // Patch the relocated value to map.
-    __ PatchRelocatedValue(inline_site, scratch, map);
+    // Get the map location in scratch and patch it.
+    __ GetRelocatedValue(inline_site, scratch, v1);  // v1 used as scratch.
+    __ sw(map, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
   }
 
   // Register mapping: a3 is object map and t0 is function prototype.
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index 8e78488..d974f08 100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -1033,19 +1033,26 @@
   __ lw(t0, FieldMemOperand(a0, String::kHashFieldOffset));
   __ sra(at, t0, String::kHashShift);
   __ xor_(a3, a3, at);
-  __ And(a3, a3, Operand(KeyedLookupCache::kCapacityMask));
+  int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
+  __ And(a3, a3, Operand(mask));
 
   // Load the key (consisting of map and symbol) from the cache and
   // check for match.
+  Label try_second_entry, hit_on_first_entry, load_in_object_property;
   ExternalReference cache_keys =
       ExternalReference::keyed_lookup_cache_keys(isolate);
   __ li(t0, Operand(cache_keys));
   __ sll(at, a3, kPointerSizeLog2 + 1);
   __ addu(t0, t0, at);
-  __ lw(t1, MemOperand(t0));  // Move t0 to symbol.
-  __ Addu(t0, t0, Operand(kPointerSize));
-  __ Branch(&slow, ne, a2, Operand(t1));
   __ lw(t1, MemOperand(t0));
+  __ Branch(&try_second_entry, ne, a2, Operand(t1));
+  __ lw(t1, MemOperand(t0, kPointerSize));
+  __ Branch(&hit_on_first_entry, eq, a0, Operand(t1));
+
+  __ bind(&try_second_entry);
+  __ lw(t1, MemOperand(t0, kPointerSize * 2));
+  __ Branch(&slow, ne, a2, Operand(t1));
+  __ lw(t1, MemOperand(t0, kPointerSize * 3));
   __ Branch(&slow, ne, a0, Operand(t1));
 
   // Get field offset.
@@ -1055,6 +1062,19 @@
   // a3     : lookup cache index
   ExternalReference cache_field_offsets =
       ExternalReference::keyed_lookup_cache_field_offsets(isolate);
+
+  // Hit on second entry.
+  __ li(t0, Operand(cache_field_offsets));
+  __ sll(at, a3, kPointerSizeLog2);
+  __ addu(at, t0, at);
+  __ lw(t1, MemOperand(at, kPointerSize));
+  __ lbu(t2, FieldMemOperand(a2, Map::kInObjectPropertiesOffset));
+  __ Subu(t1, t1, t2);
+  __ Branch(&property_array_property, ge, t1, Operand(zero_reg));
+  __ Branch(&load_in_object_property);
+
+  // Hit on first entry.
+  __ bind(&hit_on_first_entry);
   __ li(t0, Operand(cache_field_offsets));
   __ sll(at, a3, kPointerSizeLog2);
   __ addu(at, t0, at);
@@ -1064,6 +1084,7 @@
   __ Branch(&property_array_property, ge, t1, Operand(zero_reg));
 
   // Load in-object property.
+  __ bind(&load_in_object_property);
   __ lbu(t2, FieldMemOperand(a2, Map::kInstanceSizeOffset));
   __ addu(t2, t2, t1);  // Index from start of object.
   __ Subu(a1, a1, Operand(kHeapObjectTag));  // Remove the heap tag.
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 0f31c2a..7a230c1 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -2019,7 +2019,10 @@
   // We use Factory::the_hole_value() on purpose instead of loading from the
   // root array to force relocation to be able to later patch with
   // the cached map.
-  __ li(at, Operand(factory()->the_hole_value()), true);
+  Handle<JSGlobalPropertyCell> cell =
+      factory()->NewJSGlobalPropertyCell(factory()->the_hole_value());
+  __ li(at, Operand(Handle<Object>(cell)));
+  __ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset));
   __ Branch(&cache_miss, ne, map, Operand(at));
   // We use Factory::the_hole_value() on purpose instead of loading from the
   // root array to force relocation to be able to later patch
@@ -2266,7 +2269,7 @@
                                                Handle<String> name) {
   LookupResult lookup(isolate());
   type->LookupInDescriptors(NULL, *name, &lookup);
-  ASSERT(lookup.IsProperty() &&
+  ASSERT(lookup.IsFound() &&
          (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
   if (lookup.type() == FIELD) {
     int index = lookup.GetLocalFieldIndexFromMap(*type);
@@ -2716,7 +2719,7 @@
       this, pointers, Safepoint::kLazyDeopt);
   // The number of arguments is stored in receiver which is a0, as expected
   // by InvokeFunction.
-  v8::internal::ParameterCount actual(receiver);
+  ParameterCount actual(receiver);
   __ InvokeFunction(function, actual, CALL_FUNCTION,
                     safepoint_generator, CALL_AS_METHOD);
   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2772,31 +2775,41 @@
                                  int arity,
                                  LInstruction* instr,
                                  CallKind call_kind) {
-  // Change context if needed.
-  bool change_context =
-      (info()->closure()->context() != function->context()) ||
-      scope()->contains_with() ||
-      (scope()->num_heap_slots() > 0);
-  if (change_context) {
-    __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
-  }
-
-  // Set a0 to arguments count if adaption is not needed. Assumes that a0
-  // is available to write to at this point.
-  if (!function->NeedsArgumentsAdaption()) {
-    __ li(a0, Operand(arity));
-  }
+  bool can_invoke_directly = !function->NeedsArgumentsAdaption() ||
+      function->shared()->formal_parameter_count() == arity;
 
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
 
-  // Invoke function.
-  __ SetCallKind(t1, call_kind);
-  __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
-  __ Call(at);
+  if (can_invoke_directly) {
+    __ LoadHeapObject(a1, function);
+    // Change context if needed.
+    bool change_context =
+        (info()->closure()->context() != function->context()) ||
+        scope()->contains_with() ||
+        (scope()->num_heap_slots() > 0);
+    if (change_context) {
+      __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
+    }
 
-  // Set up deoptimization.
-  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
+    // Set r0 to arguments count if adaption is not needed. Assumes that r0
+    // is available to write to at this point.
+    if (!function->NeedsArgumentsAdaption()) {
+      __ li(a0, Operand(arity));
+    }
+
+    // Invoke function.
+    __ SetCallKind(t1, call_kind);
+    __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
+    __ Call(at);
+
+    // Set up deoptimization.
+    RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
+  } else {
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+    ParameterCount count(arity);
+    __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind);
+  }
 
   // Restore context.
   __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -2806,7 +2819,6 @@
 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
   ASSERT(ToRegister(instr->result()).is(v0));
   __ mov(a0, v0);
-  __ LoadHeapObject(a1, instr->function());
   CallKnownFunction(instr->function(), instr->arity(), instr, CALL_AS_METHOD);
 }
 
@@ -3249,7 +3261,6 @@
 
 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
   ASSERT(ToRegister(instr->result()).is(v0));
-  __ LoadHeapObject(a1, instr->target());
   CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
 }
 
@@ -4095,16 +4106,26 @@
 }
 
 
+void LCodeGen::DoCheckMapCommon(Register reg,
+                                Register scratch,
+                                Handle<Map> map,
+                                CompareMapMode mode,
+                                LEnvironment* env) {
+  Label success;
+  __ CompareMapAndBranch(reg, scratch, map, &success, eq, &success, mode);
+  DeoptimizeIf(al, env);
+  __ bind(&success);
+}
+
+
 void LCodeGen::DoCheckMap(LCheckMap* instr) {
   Register scratch = scratch0();
   LOperand* input = instr->InputAt(0);
   ASSERT(input->IsRegister());
   Register reg = ToRegister(input);
-  __ lw(scratch, FieldMemOperand(reg, HeapObject::kMapOffset));
-  DeoptimizeIf(ne,
-               instr->environment(),
-               scratch,
-               Operand(instr->hydrogen()->map()));
+  Handle<Map> map = instr->hydrogen()->map();
+  DoCheckMapCommon(reg, scratch, map, instr->hydrogen()->mode(),
+                   instr->environment());
 }
 
 
@@ -4172,11 +4193,9 @@
 
   // Check prototype maps up to the holder.
   while (!current_prototype.is_identical_to(holder)) {
-    __ lw(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
-    DeoptimizeIf(ne,
-                 instr->environment(),
-                 temp2,
-                 Operand(Handle<Map>(current_prototype->map())));
+    DoCheckMapCommon(temp1, temp2,
+                     Handle<Map>(current_prototype->map()),
+                     ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
     current_prototype =
         Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype()));
     // Load next prototype object.
@@ -4184,11 +4203,9 @@
   }
 
   // Check the holder map.
-  __ lw(temp2, FieldMemOperand(temp1, HeapObject::kMapOffset));
-  DeoptimizeIf(ne,
-               instr->environment(),
-               temp2,
-               Operand(Handle<Map>(current_prototype->map())));
+  DoCheckMapCommon(temp1, temp2,
+                   Handle<Map>(current_prototype->map()),
+                   ALLOW_ELEMENT_TRANSITION_MAPS, instr->environment());
 }
 
 
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index e90fc4c..513992c 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -115,6 +115,9 @@
   void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
                                        Label* map_check);
 
+  void DoCheckMapCommon(Register reg, Register scratch, Handle<Map> map,
+                        CompareMapMode mode, LEnvironment* env);
+
   // Parallel move support.
   void DoParallelMove(LParallelMove* move);
   void DoGap(LGap* instr);
@@ -223,8 +226,8 @@
                                             Safepoint::DeoptMode mode);
   void DeoptimizeIf(Condition cc,
                     LEnvironment* environment,
-                    Register src1,
-                    const Operand& src2);
+                    Register src1 = zero_reg,
+                    const Operand& src2 = Operand(zero_reg));
 
   void AddToTranslation(Translation* translation,
                         LOperand* op,
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 141d2a8..941c7fe 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -3315,17 +3315,51 @@
 }
 
 
+void MacroAssembler::CompareMapAndBranch(Register obj,
+                                         Register scratch,
+                                         Handle<Map> map,
+                                         Label* early_success,
+                                         Condition cond,
+                                         Label* branch_to,
+                                         CompareMapMode mode) {
+  lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
+  Operand right = Operand(map);
+  if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
+    Map* transitioned_fast_element_map(
+        map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
+    ASSERT(transitioned_fast_element_map == NULL ||
+           map->elements_kind() != FAST_ELEMENTS);
+    if (transitioned_fast_element_map != NULL) {
+      Branch(early_success, eq, scratch, right);
+      right = Operand(Handle<Map>(transitioned_fast_element_map));
+    }
+
+    Map* transitioned_double_map(
+        map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
+    ASSERT(transitioned_double_map == NULL ||
+           map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
+    if (transitioned_double_map != NULL) {
+      Branch(early_success, eq, scratch, right);
+      right = Operand(Handle<Map>(transitioned_double_map));
+    }
+  }
+
+  Branch(branch_to, cond, scratch, right);
+}
+
+
 void MacroAssembler::CheckMap(Register obj,
                               Register scratch,
                               Handle<Map> map,
                               Label* fail,
-                              SmiCheckType smi_check_type) {
+                              SmiCheckType smi_check_type,
+                              CompareMapMode mode) {
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, fail);
   }
-  lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
-  li(at, Operand(map));
-  Branch(fail, ne, scratch, Operand(at));
+  Label success;
+  CompareMapAndBranch(obj, scratch, map, &success, ne, fail, mode);
+  bind(&success);
 }
 
 
@@ -3432,10 +3466,12 @@
                                     Handle<Code> code_constant,
                                     Register code_reg,
                                     Label* done,
+                                    bool* definitely_mismatches,
                                     InvokeFlag flag,
                                     const CallWrapper& call_wrapper,
                                     CallKind call_kind) {
   bool definitely_matches = false;
+  *definitely_mismatches = false;
   Label regular_invoke;
 
   // Check whether the expected and actual arguments count match. If not,
@@ -3466,6 +3502,7 @@
         // arguments.
         definitely_matches = true;
       } else {
+        *definitely_mismatches = true;
         li(a2, Operand(expected.immediate()));
       }
     }
@@ -3489,7 +3526,9 @@
       SetCallKind(t1, call_kind);
       Call(adaptor);
       call_wrapper.AfterCall();
-      jmp(done);
+      if (!*definitely_mismatches) {
+        Branch(done);
+      }
     } else {
       SetCallKind(t1, call_kind);
       Jump(adaptor, RelocInfo::CODE_TARGET);
@@ -3510,21 +3549,25 @@
 
   Label done;
 
-  InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag,
+  bool definitely_mismatches = false;
+  InvokePrologue(expected, actual, Handle<Code>::null(), code,
+                 &done, &definitely_mismatches, flag,
                  call_wrapper, call_kind);
-  if (flag == CALL_FUNCTION) {
-    call_wrapper.BeforeCall(CallSize(code));
-    SetCallKind(t1, call_kind);
-    Call(code);
-    call_wrapper.AfterCall();
-  } else {
-    ASSERT(flag == JUMP_FUNCTION);
-    SetCallKind(t1, call_kind);
-    Jump(code);
+  if (!definitely_mismatches) {
+    if (flag == CALL_FUNCTION) {
+      call_wrapper.BeforeCall(CallSize(code));
+      SetCallKind(t1, call_kind);
+      Call(code);
+      call_wrapper.AfterCall();
+    } else {
+      ASSERT(flag == JUMP_FUNCTION);
+      SetCallKind(t1, call_kind);
+      Jump(code);
+    }
+    // Continue here if InvokePrologue does handle the invocation due to
+    // mismatched parameter counts.
+    bind(&done);
   }
-  // Continue here if InvokePrologue does handle the invocation due to
-  // mismatched parameter counts.
-  bind(&done);
 }
 
 
@@ -3539,18 +3582,22 @@
 
   Label done;
 
-  InvokePrologue(expected, actual, code, no_reg, &done, flag,
+  bool definitely_mismatches = false;
+  InvokePrologue(expected, actual, code, no_reg,
+                 &done, &definitely_mismatches, flag,
                  NullCallWrapper(), call_kind);
-  if (flag == CALL_FUNCTION) {
-    SetCallKind(t1, call_kind);
-    Call(code, rmode);
-  } else {
-    SetCallKind(t1, call_kind);
-    Jump(code, rmode);
+  if (!definitely_mismatches) {
+    if (flag == CALL_FUNCTION) {
+      SetCallKind(t1, call_kind);
+      Call(code, rmode);
+    } else {
+      SetCallKind(t1, call_kind);
+      Jump(code, rmode);
+    }
+    // Continue here if InvokePrologue does handle the invocation due to
+    // mismatched parameter counts.
+    bind(&done);
   }
-  // Continue here if InvokePrologue does handle the invocation due to
-  // mismatched parameter counts.
-  bind(&done);
 }
 
 
@@ -3583,6 +3630,7 @@
 void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
                                     const ParameterCount& actual,
                                     InvokeFlag flag,
+                                    const CallWrapper& call_wrapper,
                                     CallKind call_kind) {
   // You can't call a function without a valid frame.
   ASSERT(flag == JUMP_FUNCTION || has_frame());
@@ -3596,7 +3644,7 @@
   // allow recompilation to take effect without changing any of the
   // call sites.
   lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
-  InvokeCode(a3, expected, actual, flag, NullCallWrapper(), call_kind);
+  InvokeCode(a3, expected, actual, flag, call_wrapper, call_kind);
 }
 
 
@@ -4733,6 +4781,34 @@
   FlushICache(li_location, 2);
 }
 
+void MacroAssembler::GetRelocatedValue(Register li_location,
+                                       Register value,
+                                       Register scratch) {
+  lw(value, MemOperand(li_location));
+  if (emit_debug_code()) {
+    And(value, value, kOpcodeMask);
+    Check(eq, "The instruction should be a lui.",
+        value, Operand(LUI));
+    lw(value, MemOperand(li_location));
+  }
+
+  // value now holds a lui instruction. Extract the immediate.
+  sll(value, value, kImm16Bits);
+
+  lw(scratch, MemOperand(li_location, kInstrSize));
+  if (emit_debug_code()) {
+    And(scratch, scratch, kOpcodeMask);
+    Check(eq, "The instruction should be an ori.",
+        scratch, Operand(ORI));
+    lw(scratch, MemOperand(li_location, kInstrSize));
+  }
+  // "scratch" now holds an ori instruction. Extract the immediate.
+  andi(scratch, scratch, kImm16Mask);
+
+  // Merge the results.
+  or_(value, value, scratch);
+}
+
 
 void MacroAssembler::CheckPageFlag(
     Register object,
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index cdcee00..b976f6e 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -820,6 +820,7 @@
   void InvokeFunction(Handle<JSFunction> function,
                       const ParameterCount& actual,
                       InvokeFlag flag,
+                      const CallWrapper& call_wrapper,
                       CallKind call_kind);
 
 
@@ -930,15 +931,29 @@
                                    Register scratch4,
                                    Label* fail);
 
-  // Check if the map of an object is equal to a specified map (either
-  // given directly or as an index into the root list) and branch to
-  // label if not. Skip the smi check if not required (object is known
-  // to be a heap object).
+  // Compare an object's map with the specified map and its transitioned
+  // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Jumps to
+  // "branch_to" if the result of the comparison is "cond". If multiple map
+  // compares are required, the compare sequences branches to early_success.
+  void CompareMapAndBranch(Register obj,
+                           Register scratch,
+                           Handle<Map> map,
+                           Label* early_success,
+                           Condition cond,
+                           Label* branch_to,
+                           CompareMapMode mode = REQUIRE_EXACT_MAP);
+
+  // Check if the map of an object is equal to a specified map and branch to
+  // label if not. Skip the smi check if not required (object is known to be a
+  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
+  // against maps that are ElementsKind transition maps of the specificed map.
   void CheckMap(Register obj,
                 Register scratch,
                 Handle<Map> map,
                 Label* fail,
-                SmiCheckType smi_check_type);
+                SmiCheckType smi_check_type,
+                CompareMapMode mode = REQUIRE_EXACT_MAP);
+
 
   void CheckMap(Register obj,
                 Register scratch,
@@ -1327,6 +1342,10 @@
   void PatchRelocatedValue(Register li_location,
                            Register scratch,
                            Register new_value);
+  // Get the relocatad value (loaded data) from the lui/ori pair.
+  void GetRelocatedValue(Register li_location,
+                         Register value,
+                         Register scratch);
 
  private:
   void CallCFunctionHelper(Register function,
@@ -1359,6 +1378,7 @@
                       Handle<Code> code_constant,
                       Register code_reg,
                       Label* done,
+                      bool* definitely_mismatches,
                       InvokeFlag flag,
                       const CallWrapper& call_wrapper,
                       CallKind call_kind);
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 97a58c7..0051edf 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -377,13 +377,9 @@
                                       Label* miss_label) {
   // a0 : value.
   Label exit;
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver_reg, miss_label, scratch);
-
-  // Check that the map of the receiver hasn't changed.
-  __ lw(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
-  __ Branch(miss_label, ne, scratch, Operand(Handle<Map>(object->map())));
+  // Check that the map of the object hasn't changed.
+  __ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label,
+              DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
@@ -747,7 +743,7 @@
           ? CALL_AS_FUNCTION
           : CALL_AS_METHOD;
       __ InvokeFunction(optimization.constant_function(), arguments_,
-                        JUMP_FUNCTION, call_kind);
+                        JUMP_FUNCTION, NullCallWrapper(), call_kind);
     }
 
     // Deferred code for fast API call case---clean preallocated space.
@@ -1037,9 +1033,8 @@
       __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
     } else {
       Handle<Map> current_map(current->map());
-      __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
-      // Branch on the result of the map check.
-      __ Branch(miss, ne, scratch1, Operand(current_map));
+      __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK,
+                  ALLOW_ELEMENT_TRANSITION_MAPS);
       // Check access rights to the global object.  This has to happen after
       // the map check so that we know that the object is actually a global
       // object.
@@ -1070,8 +1065,8 @@
   LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1));
 
   // Check the holder map.
-  __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
-  __ Branch(miss, ne, scratch1, Operand(Handle<Map>(current->map())));
+  __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss,
+              DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform security check for access to the global object.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
@@ -1209,7 +1204,7 @@
   // and CALLBACKS, so inline only them, other cases may be added
   // later.
   bool compile_followup_inline = false;
-  if (lookup->IsProperty() && lookup->IsCacheable()) {
+  if (lookup->IsFound() && lookup->IsCacheable()) {
     if (lookup->type() == FIELD) {
       compile_followup_inline = true;
     } else if (lookup->type() == CALLBACKS &&
@@ -1934,7 +1929,8 @@
   // Tail call the full function. We do not have to patch the receiver
   // because the function makes no use of it.
   __ bind(&slow);
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
+  __ InvokeFunction(
+      function, arguments(), JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
 
   __ bind(&miss);
   // a2: function name.
@@ -2067,7 +2063,8 @@
   __ bind(&slow);
   // Tail call the full function. We do not have to patch the receiver
   // because the function makes no use of it.
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
+  __ InvokeFunction(
+      function, arguments(), JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
 
   __ bind(&miss);
   // a2: function name.
@@ -2167,7 +2164,8 @@
   // Tail call the full function. We do not have to patch the receiver
   // because the function makes no use of it.
   __ bind(&slow);
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, CALL_AS_METHOD);
+  __ InvokeFunction(
+      function, arguments(), JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD);
 
   __ bind(&miss);
   // a2: function name.
@@ -2346,7 +2344,8 @@
   CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
       ? CALL_AS_FUNCTION
       : CALL_AS_METHOD;
-  __ InvokeFunction(function, arguments(), JUMP_FUNCTION, call_kind);
+  __ InvokeFunction(
+      function, arguments(), JUMP_FUNCTION, NullCallWrapper(), call_kind);
 
   // Handle call cache miss.
   __ bind(&miss);
@@ -2493,12 +2492,9 @@
   // -----------------------------------
   Label miss;
 
-  // Check that the object isn't a smi.
-  __ JumpIfSmi(a1, &miss);
-
   // Check that the map of the object hasn't changed.
-  __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset));
-  __ Branch(&miss, ne, a3, Operand(Handle<Map>(object->map())));
+  __ CheckMap(a1, a3, Handle<Map>(object->map()), &miss,
+              DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform global security token check if needed.
   if (object->IsJSGlobalProxy()) {
@@ -2540,12 +2536,9 @@
   // -----------------------------------
   Label miss;
 
-  // Check that the object isn't a smi.
-  __ JumpIfSmi(a1, &miss);
-
   // Check that the map of the object hasn't changed.
-  __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset));
-  __ Branch(&miss, ne, a3, Operand(Handle<Map>(receiver->map())));
+  __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss,
+              DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
 
   // Perform global security token check if needed.
   if (receiver->IsJSGlobalProxy()) {
diff --git a/src/objects.cc b/src/objects.cc
index 0941e79..426327c 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4353,7 +4353,7 @@
        current != heap->null_value() && current->IsJSObject();
        current = JSObject::cast(current)->GetPrototype()) {
     JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
-    if (result->IsProperty() && result->type() == CALLBACKS) return;
+    if (result->IsFound() && result->type() == CALLBACKS) return;
   }
   result->NotFound();
 }
@@ -4457,7 +4457,7 @@
     // Lookup the name.
     LookupResult result(heap->isolate());
     LocalLookupRealNamedProperty(name, &result);
-    if (result.IsProperty()) {
+    if (result.IsFound()) {
       // TODO(mstarzinger): We should check for result.IsDontDelete() here once
       // we only call into the runtime once to set both getter and setter.
       if (result.type() == CALLBACKS) {
@@ -4935,75 +4935,191 @@
 }
 
 
-void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
-  // Traverse the transition tree without using a stack.  We do this by
-  // reversing the pointers in the maps and descriptor arrays.
-  Map* current = this;
-  Map* meta_map = GetHeap()->meta_map();
-  Object** map_or_index_field = NULL;
-  while (current != meta_map) {
-    DescriptorArray* d = reinterpret_cast<DescriptorArray*>(
-        *RawField(current, Map::kInstanceDescriptorsOrBitField3Offset));
-    if (!d->IsEmpty()) {
-      FixedArray* contents = reinterpret_cast<FixedArray*>(
-          d->get(DescriptorArray::kContentArrayIndex));
-      map_or_index_field = RawField(contents, HeapObject::kMapOffset);
-      Object* map_or_index = *map_or_index_field;
-      bool map_done = true;  // Controls a nested continue statement.
-      for (int i = map_or_index->IsSmi() ? Smi::cast(map_or_index)->value() : 0;
-           i < contents->length();
-           i += 2) {
-        PropertyDetails details(Smi::cast(contents->get(i + 1)));
-        if (details.IsTransition()) {
-          // Found a map in the transition array.  We record our progress in
-          // the transition array by recording the current map in the map field
-          // of the next map and recording the index in the transition array in
-          // the map field of the array.
-          Map* next = Map::cast(contents->get(i));
-          next->set_map_no_write_barrier(current);
-          *map_or_index_field = Smi::FromInt(i + 2);
-          current = next;
-          map_done = false;
-          break;
-        }
-      }
-      if (!map_done) continue;
-    } else {
-      map_or_index_field = NULL;
-    }
-    // That was the regular transitions, now for the prototype transitions.
-    FixedArray* prototype_transitions =
-        current->unchecked_prototype_transitions();
-    Object** proto_map_or_index_field =
-        RawField(prototype_transitions, HeapObject::kMapOffset);
-    Object* map_or_index = *proto_map_or_index_field;
-    const int start = kProtoTransitionHeaderSize + kProtoTransitionMapOffset;
-    int i = map_or_index->IsSmi() ? Smi::cast(map_or_index)->value() : start;
-    if (i < prototype_transitions->length()) {
-      // Found a map in the prototype transition array.  Record progress in
-      // an analogous way to the regular transitions array above.
-      Object* perhaps_map = prototype_transitions->get(i);
-      if (perhaps_map->IsMap()) {
-        Map* next = Map::cast(perhaps_map);
-        next->set_map_no_write_barrier(current);
-        *proto_map_or_index_field =
-            Smi::FromInt(i + kProtoTransitionElementsPerEntry);
-        current = next;
-        continue;
-      }
-    }
-    *proto_map_or_index_field = GetHeap()->fixed_array_map();
-    if (map_or_index_field != NULL) {
-      *map_or_index_field = GetHeap()->fixed_array_map();
-    }
+// An iterator over all map transitions in an descriptor array, reusing the map
+// field of the contens array while it is running.
+class IntrusiveMapTransitionIterator {
+ public:
+  explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array)
+      : descriptor_array_(descriptor_array) { }
 
-    // The callback expects a map to have a real map as its map, so we save
-    // the map field, which is being used to track the traversal and put the
-    // correct map (the meta_map) in place while we do the callback.
-    Map* prev = current->map();
-    current->set_map_no_write_barrier(meta_map);
-    callback(current, data);
-    current = prev;
+  void Start() {
+    ASSERT(!IsIterating());
+    if (HasContentArray()) *ContentHeader() = Smi::FromInt(0);
+  }
+
+  bool IsIterating() {
+    return HasContentArray() && (*ContentHeader())->IsSmi();
+  }
+
+  Map* Next() {
+    ASSERT(IsIterating());
+    FixedArray* contents = ContentArray();
+    int index = Smi::cast(*ContentHeader())->value();
+    while (index < contents->length()) {
+      int next_index = index + 2;
+      PropertyDetails details(Smi::cast(contents->get(index + 1)));
+      if (details.IsTransition()) {
+        *ContentHeader() = Smi::FromInt(next_index);
+        return static_cast<Map*>(contents->get(index));
+      }
+      index = next_index;
+    }
+    *ContentHeader() = descriptor_array_->GetHeap()->fixed_array_map();
+    return NULL;
+  }
+
+ private:
+  bool HasContentArray() {
+    return descriptor_array_-> length() > DescriptorArray::kContentArrayIndex;
+  }
+
+  FixedArray* ContentArray() {
+    Object* array = descriptor_array_->get(DescriptorArray::kContentArrayIndex);
+    return static_cast<FixedArray*>(array);
+  }
+
+  Object** ContentHeader() {
+    return HeapObject::RawField(ContentArray(), DescriptorArray::kMapOffset);
+  }
+
+  DescriptorArray* descriptor_array_;
+};
+
+
+// An iterator over all prototype transitions, reusing the map field of the
+// underlying array while it is running.
+class IntrusivePrototypeTransitionIterator {
+ public:
+  explicit IntrusivePrototypeTransitionIterator(FixedArray* proto_trans)
+      : proto_trans_(proto_trans) { }
+
+  void Start() {
+    ASSERT(!IsIterating());
+    if (HasTransitions()) *Header() = Smi::FromInt(0);
+  }
+
+  bool IsIterating() {
+    return HasTransitions() && (*Header())->IsSmi();
+  }
+
+  Map* Next() {
+    ASSERT(IsIterating());
+    int transitionNumber = Smi::cast(*Header())->value();
+    if (transitionNumber < NumberOfTransitions()) {
+      *Header() = Smi::FromInt(transitionNumber + 1);
+      return GetTransition(transitionNumber);
+    }
+    *Header() = proto_trans_->GetHeap()->fixed_array_map();
+    return NULL;
+  }
+
+ private:
+  bool HasTransitions() {
+    return proto_trans_->length() >= Map::kProtoTransitionHeaderSize;
+  }
+
+  Object** Header() {
+    return HeapObject::RawField(proto_trans_, FixedArray::kMapOffset);
+  }
+
+  int NumberOfTransitions() {
+    Object* num = proto_trans_->get(Map::kProtoTransitionNumberOfEntriesOffset);
+    return Smi::cast(num)->value();
+  }
+
+  Map* GetTransition(int transitionNumber) {
+    return Map::cast(proto_trans_->get(IndexFor(transitionNumber)));
+  }
+
+  int IndexFor(int transitionNumber) {
+    return Map::kProtoTransitionHeaderSize +
+        Map::kProtoTransitionMapOffset +
+        transitionNumber * Map::kProtoTransitionElementsPerEntry;
+  }
+
+  FixedArray* proto_trans_;
+};
+
+
+// To traverse the transition tree iteratively, we have to store two kinds of
+// information in a map: The parent map in the traversal and which children of a
+// node have already been visited. To do this without additional memory, we
+// temporarily reuse two maps with known values:
+//
+//  (1) The map of the map temporarily holds the parent, and is restored to the
+//      meta map afterwards.
+//
+//  (2) The info which children have already been visited depends on which part
+//      of the map we currently iterate:
+//
+//    (a) If we currently follow normal map transitions, we temporarily store
+//        the current index in the map of the FixedArray of the desciptor
+//        array's contents, and restore it to the fixed array map afterwards.
+//        Note that a single descriptor can have 0, 1, or 2 transitions.
+//
+//    (b) If we currently follow prototype transitions, we temporarily store
+//        the current index in the map of the FixedArray holding the prototype
+//        transitions, and restore it to the fixed array map afterwards.
+//
+// Note that the child iterator is just a concatenation of two iterators: One
+// iterating over map transitions and one iterating over prototype transisitons.
+class TraversableMap : public Map {
+ public:
+  // Record the parent in the traversal within this map. Note that this destroys
+  // this map's map!
+  void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); }
+
+  // Reset the current map's map, returning the parent previously stored in it.
+  TraversableMap* GetAndResetParent() {
+    TraversableMap* old_parent = static_cast<TraversableMap*>(map());
+    set_map_no_write_barrier(GetHeap()->meta_map());
+    return old_parent;
+  }
+
+  // Start iterating over this map's children, possibly destroying a FixedArray
+  // map (see explanation above).
+  void ChildIteratorStart() {
+    IntrusiveMapTransitionIterator(instance_descriptors()).Start();
+    IntrusivePrototypeTransitionIterator(
+        unchecked_prototype_transitions()).Start();
+  }
+
+  // If we have an unvisited child map, return that one and advance. If we have
+  // none, return NULL and reset any destroyed FixedArray maps.
+  TraversableMap* ChildIteratorNext() {
+    IntrusiveMapTransitionIterator descriptor_iterator(instance_descriptors());
+    if (descriptor_iterator.IsIterating()) {
+      Map* next = descriptor_iterator.Next();
+      if (next != NULL) return static_cast<TraversableMap*>(next);
+    }
+    IntrusivePrototypeTransitionIterator
+        proto_iterator(unchecked_prototype_transitions());
+    if (proto_iterator.IsIterating()) {
+      Map* next = proto_iterator.Next();
+      if (next != NULL) return static_cast<TraversableMap*>(next);
+    }
+    return NULL;
+  }
+};
+
+
+// Traverse the transition tree in postorder without using the C++ stack by
+// doing pointer reversal.
+void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
+  TraversableMap* current = static_cast<TraversableMap*>(this);
+  current->ChildIteratorStart();
+  while (true) {
+    TraversableMap* child = current->ChildIteratorNext();
+    if (child != NULL) {
+      child->ChildIteratorStart();
+      child->SetParent(current);
+      current = child;
+    } else {
+      TraversableMap* parent = current->GetAndResetParent();
+      callback(current, data);
+      if (current == this) break;
+      current = parent;
+    }
   }
 }
 
@@ -7472,7 +7588,7 @@
       LookupResult result(heap->isolate());
       String* name = GetThisPropertyAssignmentName(i);
       js_object->LocalLookupRealNamedProperty(name, &result);
-      if (result.IsProperty() && result.type() == CALLBACKS) {
+      if (result.IsFound() && result.type() == CALLBACKS) {
         return false;
       }
     }
@@ -10146,7 +10262,7 @@
 
   LookupResult result(isolate);
   LocalLookupRealNamedProperty(key, &result);
-  return result.IsProperty() && (result.type() == CALLBACKS);
+  return result.IsFound() && (result.type() == CALLBACKS);
 }
 
 
diff --git a/src/objects.h b/src/objects.h
index 0d5bec5..f2e35a6 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -7806,7 +7806,8 @@
   static const int kTagOffset          = HeapObject::kHeaderSize;
   static const int kPropertyListOffset = kTagOffset + kPointerSize;
   static const int kHeaderSize         = kPropertyListOffset + kPointerSize;
- protected:
+
+ private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(TemplateInfo);
 };
 
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index f4c20ae..c27e3c9 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -722,6 +722,7 @@
   static Mutex* mutex_;
   static SamplerThread* instance_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SamplerThread);
 };
 
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 65bd720..6d04fb1 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -840,6 +840,7 @@
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 5a1c0d1..30b6086 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -1178,6 +1178,7 @@
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index 369c3e4..9f8fe12 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -854,6 +854,7 @@
   static Mutex* mutex_;
   static SamplerThread* instance_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SamplerThread);
 };
 
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index a01c08d..fda5fb4 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -923,6 +923,7 @@
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index 08bec93..9b3713f 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -53,6 +53,7 @@
 #include "v8.h"
 
 #include "platform.h"
+#include "v8threads.h"
 #include "vm-state-inl.h"
 
 
@@ -322,43 +323,126 @@
 static const int kMmapFdOffset = 0;
 
 
+VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
+
 VirtualMemory::VirtualMemory(size_t size) {
-  address_ = mmap(NULL, size, PROT_NONE,
-                  MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
-                  kMmapFd, kMmapFdOffset);
+  address_ = ReserveRegion(size);
   size_ = size;
 }
 
 
+VirtualMemory::VirtualMemory(size_t size, size_t alignment)
+    : address_(NULL), size_(0) {
+  ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment())));
+  size_t request_size = RoundUp(size + alignment,
+                                static_cast<intptr_t>(OS::AllocateAlignment()));
+  void* reservation = mmap(OS::GetRandomMmapAddr(),
+                           request_size,
+                           PROT_NONE,
+                           MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
+                           kMmapFd,
+                           kMmapFdOffset);
+  if (reservation == MAP_FAILED) return;
+
+  Address base = static_cast<Address>(reservation);
+  Address aligned_base = RoundUp(base, alignment);
+  ASSERT_LE(base, aligned_base);
+
+  // Unmap extra memory reserved before and after the desired block.
+  if (aligned_base != base) {
+    size_t prefix_size = static_cast<size_t>(aligned_base - base);
+    OS::Free(base, prefix_size);
+    request_size -= prefix_size;
+  }
+
+  size_t aligned_size = RoundUp(size, OS::AllocateAlignment());
+  ASSERT_LE(aligned_size, request_size);
+
+  if (aligned_size != request_size) {
+    size_t suffix_size = request_size - aligned_size;
+    OS::Free(aligned_base + aligned_size, suffix_size);
+    request_size -= suffix_size;
+  }
+
+  ASSERT(aligned_size == request_size);
+
+  address_ = static_cast<void*>(aligned_base);
+  size_ = aligned_size;
+}
+
+
 VirtualMemory::~VirtualMemory() {
   if (IsReserved()) {
-    if (0 == munmap(address(), size())) address_ = MAP_FAILED;
+    bool result = ReleaseRegion(address(), size());
+    ASSERT(result);
+    USE(result);
   }
 }
 
 
 bool VirtualMemory::IsReserved() {
-  return address_ != MAP_FAILED;
+  return address_ != NULL;
 }
 
 
-bool VirtualMemory::Commit(void* address, size_t size, bool executable) {
-  int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0);
-  if (MAP_FAILED == mmap(address, size, prot,
-                         MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-                         kMmapFd, kMmapFdOffset)) {
-    return false;
-  }
+void VirtualMemory::Reset() {
+  address_ = NULL;
+  size_ = 0;
+}
 
-  UpdateAllocatedSpaceLimits(address, size);
-  return true;
+
+bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
+  return CommitRegion(address, size, is_executable);
 }
 
 
 bool VirtualMemory::Uncommit(void* address, size_t size) {
-  return mmap(address, size, PROT_NONE,
-              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED,
-              kMmapFd, kMmapFdOffset) != MAP_FAILED;
+  return UncommitRegion(address, size);
+}
+
+
+void* VirtualMemory::ReserveRegion(size_t size) {
+  void* result = mmap(OS::GetRandomMmapAddr(),
+                      size,
+                      PROT_NONE,
+                      MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
+                      kMmapFd,
+                      kMmapFdOffset);
+
+  if (result == MAP_FAILED) return NULL;
+
+  return result;
+}
+
+
+bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
+  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
+  if (MAP_FAILED == mmap(base,
+                         size,
+                         prot,
+                         MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+                         kMmapFd,
+                         kMmapFdOffset)) {
+    return false;
+  }
+
+  UpdateAllocatedSpaceLimits(base, size);
+  return true;
+}
+
+
+bool VirtualMemory::UncommitRegion(void* base, size_t size) {
+  return mmap(base,
+              size,
+              PROT_NONE,
+              MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED,
+              kMmapFd,
+              kMmapFdOffset) != MAP_FAILED;
+}
+
+
+bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
+  return munmap(base, size) == 0;
 }
 
 
@@ -759,6 +843,7 @@
   static bool signal_handler_installed_;
   static struct sigaction old_signal_handler_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SignalSender);
 };
 
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 5c000e6..ffda660 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -2006,6 +2006,7 @@
   static Mutex* mutex_;
   static SamplerThread* instance_;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(SamplerThread);
 };
 
diff --git a/src/property.h b/src/property.h
index 3203dd1..120734d 100644
--- a/src/property.h
+++ b/src/property.h
@@ -265,11 +265,6 @@
     return IsFound() && GetPropertyDetails().IsProperty();
   }
 
-  // Is the result a property or a transition?
-  bool IsPropertyOrTransition() {
-    return IsFound() && (type() != NULL_DESCRIPTOR);
-  }
-
   bool IsCacheable() { return cacheable_; }
   void DisallowCaching() { cacheable_ = false; }
 
diff --git a/src/runtime.cc b/src/runtime.cc
index b9ec719..2bac304 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1434,7 +1434,7 @@
         !object->IsJSContextExtensionObject()) {
       LookupResult lookup(isolate);
       object->Lookup(*name, &lookup);
-      if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
+      if (lookup.IsFound() && (lookup.type() == CALLBACKS)) {
         return ThrowRedeclarationError(isolate, "const", name);
       }
     }
@@ -1482,7 +1482,7 @@
          JSObject::cast(object)->map()->is_hidden_prototype()) {
     JSObject* raw_holder = JSObject::cast(object);
     raw_holder->LocalLookup(*name, &lookup);
-    if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
+    if (lookup.IsFound() && lookup.type() == INTERCEPTOR) {
       HandleScope handle_scope(isolate);
       Handle<JSObject> holder(raw_holder);
       PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
@@ -1648,7 +1648,7 @@
     // GetProperty() to get the current value as it 'unholes' the value.
     LookupResult lookup(isolate);
     object->LocalLookupRealNamedProperty(*name, &lookup);
-    ASSERT(lookup.IsProperty());  // the property was declared
+    ASSERT(lookup.IsFound());  // the property was declared
     ASSERT(lookup.IsReadOnly());  // and it was declared as read-only
 
     PropertyType type = lookup.type();
@@ -1869,9 +1869,19 @@
 
 
 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDefaultReceiver) {
-  NoHandleAllocation handle_free;
   ASSERT(args.length() == 1);
-  CONVERT_CHECKED(JSFunction, function, args[0]);
+  CONVERT_CHECKED(JSReceiver, callable, args[0]);
+
+  if (!callable->IsJSFunction()) {
+    HandleScope scope(isolate);
+    bool threw = false;
+    Handle<Object> delegate =
+        Execution::TryGetFunctionDelegate(Handle<JSReceiver>(callable), &threw);
+    if (threw) return Failure::Exception();
+    callable = JSFunction::cast(*delegate);
+  }
+  JSFunction* function = JSFunction::cast(callable);
+
   SharedFunctionInfo* shared = function->shared();
   if (shared->native() || !shared->is_classic_mode()) {
     return isolate->heap()->undefined_value();
@@ -4246,7 +4256,7 @@
         // appropriate.
         LookupResult result(isolate);
         receiver->LocalLookup(key, &result);
-        if (result.IsProperty() && result.type() == FIELD) {
+        if (result.IsFound() && result.type() == FIELD) {
           int offset = result.GetFieldIndex();
           keyed_lookup_cache->Update(receiver_map, key, offset);
           return receiver->FastPropertyAt(offset);
@@ -4394,7 +4404,7 @@
   js_object->LocalLookupRealNamedProperty(*name, &result);
 
   // Special case for callback properties.
-  if (result.IsProperty() && result.type() == CALLBACKS) {
+  if (result.IsFound() && result.type() == CALLBACKS) {
     Object* callback = result.GetCallbackObject();
     // To be compatible with Safari we do not change the value on API objects
     // in Object.defineProperty(). Firefox disagrees here, and actually changes
diff --git a/src/serialize.h b/src/serialize.h
index 6efb8ee..839bfc5 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -581,6 +581,7 @@
   friend class ObjectSerializer;
   friend class Deserializer;
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(Serializer);
 };
 
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index ec8f6bd..c7f4f94 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1452,13 +1452,13 @@
 
 
 CallOptimization::CallOptimization(LookupResult* lookup) {
-  if (!lookup->IsProperty() ||
-      !lookup->IsCacheable() ||
-      lookup->type() != CONSTANT_FUNCTION) {
-    Initialize(Handle<JSFunction>::null());
-  } else {
+  if (lookup->IsFound() &&
+      lookup->IsCacheable() &&
+      lookup->type() == CONSTANT_FUNCTION) {
     // We only optimize constant function calls.
     Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
+  } else {
+    Initialize(Handle<JSFunction>::null());
   }
 }
 
diff --git a/src/utils.h b/src/utils.h
index 17bf06f..1d40c98 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
@@ -931,9 +931,17 @@
   explicit EnumSet(T bits = 0) : bits_(bits) {}
   bool IsEmpty() const { return bits_ == 0; }
   bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
+  bool ContainsAnyOf(const EnumSet& set) const {
+    return (bits_ & set.bits_) != 0;
+  }
   void Add(E element) { bits_ |= Mask(element); }
+  void Add(const EnumSet& set) { bits_ |= set.bits_; }
   void Remove(E element) { bits_ &= ~Mask(element); }
+  void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
+  void RemoveAll() { bits_ = 0; }
+  void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
   T ToIntegral() const { return bits_; }
+  bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
 
  private:
   T Mask(E element) const {
diff --git a/src/version.cc b/src/version.cc
index 2c1daeb..ba531ab 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     8
-#define BUILD_NUMBER      7
-#define PATCH_LEVEL       1
+#define BUILD_NUMBER      8
+#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/ic-x64.cc b/src/x64/ic-x64.cc
index 0204460..8dca1e1 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -462,23 +462,43 @@
   __ movl(rdi, FieldOperand(rax, String::kHashFieldOffset));
   __ shr(rdi, Immediate(String::kHashShift));
   __ xor_(rcx, rdi);
-  __ and_(rcx, Immediate(KeyedLookupCache::kCapacityMask));
+  int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
+  __ and_(rcx, Immediate(mask));
 
   // Load the key (consisting of map and symbol) from the cache and
   // check for match.
+  Label try_second_entry, hit_on_first_entry, load_in_object_property;
   ExternalReference cache_keys
       = ExternalReference::keyed_lookup_cache_keys(masm->isolate());
   __ movq(rdi, rcx);
   __ shl(rdi, Immediate(kPointerSizeLog2 + 1));
   __ LoadAddress(kScratchRegister, cache_keys);
   __ cmpq(rbx, Operand(kScratchRegister, rdi, times_1, 0));
-  __ j(not_equal, &slow);
+  __ j(not_equal, &try_second_entry);
   __ cmpq(rax, Operand(kScratchRegister, rdi, times_1, kPointerSize));
+  __ j(equal, &hit_on_first_entry);
+
+  __ bind(&try_second_entry);
+  __ cmpq(rbx, Operand(kScratchRegister, rdi, times_1, kPointerSize * 2));
+  __ j(not_equal, &slow);
+  __ cmpq(rax, Operand(kScratchRegister, rdi, times_1, kPointerSize * 3));
   __ j(not_equal, &slow);
 
   // Get field offset, which is a 32-bit integer.
   ExternalReference cache_field_offsets
       = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
+
+  // Hit on second entry.
+  __ LoadAddress(kScratchRegister, cache_field_offsets);
+  __ addl(rcx, Immediate(1));
+  __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0));
+  __ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
+  __ subq(rdi, rcx);
+  __ j(above_equal, &property_array_property);
+  __ jmp(&load_in_object_property);
+
+  // Hit on first entry.
+  __ bind(&hit_on_first_entry);
   __ LoadAddress(kScratchRegister, cache_field_offsets);
   __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0));
   __ movzxbq(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
@@ -486,6 +506,7 @@
   __ j(above_equal, &property_array_property);
 
   // Load in-object property.
+  __ bind(&load_in_object_property);
   __ movzxbq(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
   __ addq(rcx, rdi);
   __ movq(rax, FieldOperand(rdx, rcx, times_pointer_size, 0));
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 350ff6f..e051214 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -2142,7 +2142,7 @@
                                                Handle<String> name) {
   LookupResult lookup(isolate());
   type->LookupInDescriptors(NULL, *name, &lookup);
-  ASSERT(lookup.IsProperty() &&
+  ASSERT(lookup.IsFound() &&
          (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION));
   if (lookup.type() == FIELD) {
     int index = lookup.GetLocalFieldIndexFromMap(*type);
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 47c2177..a6e1b83 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -1045,7 +1045,7 @@
   // and CALLBACKS, so inline only them, other cases may be added
   // later.
   bool compile_followup_inline = false;
-  if (lookup->IsProperty() && lookup->IsCacheable()) {
+  if (lookup->IsFound() && lookup->IsCacheable()) {
     if (lookup->type() == FIELD) {
       compile_followup_inline = true;
     } else if (lookup->type() == CALLBACKS &&