Update V8 to r7427: Initial merge by git

As required by WebKit r82507

Change-Id: I7ae83ef3f689356043b4929255b7c1dd31d8c5df
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 8cd29b2..9c9bac7 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -44,100 +44,57 @@
 namespace v8 {
 namespace internal {
 
-// A SourceCodeCache uses a FixedArray to store pairs of
-// (AsciiString*, JSFunction*), mapping names of native code files
-// (runtime.js, etc.) to precompiled functions. Instead of mapping
-// names to functions it might make sense to let the JS2C tool
-// generate an index for each native JS file.
-class SourceCodeCache BASE_EMBEDDED {
- public:
-  explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { }
 
-  void Initialize(bool create_heap_objects) {
-    cache_ = create_heap_objects ? Heap::empty_fixed_array() : NULL;
-  }
-
-  void Iterate(ObjectVisitor* v) {
-    v->VisitPointer(BitCast<Object**>(&cache_));
-  }
-
-
-  bool Lookup(Vector<const char> name, Handle<SharedFunctionInfo>* handle) {
-    for (int i = 0; i < cache_->length(); i+=2) {
-      SeqAsciiString* str = SeqAsciiString::cast(cache_->get(i));
-      if (str->IsEqualTo(name)) {
-        *handle = Handle<SharedFunctionInfo>(
-            SharedFunctionInfo::cast(cache_->get(i + 1)));
-        return true;
-      }
-    }
-    return false;
-  }
-
-
-  void Add(Vector<const char> name, Handle<SharedFunctionInfo> shared) {
-    HandleScope scope;
-    int length = cache_->length();
-    Handle<FixedArray> new_array =
-        Factory::NewFixedArray(length + 2, TENURED);
-    cache_->CopyTo(0, *new_array, 0, cache_->length());
-    cache_ = *new_array;
-    Handle<String> str = Factory::NewStringFromAscii(name, TENURED);
-    cache_->set(length, *str);
-    cache_->set(length + 1, *shared);
-    Script::cast(shared->script())->set_type(Smi::FromInt(type_));
-  }
-
- private:
-  Script::Type type_;
-  FixedArray* cache_;
-  DISALLOW_COPY_AND_ASSIGN(SourceCodeCache);
-};
-
-static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION);
-// This is for delete, not delete[].
-static List<char*>* delete_these_non_arrays_on_tear_down = NULL;
-// This is for delete[]
-static List<char*>* delete_these_arrays_on_tear_down = NULL;
-
-
-NativesExternalStringResource::NativesExternalStringResource(const char* source)
+NativesExternalStringResource::NativesExternalStringResource(
+    Bootstrapper* bootstrapper,
+    const char* source)
     : data_(source), length_(StrLength(source)) {
-  if (delete_these_non_arrays_on_tear_down == NULL) {
-    delete_these_non_arrays_on_tear_down = new List<char*>(2);
+  if (bootstrapper->delete_these_non_arrays_on_tear_down_ == NULL) {
+    bootstrapper->delete_these_non_arrays_on_tear_down_ = new List<char*>(2);
   }
   // The resources are small objects and we only make a fixed number of
   // them, but let's clean them up on exit for neatness.
-  delete_these_non_arrays_on_tear_down->
+  bootstrapper->delete_these_non_arrays_on_tear_down_->
       Add(reinterpret_cast<char*>(this));
 }
 
 
+Bootstrapper::Bootstrapper()
+    : nesting_(0),
+      extensions_cache_(Script::TYPE_EXTENSION),
+      delete_these_non_arrays_on_tear_down_(NULL),
+      delete_these_arrays_on_tear_down_(NULL) {
+}
+
+
 Handle<String> Bootstrapper::NativesSourceLookup(int index) {
   ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
-  if (Heap::natives_source_cache()->get(index)->IsUndefined()) {
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+  if (heap->natives_source_cache()->get(index)->IsUndefined()) {
     if (!Snapshot::IsEnabled() || FLAG_new_snapshot) {
       // We can use external strings for the natives.
       NativesExternalStringResource* resource =
-          new NativesExternalStringResource(
+          new NativesExternalStringResource(this,
               Natives::GetScriptSource(index).start());
       Handle<String> source_code =
-          Factory::NewExternalStringFromAscii(resource);
-      Heap::natives_source_cache()->set(index, *source_code);
+          factory->NewExternalStringFromAscii(resource);
+      heap->natives_source_cache()->set(index, *source_code);
     } else {
       // Old snapshot code can't cope with external strings at all.
       Handle<String> source_code =
-        Factory::NewStringFromAscii(Natives::GetScriptSource(index));
-      Heap::natives_source_cache()->set(index, *source_code);
+        factory->NewStringFromAscii(Natives::GetScriptSource(index));
+      heap->natives_source_cache()->set(index, *source_code);
     }
   }
-  Handle<Object> cached_source(Heap::natives_source_cache()->get(index));
+  Handle<Object> cached_source(heap->natives_source_cache()->get(index));
   return Handle<String>::cast(cached_source);
 }
 
 
 void Bootstrapper::Initialize(bool create_heap_objects) {
-  extensions_cache.Initialize(create_heap_objects);
+  extensions_cache_.Initialize(create_heap_objects);
   GCExtension::Register();
   ExternalizeStringExtension::Register();
 }
@@ -146,39 +103,39 @@
 char* Bootstrapper::AllocateAutoDeletedArray(int bytes) {
   char* memory = new char[bytes];
   if (memory != NULL) {
-    if (delete_these_arrays_on_tear_down == NULL) {
-      delete_these_arrays_on_tear_down = new List<char*>(2);
+    if (delete_these_arrays_on_tear_down_ == NULL) {
+      delete_these_arrays_on_tear_down_ = new List<char*>(2);
     }
-    delete_these_arrays_on_tear_down->Add(memory);
+    delete_these_arrays_on_tear_down_->Add(memory);
   }
   return memory;
 }
 
 
 void Bootstrapper::TearDown() {
-  if (delete_these_non_arrays_on_tear_down != NULL) {
-    int len = delete_these_non_arrays_on_tear_down->length();
+  if (delete_these_non_arrays_on_tear_down_ != NULL) {
+    int len = delete_these_non_arrays_on_tear_down_->length();
     ASSERT(len < 20);  // Don't use this mechanism for unbounded allocations.
     for (int i = 0; i < len; i++) {
-      delete delete_these_non_arrays_on_tear_down->at(i);
-      delete_these_non_arrays_on_tear_down->at(i) = NULL;
+      delete delete_these_non_arrays_on_tear_down_->at(i);
+      delete_these_non_arrays_on_tear_down_->at(i) = NULL;
     }
-    delete delete_these_non_arrays_on_tear_down;
-    delete_these_non_arrays_on_tear_down = NULL;
+    delete delete_these_non_arrays_on_tear_down_;
+    delete_these_non_arrays_on_tear_down_ = NULL;
   }
 
-  if (delete_these_arrays_on_tear_down != NULL) {
-    int len = delete_these_arrays_on_tear_down->length();
+  if (delete_these_arrays_on_tear_down_ != NULL) {
+    int len = delete_these_arrays_on_tear_down_->length();
     ASSERT(len < 1000);  // Don't use this mechanism for unbounded allocations.
     for (int i = 0; i < len; i++) {
-      delete[] delete_these_arrays_on_tear_down->at(i);
-      delete_these_arrays_on_tear_down->at(i) = NULL;
+      delete[] delete_these_arrays_on_tear_down_->at(i);
+      delete_these_arrays_on_tear_down_->at(i) = NULL;
     }
-    delete delete_these_arrays_on_tear_down;
-    delete_these_arrays_on_tear_down = NULL;
+    delete delete_these_arrays_on_tear_down_;
+    delete_these_arrays_on_tear_down_ = NULL;
   }
 
-  extensions_cache.Initialize(false);  // Yes, symmetrical
+  extensions_cache_.Initialize(false);  // Yes, symmetrical
 }
 
 
@@ -207,6 +164,10 @@
   void CreateRoots();
   // Creates the empty function.  Used for creating a context from scratch.
   Handle<JSFunction> CreateEmptyFunction();
+  // Creates the ThrowTypeError function. ECMA 5th Ed. 13.2.3
+  Handle<JSFunction> CreateThrowTypeErrorFunction(Builtins::Name builtin);
+
+  void CreateStrictModeFunctionMaps(Handle<JSFunction> empty);
   // Creates the global objects using the global and the template passed in
   // through the API.  We call this regardless of whether we are building a
   // context from scratch or using a deserialized one from the partial snapshot
@@ -260,10 +221,24 @@
     ADD_READONLY_PROTOTYPE,
     ADD_WRITEABLE_PROTOTYPE
   };
+
+  Handle<Map> CreateFunctionMap(PrototypePropertyMode prototype_mode);
+
   Handle<DescriptorArray> ComputeFunctionInstanceDescriptor(
       PrototypePropertyMode prototypeMode);
   void MakeFunctionInstancePrototypeWritable();
 
+  Handle<Map> CreateStrictModeFunctionMap(
+      PrototypePropertyMode prototype_mode,
+      Handle<JSFunction> empty_function,
+      Handle<FixedArray> arguments_callbacks,
+      Handle<FixedArray> caller_callbacks);
+
+  Handle<DescriptorArray> ComputeStrictFunctionInstanceDescriptor(
+      PrototypePropertyMode propertyMode,
+      Handle<FixedArray> arguments,
+      Handle<FixedArray> caller);
+
   static bool CompileBuiltin(int index);
   static bool CompileNative(Vector<const char> name, Handle<String> source);
   static bool CompileScriptCached(Vector<const char> name,
@@ -274,14 +249,21 @@
                                   bool use_runtime_context);
 
   Handle<Context> result_;
-  Handle<JSFunction> empty_function_;
+
+  // Function instance maps. Function literal maps are created initially with
+  // a read only prototype for the processing of JS builtins. Later the function
+  // instance maps are replaced in order to make prototype writable.
+  // These are the final, writable prototype, maps.
+  Handle<Map> function_instance_map_writable_prototype_;
+  Handle<Map> strict_mode_function_instance_map_writable_prototype_;
+
   BootstrapperActive active_;
   friend class Bootstrapper;
 };
 
 
 void Bootstrapper::Iterate(ObjectVisitor* v) {
-  extensions_cache.Iterate(v);
+  extensions_cache_.Iterate(v);
   v->Synchronize("Extensions");
 }
 
@@ -306,16 +288,17 @@
 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
   // object.__proto__ = proto;
   Handle<Map> old_to_map = Handle<Map>(object->map());
-  Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map);
+  Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map);
   new_to_map->set_prototype(*proto);
   object->set_map(*new_to_map);
 }
 
 
 void Bootstrapper::DetachGlobal(Handle<Context> env) {
-  JSGlobalProxy::cast(env->global_proxy())->set_context(*Factory::null_value());
+  Factory* factory = Isolate::Current()->factory();
+  JSGlobalProxy::cast(env->global_proxy())->set_context(*factory->null_value());
   SetObjectPrototype(Handle<JSObject>(env->global_proxy()),
-                     Factory::null_value());
+                     factory->null_value());
   env->set_global_proxy(env->global());
   env->global()->set_global_receiver(env->global());
 }
@@ -339,11 +322,13 @@
                                           Handle<JSObject> prototype,
                                           Builtins::Name call,
                                           bool is_ecma_native) {
-  Handle<String> symbol = Factory::LookupAsciiSymbol(name);
-  Handle<Code> call_code = Handle<Code>(Builtins::builtin(call));
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  Handle<String> symbol = factory->LookupAsciiSymbol(name);
+  Handle<Code> call_code = Handle<Code>(isolate->builtins()->builtin(call));
   Handle<JSFunction> function = prototype.is_null() ?
-    Factory::NewFunctionWithoutPrototype(symbol, call_code) :
-    Factory::NewFunctionWithPrototype(symbol,
+    factory->NewFunctionWithoutPrototype(symbol, call_code) :
+    factory->NewFunctionWithPrototype(symbol,
                                       type,
                                       instance_size,
                                       prototype,
@@ -359,174 +344,305 @@
 
 Handle<DescriptorArray> Genesis::ComputeFunctionInstanceDescriptor(
     PrototypePropertyMode prototypeMode) {
-  Handle<DescriptorArray> result = Factory::empty_descriptor_array();
-
-  if (prototypeMode != DONT_ADD_PROTOTYPE) {
-    PropertyAttributes attributes = static_cast<PropertyAttributes>(
-        DONT_ENUM |
-        DONT_DELETE |
-        (prototypeMode == ADD_READONLY_PROTOTYPE ? READ_ONLY : 0));
-    result =
-        Factory::CopyAppendProxyDescriptor(
-            result,
-            Factory::prototype_symbol(),
-            Factory::NewProxy(&Accessors::FunctionPrototype),
-            attributes);
-  }
-
+  Factory* factory = Isolate::Current()->factory();
+  Handle<DescriptorArray> descriptors =
+      factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5);
   PropertyAttributes attributes =
       static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
-  // Add length.
-  result =
-      Factory::CopyAppendProxyDescriptor(
-          result,
-          Factory::length_symbol(),
-          Factory::NewProxy(&Accessors::FunctionLength),
-          attributes);
 
-  // Add name.
-  result =
-      Factory::CopyAppendProxyDescriptor(
-          result,
-          Factory::name_symbol(),
-          Factory::NewProxy(&Accessors::FunctionName),
-          attributes);
+  {  // Add length.
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength);
+    CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes);
+    descriptors->Set(0, &d);
+  }
+  {  // Add name.
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName);
+    CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes);
+    descriptors->Set(1, &d);
+  }
+  {  // Add arguments.
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionArguments);
+    CallbacksDescriptor d(*factory->arguments_symbol(), *proxy, attributes);
+    descriptors->Set(2, &d);
+  }
+  {  // Add caller.
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionCaller);
+    CallbacksDescriptor d(*factory->caller_symbol(), *proxy, attributes);
+    descriptors->Set(3, &d);
+  }
+  if (prototypeMode != DONT_ADD_PROTOTYPE) {
+    // Add prototype.
+    if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
+      attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+    }
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype);
+    CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes);
+    descriptors->Set(4, &d);
+  }
+  descriptors->Sort();
+  return descriptors;
+}
 
-  // Add arguments.
-  result =
-      Factory::CopyAppendProxyDescriptor(
-          result,
-          Factory::arguments_symbol(),
-          Factory::NewProxy(&Accessors::FunctionArguments),
-          attributes);
 
-  // Add caller.
-  result =
-      Factory::CopyAppendProxyDescriptor(
-          result,
-          Factory::caller_symbol(),
-          Factory::NewProxy(&Accessors::FunctionCaller),
-          attributes);
-
-  return result;
+Handle<Map> Genesis::CreateFunctionMap(PrototypePropertyMode prototype_mode) {
+  Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+  Handle<DescriptorArray> descriptors =
+      ComputeFunctionInstanceDescriptor(prototype_mode);
+  map->set_instance_descriptors(*descriptors);
+  map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
+  return map;
 }
 
 
 Handle<JSFunction> Genesis::CreateEmptyFunction() {
-  // Allocate the map for function instances.
-  Handle<Map> fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
-  global_context()->set_function_instance_map(*fm);
+  // Allocate the map for function instances. Maps are allocated first and their
+  // prototypes patched later, once empty function is created.
+
   // Please note that the prototype property for function instances must be
   // writable.
-  Handle<DescriptorArray> function_map_descriptors =
-      ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
-  fm->set_instance_descriptors(*function_map_descriptors);
-  fm->set_function_with_prototype(true);
+  global_context()->set_function_instance_map(
+      *CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE));
 
   // Functions with this map will not have a 'prototype' property, and
   // can not be used as constructors.
-  Handle<Map> function_without_prototype_map =
-      Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
   global_context()->set_function_without_prototype_map(
-      *function_without_prototype_map);
-  Handle<DescriptorArray> function_without_prototype_map_descriptors =
-      ComputeFunctionInstanceDescriptor(DONT_ADD_PROTOTYPE);
-  function_without_prototype_map->set_instance_descriptors(
-      *function_without_prototype_map_descriptors);
-  function_without_prototype_map->set_function_with_prototype(false);
+      *CreateFunctionMap(DONT_ADD_PROTOTYPE));
 
-  // Allocate the function map first and then patch the prototype later
-  fm = Factory::NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
-  global_context()->set_function_map(*fm);
-  function_map_descriptors =
-      ComputeFunctionInstanceDescriptor(ADD_READONLY_PROTOTYPE);
-  fm->set_instance_descriptors(*function_map_descriptors);
-  fm->set_function_with_prototype(true);
+  // Allocate the function map. This map is temporary, used only for processing
+  // of builtins.
+  // Later the map is replaced with writable prototype map, allocated below.
+  global_context()->set_function_map(
+      *CreateFunctionMap(ADD_READONLY_PROTOTYPE));
 
-  Handle<String> object_name = Handle<String>(Heap::Object_symbol());
+  // The final map for functions. Writeable prototype.
+  // This map is installed in MakeFunctionInstancePrototypeWritable.
+  function_instance_map_writable_prototype_ =
+      CreateFunctionMap(ADD_WRITEABLE_PROTOTYPE);
+
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+
+  Handle<String> object_name = Handle<String>(heap->Object_symbol());
 
   {  // --- O b j e c t ---
     Handle<JSFunction> object_fun =
-        Factory::NewFunction(object_name, Factory::null_value());
+        factory->NewFunction(object_name, factory->null_value());
     Handle<Map> object_function_map =
-        Factory::NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+        factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
     object_fun->set_initial_map(*object_function_map);
     object_function_map->set_constructor(*object_fun);
 
     global_context()->set_object_function(*object_fun);
 
     // Allocate a new prototype for the object function.
-    Handle<JSObject> prototype = Factory::NewJSObject(Top::object_function(),
-                                                      TENURED);
+    Handle<JSObject> prototype = factory->NewJSObject(
+        isolate->object_function(),
+        TENURED);
 
     global_context()->set_initial_object_prototype(*prototype);
     SetPrototype(object_fun, prototype);
     object_function_map->
-      set_instance_descriptors(Heap::empty_descriptor_array());
+      set_instance_descriptors(heap->empty_descriptor_array());
   }
 
   // Allocate the empty function as the prototype for function ECMAScript
   // 262 15.3.4.
-  Handle<String> symbol = Factory::LookupAsciiSymbol("Empty");
+  Handle<String> symbol = factory->LookupAsciiSymbol("Empty");
   Handle<JSFunction> empty_function =
-      Factory::NewFunctionWithoutPrototype(symbol);
+      factory->NewFunctionWithoutPrototype(symbol, kNonStrictMode);
 
   // --- E m p t y ---
   Handle<Code> code =
-      Handle<Code>(Builtins::builtin(Builtins::EmptyFunction));
+      Handle<Code>(isolate->builtins()->builtin(
+          Builtins::kEmptyFunction));
   empty_function->set_code(*code);
   empty_function->shared()->set_code(*code);
-  Handle<String> source = Factory::NewStringFromAscii(CStrVector("() {}"));
-  Handle<Script> script = Factory::NewScript(source);
+  Handle<String> source = factory->NewStringFromAscii(CStrVector("() {}"));
+  Handle<Script> script = factory->NewScript(source);
   script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
   empty_function->shared()->set_script(*script);
   empty_function->shared()->set_start_position(0);
   empty_function->shared()->set_end_position(source->length());
   empty_function->shared()->DontAdaptArguments();
+
+  // Set prototypes for the function maps.
   global_context()->function_map()->set_prototype(*empty_function);
   global_context()->function_instance_map()->set_prototype(*empty_function);
   global_context()->function_without_prototype_map()->
       set_prototype(*empty_function);
+  function_instance_map_writable_prototype_->set_prototype(*empty_function);
 
   // Allocate the function map first and then patch the prototype later
-  Handle<Map> empty_fm = Factory::CopyMapDropDescriptors(
+  Handle<Map> function_without_prototype_map(
+      global_context()->function_without_prototype_map());
+  Handle<Map> empty_fm = factory->CopyMapDropDescriptors(
       function_without_prototype_map);
   empty_fm->set_instance_descriptors(
-      *function_without_prototype_map_descriptors);
+      function_without_prototype_map->instance_descriptors());
   empty_fm->set_prototype(global_context()->object_function()->prototype());
   empty_function->set_map(*empty_fm);
   return empty_function;
 }
 
 
+Handle<DescriptorArray> Genesis::ComputeStrictFunctionInstanceDescriptor(
+    PrototypePropertyMode prototypeMode,
+    Handle<FixedArray> arguments,
+    Handle<FixedArray> caller) {
+  Factory* factory = Isolate::Current()->factory();
+  Handle<DescriptorArray> descriptors =
+      factory->NewDescriptorArray(prototypeMode == DONT_ADD_PROTOTYPE ? 4 : 5);
+  PropertyAttributes attributes = static_cast<PropertyAttributes>(
+      DONT_ENUM | DONT_DELETE | READ_ONLY);
+
+  {  // length
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionLength);
+    CallbacksDescriptor d(*factory->length_symbol(), *proxy, attributes);
+    descriptors->Set(0, &d);
+  }
+  {  // name
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionName);
+    CallbacksDescriptor d(*factory->name_symbol(), *proxy, attributes);
+    descriptors->Set(1, &d);
+  }
+  {  // arguments
+    CallbacksDescriptor d(*factory->arguments_symbol(), *arguments, attributes);
+    descriptors->Set(2, &d);
+  }
+  {  // caller
+    CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
+    descriptors->Set(3, &d);
+  }
+
+  // prototype
+  if (prototypeMode != DONT_ADD_PROTOTYPE) {
+    if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) {
+      attributes = static_cast<PropertyAttributes>(attributes & ~READ_ONLY);
+    }
+    Handle<Proxy> proxy = factory->NewProxy(&Accessors::FunctionPrototype);
+    CallbacksDescriptor d(*factory->prototype_symbol(), *proxy, attributes);
+    descriptors->Set(4, &d);
+  }
+
+  descriptors->Sort();
+  return descriptors;
+}
+
+
+// ECMAScript 5th Edition, 13.2.3
+Handle<JSFunction> Genesis::CreateThrowTypeErrorFunction(
+    Builtins::Name builtin) {
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+
+  Handle<String> name = factory->LookupAsciiSymbol("ThrowTypeError");
+  Handle<JSFunction> throw_type_error =
+      factory->NewFunctionWithoutPrototype(name, kStrictMode);
+  Handle<Code> code = Handle<Code>(
+      isolate->builtins()->builtin(builtin));
+
+  throw_type_error->set_map(global_context()->strict_mode_function_map());
+  throw_type_error->set_code(*code);
+  throw_type_error->shared()->set_code(*code);
+  throw_type_error->shared()->DontAdaptArguments();
+
+  PreventExtensions(throw_type_error);
+
+  return throw_type_error;
+}
+
+
+Handle<Map> Genesis::CreateStrictModeFunctionMap(
+    PrototypePropertyMode prototype_mode,
+    Handle<JSFunction> empty_function,
+    Handle<FixedArray> arguments_callbacks,
+    Handle<FixedArray> caller_callbacks) {
+  Handle<Map> map = FACTORY->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
+  Handle<DescriptorArray> descriptors =
+      ComputeStrictFunctionInstanceDescriptor(prototype_mode,
+                                              arguments_callbacks,
+                                              caller_callbacks);
+  map->set_instance_descriptors(*descriptors);
+  map->set_function_with_prototype(prototype_mode != DONT_ADD_PROTOTYPE);
+  map->set_prototype(*empty_function);
+  return map;
+}
+
+
+void Genesis::CreateStrictModeFunctionMaps(Handle<JSFunction> empty) {
+  // Create the callbacks arrays for ThrowTypeError functions.
+  // The get/set callacks are filled in after the maps are created below.
+  Factory* factory = Isolate::Current()->factory();
+  Handle<FixedArray> arguments = factory->NewFixedArray(2, TENURED);
+  Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
+
+  // Allocate map for the strict mode function instances.
+  global_context()->set_strict_mode_function_instance_map(
+      *CreateStrictModeFunctionMap(
+          ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller));
+
+  // Allocate map for the prototype-less strict mode instances.
+  global_context()->set_strict_mode_function_without_prototype_map(
+      *CreateStrictModeFunctionMap(
+          DONT_ADD_PROTOTYPE, empty, arguments, caller));
+
+  // Allocate map for the strict mode functions. This map is temporary, used
+  // only for processing of builtins.
+  // Later the map is replaced with writable prototype map, allocated below.
+  global_context()->set_strict_mode_function_map(
+      *CreateStrictModeFunctionMap(
+          ADD_READONLY_PROTOTYPE, empty, arguments, caller));
+
+  // The final map for the strict mode functions. Writeable prototype.
+  // This map is installed in MakeFunctionInstancePrototypeWritable.
+  strict_mode_function_instance_map_writable_prototype_ =
+      CreateStrictModeFunctionMap(
+          ADD_WRITEABLE_PROTOTYPE, empty, arguments, caller);
+
+  // Create the ThrowTypeError function instances.
+  Handle<JSFunction> arguments_throw =
+      CreateThrowTypeErrorFunction(Builtins::kStrictFunctionArguments);
+  Handle<JSFunction> caller_throw =
+      CreateThrowTypeErrorFunction(Builtins::kStrictFunctionCaller);
+
+  // Complete the callback fixed arrays.
+  arguments->set(0, *arguments_throw);
+  arguments->set(1, *arguments_throw);
+  caller->set(0, *caller_throw);
+  caller->set(1, *caller_throw);
+}
+
+
 static void AddToWeakGlobalContextList(Context* context) {
   ASSERT(context->IsGlobalContext());
+  Heap* heap = Isolate::Current()->heap();
 #ifdef DEBUG
   { // NOLINT
     ASSERT(context->get(Context::NEXT_CONTEXT_LINK)->IsUndefined());
     // Check that context is not in the list yet.
-    for (Object* current = Heap::global_contexts_list();
+    for (Object* current = heap->global_contexts_list();
          !current->IsUndefined();
          current = Context::cast(current)->get(Context::NEXT_CONTEXT_LINK)) {
       ASSERT(current != context);
     }
   }
 #endif
-  context->set(Context::NEXT_CONTEXT_LINK, Heap::global_contexts_list());
-  Heap::set_global_contexts_list(context);
+  context->set(Context::NEXT_CONTEXT_LINK, heap->global_contexts_list());
+  heap->set_global_contexts_list(context);
 }
 
 
 void Genesis::CreateRoots() {
+  Isolate* isolate = Isolate::Current();
   // Allocate the global context FixedArray first and then patch the
   // closure and extension object later (we need the empty function
   // and the global object, but in order to create those, we need the
   // global context).
-  global_context_ =
-      Handle<Context>::cast(
-          GlobalHandles::Create(*Factory::NewGlobalContext()));
+  global_context_ = Handle<Context>::cast(isolate->global_handles()->Create(
+              *isolate->factory()->NewGlobalContext()));
   AddToWeakGlobalContextList(*global_context_);
-  Top::set_context(*global_context());
+  isolate->set_context(*global_context());
 
   // Allocate the message listeners object.
   {
@@ -569,11 +685,16 @@
     }
   }
 
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+
   if (js_global_template.is_null()) {
-    Handle<String> name = Handle<String>(Heap::empty_symbol());
-    Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+    Handle<String> name = Handle<String>(heap->empty_symbol());
+    Handle<Code> code = Handle<Code>(isolate->builtins()->builtin(
+        Builtins::kIllegal));
     js_global_function =
-        Factory::NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
+        factory->NewFunction(name, JS_GLOBAL_OBJECT_TYPE,
                              JSGlobalObject::kSize, code, true);
     // Change the constructor property of the prototype of the
     // hidden global function to refer to the Object function.
@@ -581,18 +702,21 @@
         Handle<JSObject>(
             JSObject::cast(js_global_function->instance_prototype()));
     SetLocalPropertyNoThrow(
-        prototype, Factory::constructor_symbol(), Top::object_function(), NONE);
+        prototype,
+        factory->constructor_symbol(),
+        isolate->object_function(),
+        NONE);
   } else {
     Handle<FunctionTemplateInfo> js_global_constructor(
         FunctionTemplateInfo::cast(js_global_template->constructor()));
     js_global_function =
-        Factory::CreateApiFunction(js_global_constructor,
-                                   Factory::InnerGlobalObject);
+        factory->CreateApiFunction(js_global_constructor,
+                                   factory->InnerGlobalObject);
   }
 
   js_global_function->initial_map()->set_is_hidden_prototype();
   Handle<GlobalObject> inner_global =
-      Factory::NewGlobalObject(js_global_function);
+      factory->NewGlobalObject(js_global_function);
   if (inner_global_out != NULL) {
     *inner_global_out = inner_global;
   }
@@ -600,10 +724,11 @@
   // Step 2: create or re-initialize the global proxy object.
   Handle<JSFunction> global_proxy_function;
   if (global_template.IsEmpty()) {
-    Handle<String> name = Handle<String>(Heap::empty_symbol());
-    Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+    Handle<String> name = Handle<String>(heap->empty_symbol());
+    Handle<Code> code = Handle<Code>(isolate->builtins()->builtin(
+        Builtins::kIllegal));
     global_proxy_function =
-        Factory::NewFunction(name, JS_GLOBAL_PROXY_TYPE,
+        factory->NewFunction(name, JS_GLOBAL_PROXY_TYPE,
                              JSGlobalProxy::kSize, code, true);
   } else {
     Handle<ObjectTemplateInfo> data =
@@ -611,11 +736,11 @@
     Handle<FunctionTemplateInfo> global_constructor(
             FunctionTemplateInfo::cast(data->constructor()));
     global_proxy_function =
-        Factory::CreateApiFunction(global_constructor,
-                                   Factory::OuterGlobalObject);
+        factory->CreateApiFunction(global_constructor,
+                                   factory->OuterGlobalObject);
   }
 
-  Handle<String> global_name = Factory::LookupAsciiSymbol("global");
+  Handle<String> global_name = factory->LookupAsciiSymbol("global");
   global_proxy_function->shared()->set_instance_class_name(*global_name);
   global_proxy_function->initial_map()->set_is_access_check_needed(true);
 
@@ -629,7 +754,7 @@
         Handle<JSGlobalProxy>::cast(global_object));
   } else {
     return Handle<JSGlobalProxy>::cast(
-        Factory::NewJSObject(global_proxy_function, TENURED));
+        factory->NewJSObject(global_proxy_function, TENURED));
   }
 }
 
@@ -654,7 +779,7 @@
   static const PropertyAttributes attributes =
       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
   ForceSetProperty(builtins_global,
-                   Factory::LookupAsciiSymbol("global"),
+                   FACTORY->LookupAsciiSymbol("global"),
                    inner_global,
                    attributes);
   // Setup the reference from the global object to the builtins object.
@@ -682,33 +807,37 @@
   // object reinitialization.
   global_context()->set_security_token(*inner_global);
 
-  Handle<String> object_name = Handle<String>(Heap::Object_symbol());
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+
+  Handle<String> object_name = Handle<String>(heap->Object_symbol());
   SetLocalPropertyNoThrow(inner_global, object_name,
-                          Top::object_function(), DONT_ENUM);
+                          isolate->object_function(), DONT_ENUM);
 
   Handle<JSObject> global = Handle<JSObject>(global_context()->global());
 
   // Install global Function object
   InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
-                  empty_function, Builtins::Illegal, true);  // ECMA native.
+                  empty_function, Builtins::kIllegal, true);  // ECMA native.
 
   {  // --- A r r a y ---
     Handle<JSFunction> array_function =
         InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize,
-                        Top::initial_object_prototype(), Builtins::ArrayCode,
-                        true);
+                        isolate->initial_object_prototype(),
+                        Builtins::kArrayCode, true);
     array_function->shared()->set_construct_stub(
-        Builtins::builtin(Builtins::ArrayConstructCode));
+        isolate->builtins()->builtin(Builtins::kArrayConstructCode));
     array_function->shared()->DontAdaptArguments();
 
     // This seems a bit hackish, but we need to make sure Array.length
     // is 1.
     array_function->shared()->set_length(1);
     Handle<DescriptorArray> array_descriptors =
-        Factory::CopyAppendProxyDescriptor(
-            Factory::empty_descriptor_array(),
-            Factory::length_symbol(),
-            Factory::NewProxy(&Accessors::ArrayLength),
+        factory->CopyAppendProxyDescriptor(
+            factory->empty_descriptor_array(),
+            factory->length_symbol(),
+            factory->NewProxy(&Accessors::ArrayLength),
             static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
 
     // Cache the fast JavaScript array map
@@ -725,33 +854,33 @@
   {  // --- N u m b e r ---
     Handle<JSFunction> number_fun =
         InstallFunction(global, "Number", JS_VALUE_TYPE, JSValue::kSize,
-                        Top::initial_object_prototype(), Builtins::Illegal,
-                        true);
+                        isolate->initial_object_prototype(),
+                        Builtins::kIllegal, true);
     global_context()->set_number_function(*number_fun);
   }
 
   {  // --- B o o l e a n ---
     Handle<JSFunction> boolean_fun =
         InstallFunction(global, "Boolean", JS_VALUE_TYPE, JSValue::kSize,
-                        Top::initial_object_prototype(), Builtins::Illegal,
-                        true);
+                        isolate->initial_object_prototype(),
+                        Builtins::kIllegal, true);
     global_context()->set_boolean_function(*boolean_fun);
   }
 
   {  // --- S t r i n g ---
     Handle<JSFunction> string_fun =
         InstallFunction(global, "String", JS_VALUE_TYPE, JSValue::kSize,
-                        Top::initial_object_prototype(), Builtins::Illegal,
-                        true);
+                        isolate->initial_object_prototype(),
+                        Builtins::kIllegal, true);
     string_fun->shared()->set_construct_stub(
-        Builtins::builtin(Builtins::StringConstructCode));
+        isolate->builtins()->builtin(Builtins::kStringConstructCode));
     global_context()->set_string_function(*string_fun);
     // Add 'length' property to strings.
     Handle<DescriptorArray> string_descriptors =
-        Factory::CopyAppendProxyDescriptor(
-            Factory::empty_descriptor_array(),
-            Factory::length_symbol(),
-            Factory::NewProxy(&Accessors::StringLength),
+        factory->CopyAppendProxyDescriptor(
+            factory->empty_descriptor_array(),
+            factory->length_symbol(),
+            factory->NewProxy(&Accessors::StringLength),
             static_cast<PropertyAttributes>(DONT_ENUM |
                                             DONT_DELETE |
                                             READ_ONLY));
@@ -765,8 +894,8 @@
     // Builtin functions for Date.prototype.
     Handle<JSFunction> date_fun =
         InstallFunction(global, "Date", JS_VALUE_TYPE, JSValue::kSize,
-                        Top::initial_object_prototype(), Builtins::Illegal,
-                        true);
+                        isolate->initial_object_prototype(),
+                        Builtins::kIllegal, true);
 
     global_context()->set_date_function(*date_fun);
   }
@@ -776,8 +905,8 @@
     // Builtin functions for RegExp.prototype.
     Handle<JSFunction> regexp_fun =
         InstallFunction(global, "RegExp", JS_REGEXP_TYPE, JSRegExp::kSize,
-                        Top::initial_object_prototype(), Builtins::Illegal,
-                        true);
+                        isolate->initial_object_prototype(),
+                        Builtins::kIllegal, true);
     global_context()->set_regexp_function(*regexp_fun);
 
     ASSERT(regexp_fun->has_initial_map());
@@ -785,13 +914,13 @@
 
     ASSERT_EQ(0, initial_map->inobject_properties());
 
-    Handle<DescriptorArray> descriptors = Factory::NewDescriptorArray(5);
+    Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(5);
     PropertyAttributes final =
         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
     int enum_index = 0;
     {
       // ECMA-262, section 15.10.7.1.
-      FieldDescriptor field(Heap::source_symbol(),
+      FieldDescriptor field(heap->source_symbol(),
                             JSRegExp::kSourceFieldIndex,
                             final,
                             enum_index++);
@@ -799,7 +928,7 @@
     }
     {
       // ECMA-262, section 15.10.7.2.
-      FieldDescriptor field(Heap::global_symbol(),
+      FieldDescriptor field(heap->global_symbol(),
                             JSRegExp::kGlobalFieldIndex,
                             final,
                             enum_index++);
@@ -807,7 +936,7 @@
     }
     {
       // ECMA-262, section 15.10.7.3.
-      FieldDescriptor field(Heap::ignore_case_symbol(),
+      FieldDescriptor field(heap->ignore_case_symbol(),
                             JSRegExp::kIgnoreCaseFieldIndex,
                             final,
                             enum_index++);
@@ -815,7 +944,7 @@
     }
     {
       // ECMA-262, section 15.10.7.4.
-      FieldDescriptor field(Heap::multiline_symbol(),
+      FieldDescriptor field(heap->multiline_symbol(),
                             JSRegExp::kMultilineFieldIndex,
                             final,
                             enum_index++);
@@ -825,7 +954,7 @@
       // ECMA-262, section 15.10.7.5.
       PropertyAttributes writable =
           static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
-      FieldDescriptor field(Heap::last_index_symbol(),
+      FieldDescriptor field(heap->last_index_symbol(),
                             JSRegExp::kLastIndexFieldIndex,
                             writable,
                             enum_index++);
@@ -844,13 +973,13 @@
   }
 
   {  // -- J S O N
-    Handle<String> name = Factory::NewStringFromAscii(CStrVector("JSON"));
-    Handle<JSFunction> cons = Factory::NewFunction(
+    Handle<String> name = factory->NewStringFromAscii(CStrVector("JSON"));
+    Handle<JSFunction> cons = factory->NewFunction(
         name,
-        Factory::the_hole_value());
+        factory->the_hole_value());
     cons->SetInstancePrototype(global_context()->initial_object_prototype());
     cons->SetInstanceClassName(*name);
-    Handle<JSObject> json_object = Factory::NewJSObject(cons, TENURED);
+    Handle<JSObject> json_object = factory->NewJSObject(cons, TENURED);
     ASSERT(json_object->IsJSObject());
     SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
     global_context()->set_json_object(*json_object);
@@ -860,14 +989,15 @@
     // Make sure we can recognize argument objects at runtime.
     // This is done by introducing an anonymous function with
     // class_name equals 'Arguments'.
-    Handle<String> symbol = Factory::LookupAsciiSymbol("Arguments");
-    Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+    Handle<String> symbol = factory->LookupAsciiSymbol("Arguments");
+    Handle<Code> code = Handle<Code>(
+        isolate->builtins()->builtin(Builtins::kIllegal));
     Handle<JSObject> prototype =
         Handle<JSObject>(
             JSObject::cast(global_context()->object_function()->prototype()));
 
     Handle<JSFunction> function =
-        Factory::NewFunctionWithPrototype(symbol,
+        factory->NewFunctionWithPrototype(symbol,
                                           JS_OBJECT_TYPE,
                                           JSObject::kHeaderSize,
                                           prototype,
@@ -876,30 +1006,101 @@
     ASSERT(!function->has_initial_map());
     function->shared()->set_instance_class_name(*symbol);
     function->shared()->set_expected_nof_properties(2);
-    Handle<JSObject> result = Factory::NewJSObject(function);
+    Handle<JSObject> result = factory->NewJSObject(function);
 
     global_context()->set_arguments_boilerplate(*result);
-    // Note: callee must be added as the first property and
-    //       length must be added as the second property.
-    SetLocalPropertyNoThrow(result, Factory::callee_symbol(),
-                            Factory::undefined_value(),
+    // Note: length must be added as the first property and
+    //       callee must be added as the second property.
+    SetLocalPropertyNoThrow(result, factory->length_symbol(),
+                            factory->undefined_value(),
                             DONT_ENUM);
-    SetLocalPropertyNoThrow(result, Factory::length_symbol(),
-                            Factory::undefined_value(),
+    SetLocalPropertyNoThrow(result, factory->callee_symbol(),
+                            factory->undefined_value(),
                             DONT_ENUM);
 
 #ifdef DEBUG
     LookupResult lookup;
-    result->LocalLookup(Heap::callee_symbol(), &lookup);
+    result->LocalLookup(heap->callee_symbol(), &lookup);
     ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
-    ASSERT(lookup.GetFieldIndex() == Heap::arguments_callee_index);
+    ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsCalleeIndex);
 
-    result->LocalLookup(Heap::length_symbol(), &lookup);
+    result->LocalLookup(heap->length_symbol(), &lookup);
     ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
-    ASSERT(lookup.GetFieldIndex() == Heap::arguments_length_index);
+    ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
 
-    ASSERT(result->map()->inobject_properties() > Heap::arguments_callee_index);
-    ASSERT(result->map()->inobject_properties() > Heap::arguments_length_index);
+    ASSERT(result->map()->inobject_properties() > Heap::kArgumentsCalleeIndex);
+    ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
+
+    // Check the state of the object.
+    ASSERT(result->HasFastProperties());
+    ASSERT(result->HasFastElements());
+#endif
+  }
+
+  {  // --- strict mode arguments boilerplate
+    const PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+
+    // Create the ThrowTypeError functions.
+    Handle<FixedArray> callee = factory->NewFixedArray(2, TENURED);
+    Handle<FixedArray> caller = factory->NewFixedArray(2, TENURED);
+
+    Handle<JSFunction> callee_throw =
+        CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCallee);
+    Handle<JSFunction> caller_throw =
+        CreateThrowTypeErrorFunction(Builtins::kStrictArgumentsCaller);
+
+    // Install the ThrowTypeError functions.
+    callee->set(0, *callee_throw);
+    callee->set(1, *callee_throw);
+    caller->set(0, *caller_throw);
+    caller->set(1, *caller_throw);
+
+    // Create the descriptor array for the arguments object.
+    Handle<DescriptorArray> descriptors = factory->NewDescriptorArray(3);
+    {  // length
+      FieldDescriptor d(*factory->length_symbol(), 0, DONT_ENUM);
+      descriptors->Set(0, &d);
+    }
+    {  // callee
+      CallbacksDescriptor d(*factory->callee_symbol(), *callee, attributes);
+      descriptors->Set(1, &d);
+    }
+    {  // caller
+      CallbacksDescriptor d(*factory->caller_symbol(), *caller, attributes);
+      descriptors->Set(2, &d);
+    }
+    descriptors->Sort();
+
+    // Create the map. Allocate one in-object field for length.
+    Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE,
+                                      Heap::kArgumentsObjectSizeStrict);
+    map->set_instance_descriptors(*descriptors);
+    map->set_function_with_prototype(true);
+    map->set_prototype(global_context()->object_function()->prototype());
+    map->set_pre_allocated_property_fields(1);
+    map->set_inobject_properties(1);
+
+    // Copy constructor from the non-strict arguments boilerplate.
+    map->set_constructor(
+      global_context()->arguments_boilerplate()->map()->constructor());
+
+    // Allocate the arguments boilerplate object.
+    Handle<JSObject> result = factory->NewJSObjectFromMap(map);
+    global_context()->set_strict_mode_arguments_boilerplate(*result);
+
+    // Add length property only for strict mode boilerplate.
+    SetLocalPropertyNoThrow(result, factory->length_symbol(),
+                            factory->undefined_value(),
+                            DONT_ENUM);
+
+#ifdef DEBUG
+    LookupResult lookup;
+    result->LocalLookup(heap->length_symbol(), &lookup);
+    ASSERT(lookup.IsProperty() && (lookup.type() == FIELD));
+    ASSERT(lookup.GetFieldIndex() == Heap::kArgumentsLengthIndex);
+
+    ASSERT(result->map()->inobject_properties() > Heap::kArgumentsLengthIndex);
 
     // Check the state of the object.
     ASSERT(result->HasFastProperties());
@@ -909,15 +1110,16 @@
 
   {  // --- context extension
     // Create a function for the context extension objects.
-    Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+    Handle<Code> code = Handle<Code>(
+        isolate->builtins()->builtin(Builtins::kIllegal));
     Handle<JSFunction> context_extension_fun =
-        Factory::NewFunction(Factory::empty_symbol(),
+        factory->NewFunction(factory->empty_symbol(),
                              JS_CONTEXT_EXTENSION_OBJECT_TYPE,
                              JSObject::kHeaderSize,
                              code,
                              true);
 
-    Handle<String> name = Factory::LookupAsciiSymbol("context_extension");
+    Handle<String> name = factory->LookupAsciiSymbol("context_extension");
     context_extension_fun->shared()->set_instance_class_name(*name);
     global_context()->set_context_extension_function(*context_extension_fun);
   }
@@ -926,9 +1128,10 @@
   {
     // Setup the call-as-function delegate.
     Handle<Code> code =
-        Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsFunction));
+        Handle<Code>(isolate->builtins()->builtin(
+            Builtins::kHandleApiCallAsFunction));
     Handle<JSFunction> delegate =
-        Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
+        factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
                              JSObject::kHeaderSize, code, true);
     global_context()->set_call_as_function_delegate(*delegate);
     delegate->shared()->DontAdaptArguments();
@@ -937,44 +1140,47 @@
   {
     // Setup the call-as-constructor delegate.
     Handle<Code> code =
-        Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsConstructor));
+        Handle<Code>(isolate->builtins()->builtin(
+            Builtins::kHandleApiCallAsConstructor));
     Handle<JSFunction> delegate =
-        Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
+        factory->NewFunction(factory->empty_symbol(), JS_OBJECT_TYPE,
                              JSObject::kHeaderSize, code, true);
     global_context()->set_call_as_constructor_delegate(*delegate);
     delegate->shared()->DontAdaptArguments();
   }
 
   // Initialize the out of memory slot.
-  global_context()->set_out_of_memory(Heap::false_value());
+  global_context()->set_out_of_memory(heap->false_value());
 
   // Initialize the data slot.
-  global_context()->set_data(Heap::undefined_value());
+  global_context()->set_data(heap->undefined_value());
 }
 
 
 bool Genesis::CompileBuiltin(int index) {
   Vector<const char> name = Natives::GetScriptName(index);
-  Handle<String> source_code = Bootstrapper::NativesSourceLookup(index);
+  Handle<String> source_code =
+      Isolate::Current()->bootstrapper()->NativesSourceLookup(index);
   return CompileNative(name, source_code);
 }
 
 
 bool Genesis::CompileNative(Vector<const char> name, Handle<String> source) {
   HandleScope scope;
+  Isolate* isolate = Isolate::Current();
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  Debugger::set_compiling_natives(true);
+  isolate->debugger()->set_compiling_natives(true);
 #endif
   bool result = CompileScriptCached(name,
                                     source,
                                     NULL,
                                     NULL,
-                                    Handle<Context>(Top::context()),
+                                    Handle<Context>(isolate->context()),
                                     true);
-  ASSERT(Top::has_pending_exception() != result);
-  if (!result) Top::clear_pending_exception();
+  ASSERT(isolate->has_pending_exception() != result);
+  if (!result) isolate->clear_pending_exception();
 #ifdef ENABLE_DEBUGGER_SUPPORT
-  Debugger::set_compiling_natives(false);
+  isolate->debugger()->set_compiling_natives(false);
 #endif
   return result;
 }
@@ -986,6 +1192,7 @@
                                   v8::Extension* extension,
                                   Handle<Context> top_context,
                                   bool use_runtime_context) {
+  Factory* factory = Isolate::Current()->factory();
   HandleScope scope;
   Handle<SharedFunctionInfo> function_info;
 
@@ -993,7 +1200,7 @@
   // function and insert it into the cache.
   if (cache == NULL || !cache->Lookup(name, &function_info)) {
     ASSERT(source->IsAsciiRepresentation());
-    Handle<String> script_name = Factory::NewStringFromUtf8(name);
+    Handle<String> script_name = factory->NewStringFromUtf8(name);
     function_info = Compiler::Compile(
         source,
         script_name,
@@ -1016,7 +1223,7 @@
                       ? Handle<Context>(top_context->runtime_context())
                       : top_context);
   Handle<JSFunction> fun =
-      Factory::NewFunctionFromSharedFunctionInfo(function_info, context);
+      factory->NewFunctionFromSharedFunctionInfo(function_info, context);
 
   // Call function using either the runtime object or the global
   // object as the receiver. Provide no parameters.
@@ -1033,11 +1240,13 @@
 
 
 #define INSTALL_NATIVE(Type, name, var)                                     \
-  Handle<String> var##_name = Factory::LookupAsciiSymbol(name);             \
+  Handle<String> var##_name = factory->LookupAsciiSymbol(name);             \
   global_context()->set_##var(Type::cast(                                   \
       global_context()->builtins()->GetPropertyNoExceptionThrown(*var##_name)));
 
+
 void Genesis::InstallNativeFunctions() {
+  Factory* factory = Isolate::Current()->factory();
   HandleScope scope;
   INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
   INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
@@ -1060,21 +1269,25 @@
 
 bool Genesis::InstallNatives() {
   HandleScope scope;
+  Isolate* isolate = Isolate::Current();
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
 
   // Create a function for the builtins object. Allocate space for the
   // JavaScript builtins, a reference to the builtins object
   // (itself) and a reference to the global_context directly in the object.
-  Handle<Code> code = Handle<Code>(Builtins::builtin(Builtins::Illegal));
+  Handle<Code> code = Handle<Code>(
+      isolate->builtins()->builtin(Builtins::kIllegal));
   Handle<JSFunction> builtins_fun =
-      Factory::NewFunction(Factory::empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
+      factory->NewFunction(factory->empty_symbol(), JS_BUILTINS_OBJECT_TYPE,
                            JSBuiltinsObject::kSize, code, true);
 
-  Handle<String> name = Factory::LookupAsciiSymbol("builtins");
+  Handle<String> name = factory->LookupAsciiSymbol("builtins");
   builtins_fun->shared()->set_instance_class_name(*name);
 
   // Allocate the builtins object.
   Handle<JSBuiltinsObject> builtins =
-      Handle<JSBuiltinsObject>::cast(Factory::NewGlobalObject(builtins_fun));
+      Handle<JSBuiltinsObject>::cast(factory->NewGlobalObject(builtins_fun));
   builtins->set_builtins(*builtins);
   builtins->set_global_context(*global_context());
   builtins->set_global_receiver(*builtins);
@@ -1085,7 +1298,7 @@
   // global object.
   static const PropertyAttributes attributes =
       static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
-  Handle<String> global_symbol = Factory::LookupAsciiSymbol("global");
+  Handle<String> global_symbol = factory->LookupAsciiSymbol("global");
   Handle<Object> global_obj(global_context()->global());
   SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
 
@@ -1094,12 +1307,12 @@
 
   // Create a bridge function that has context in the global context.
   Handle<JSFunction> bridge =
-      Factory::NewFunction(Factory::empty_symbol(), Factory::undefined_value());
-  ASSERT(bridge->context() == *Top::global_context());
+      factory->NewFunction(factory->empty_symbol(), factory->undefined_value());
+  ASSERT(bridge->context() == *isolate->global_context());
 
   // Allocate the builtins context.
   Handle<Context> context =
-    Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
+    factory->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, bridge);
   context->set_global(*builtins);  // override builtins global object
 
   global_context()->set_runtime_context(*context);
@@ -1108,113 +1321,113 @@
     // Builtin functions for Script.
     Handle<JSFunction> script_fun =
         InstallFunction(builtins, "Script", JS_VALUE_TYPE, JSValue::kSize,
-                        Top::initial_object_prototype(), Builtins::Illegal,
-                        false);
+                        isolate->initial_object_prototype(),
+                        Builtins::kIllegal, false);
     Handle<JSObject> prototype =
-        Factory::NewJSObject(Top::object_function(), TENURED);
+        factory->NewJSObject(isolate->object_function(), TENURED);
     SetPrototype(script_fun, prototype);
     global_context()->set_script_function(*script_fun);
 
     // Add 'source' and 'data' property to scripts.
     PropertyAttributes common_attributes =
         static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
-    Handle<Proxy> proxy_source = Factory::NewProxy(&Accessors::ScriptSource);
+    Handle<Proxy> proxy_source = factory->NewProxy(&Accessors::ScriptSource);
     Handle<DescriptorArray> script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
-            Factory::empty_descriptor_array(),
-            Factory::LookupAsciiSymbol("source"),
+        factory->CopyAppendProxyDescriptor(
+            factory->empty_descriptor_array(),
+            factory->LookupAsciiSymbol("source"),
             proxy_source,
             common_attributes);
-    Handle<Proxy> proxy_name = Factory::NewProxy(&Accessors::ScriptName);
+    Handle<Proxy> proxy_name = factory->NewProxy(&Accessors::ScriptName);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("name"),
+            factory->LookupAsciiSymbol("name"),
             proxy_name,
             common_attributes);
-    Handle<Proxy> proxy_id = Factory::NewProxy(&Accessors::ScriptId);
+    Handle<Proxy> proxy_id = factory->NewProxy(&Accessors::ScriptId);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("id"),
+            factory->LookupAsciiSymbol("id"),
             proxy_id,
             common_attributes);
     Handle<Proxy> proxy_line_offset =
-        Factory::NewProxy(&Accessors::ScriptLineOffset);
+        factory->NewProxy(&Accessors::ScriptLineOffset);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("line_offset"),
+            factory->LookupAsciiSymbol("line_offset"),
             proxy_line_offset,
             common_attributes);
     Handle<Proxy> proxy_column_offset =
-        Factory::NewProxy(&Accessors::ScriptColumnOffset);
+        factory->NewProxy(&Accessors::ScriptColumnOffset);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("column_offset"),
+            factory->LookupAsciiSymbol("column_offset"),
             proxy_column_offset,
             common_attributes);
-    Handle<Proxy> proxy_data = Factory::NewProxy(&Accessors::ScriptData);
+    Handle<Proxy> proxy_data = factory->NewProxy(&Accessors::ScriptData);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("data"),
+            factory->LookupAsciiSymbol("data"),
             proxy_data,
             common_attributes);
-    Handle<Proxy> proxy_type = Factory::NewProxy(&Accessors::ScriptType);
+    Handle<Proxy> proxy_type = factory->NewProxy(&Accessors::ScriptType);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("type"),
+            factory->LookupAsciiSymbol("type"),
             proxy_type,
             common_attributes);
     Handle<Proxy> proxy_compilation_type =
-        Factory::NewProxy(&Accessors::ScriptCompilationType);
+        factory->NewProxy(&Accessors::ScriptCompilationType);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("compilation_type"),
+            factory->LookupAsciiSymbol("compilation_type"),
             proxy_compilation_type,
             common_attributes);
     Handle<Proxy> proxy_line_ends =
-        Factory::NewProxy(&Accessors::ScriptLineEnds);
+        factory->NewProxy(&Accessors::ScriptLineEnds);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("line_ends"),
+            factory->LookupAsciiSymbol("line_ends"),
             proxy_line_ends,
             common_attributes);
     Handle<Proxy> proxy_context_data =
-        Factory::NewProxy(&Accessors::ScriptContextData);
+        factory->NewProxy(&Accessors::ScriptContextData);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("context_data"),
+            factory->LookupAsciiSymbol("context_data"),
             proxy_context_data,
             common_attributes);
     Handle<Proxy> proxy_eval_from_script =
-        Factory::NewProxy(&Accessors::ScriptEvalFromScript);
+        factory->NewProxy(&Accessors::ScriptEvalFromScript);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("eval_from_script"),
+            factory->LookupAsciiSymbol("eval_from_script"),
             proxy_eval_from_script,
             common_attributes);
     Handle<Proxy> proxy_eval_from_script_position =
-        Factory::NewProxy(&Accessors::ScriptEvalFromScriptPosition);
+        factory->NewProxy(&Accessors::ScriptEvalFromScriptPosition);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("eval_from_script_position"),
+            factory->LookupAsciiSymbol("eval_from_script_position"),
             proxy_eval_from_script_position,
             common_attributes);
     Handle<Proxy> proxy_eval_from_function_name =
-        Factory::NewProxy(&Accessors::ScriptEvalFromFunctionName);
+        factory->NewProxy(&Accessors::ScriptEvalFromFunctionName);
     script_descriptors =
-        Factory::CopyAppendProxyDescriptor(
+        factory->CopyAppendProxyDescriptor(
             script_descriptors,
-            Factory::LookupAsciiSymbol("eval_from_function_name"),
+            factory->LookupAsciiSymbol("eval_from_function_name"),
             proxy_eval_from_function_name,
             common_attributes);
 
@@ -1222,9 +1435,9 @@
     script_map->set_instance_descriptors(*script_descriptors);
 
     // Allocate the empty script.
-    Handle<Script> script = Factory::NewScript(Factory::empty_string());
+    Handle<Script> script = factory->NewScript(factory->empty_string());
     script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
-    Heap::public_set_empty_script(*script);
+    heap->public_set_empty_script(*script);
   }
   {
     // Builtin function for OpaqueReference -- a JSValue-based object,
@@ -1232,10 +1445,11 @@
     // objects, that JavaScript code may not access.
     Handle<JSFunction> opaque_reference_fun =
         InstallFunction(builtins, "OpaqueReference", JS_VALUE_TYPE,
-                        JSValue::kSize, Top::initial_object_prototype(),
-                        Builtins::Illegal, false);
+                        JSValue::kSize,
+                        isolate->initial_object_prototype(),
+                        Builtins::kIllegal, false);
     Handle<JSObject> prototype =
-        Factory::NewJSObject(Top::object_function(), TENURED);
+        factory->NewJSObject(isolate->object_function(), TENURED);
     SetPrototype(opaque_reference_fun, prototype);
     global_context()->set_opaque_reference_function(*opaque_reference_fun);
   }
@@ -1254,23 +1468,23 @@
                         "InternalArray",
                         JS_ARRAY_TYPE,
                         JSArray::kSize,
-                        Top::initial_object_prototype(),
-                        Builtins::ArrayCode,
+                        isolate->initial_object_prototype(),
+                        Builtins::kArrayCode,
                         true);
     Handle<JSObject> prototype =
-        Factory::NewJSObject(Top::object_function(), TENURED);
+        factory->NewJSObject(isolate->object_function(), TENURED);
     SetPrototype(array_function, prototype);
 
     array_function->shared()->set_construct_stub(
-        Builtins::builtin(Builtins::ArrayConstructCode));
+        isolate->builtins()->builtin(Builtins::kArrayConstructCode));
     array_function->shared()->DontAdaptArguments();
 
     // Make "length" magic on instances.
     Handle<DescriptorArray> array_descriptors =
-        Factory::CopyAppendProxyDescriptor(
-            Factory::empty_descriptor_array(),
-            Factory::length_symbol(),
-            Factory::NewProxy(&Accessors::ArrayLength),
+        factory->CopyAppendProxyDescriptor(
+            factory->empty_descriptor_array(),
+            factory->length_symbol(),
+            factory->NewProxy(&Accessors::ArrayLength),
             static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE));
 
     array_function->initial_map()->set_instance_descriptors(
@@ -1307,9 +1521,9 @@
   InstallBuiltinFunctionIds();
 
   // Install Function.prototype.call and apply.
-  { Handle<String> key = Factory::function_class_symbol();
+  { Handle<String> key = factory->function_class_symbol();
     Handle<JSFunction> function =
-        Handle<JSFunction>::cast(GetProperty(Top::global(), key));
+        Handle<JSFunction>::cast(GetProperty(isolate->global(), key));
     Handle<JSObject> proto =
         Handle<JSObject>(JSObject::cast(function->instance_prototype()));
 
@@ -1317,12 +1531,12 @@
     Handle<JSFunction> call =
         InstallFunction(proto, "call", JS_OBJECT_TYPE, JSObject::kHeaderSize,
                         Handle<JSObject>::null(),
-                        Builtins::FunctionCall,
+                        Builtins::kFunctionCall,
                         false);
     Handle<JSFunction> apply =
         InstallFunction(proto, "apply", JS_OBJECT_TYPE, JSObject::kHeaderSize,
                         Handle<JSObject>::null(),
-                        Builtins::FunctionApply,
+                        Builtins::kFunctionApply,
                         false);
 
     // Make sure that Function.prototype.call appears to be compiled.
@@ -1351,7 +1565,7 @@
 
     // Add initial map.
     Handle<Map> initial_map =
-        Factory::NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
+        factory->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize);
     initial_map->set_constructor(*array_constructor);
 
     // Set prototype on map.
@@ -1365,13 +1579,13 @@
     ASSERT_EQ(1, array_descriptors->number_of_descriptors());
 
     Handle<DescriptorArray> reresult_descriptors =
-        Factory::NewDescriptorArray(3);
+        factory->NewDescriptorArray(3);
 
     reresult_descriptors->CopyFrom(0, *array_descriptors, 0);
 
     int enum_index = 0;
     {
-      FieldDescriptor index_field(Heap::index_symbol(),
+      FieldDescriptor index_field(heap->index_symbol(),
                                   JSRegExpResult::kIndexIndex,
                                   NONE,
                                   enum_index++);
@@ -1379,7 +1593,7 @@
     }
 
     {
-      FieldDescriptor input_field(Heap::input_symbol(),
+      FieldDescriptor input_field(heap->input_symbol(),
                                   JSRegExpResult::kInputIndex,
                                   NONE,
                                   enum_index++);
@@ -1407,17 +1621,18 @@
 static Handle<JSObject> ResolveBuiltinIdHolder(
     Handle<Context> global_context,
     const char* holder_expr) {
+  Factory* factory = Isolate::Current()->factory();
   Handle<GlobalObject> global(global_context->global());
   const char* period_pos = strchr(holder_expr, '.');
   if (period_pos == NULL) {
     return Handle<JSObject>::cast(
-        GetProperty(global, Factory::LookupAsciiSymbol(holder_expr)));
+        GetProperty(global, factory->LookupAsciiSymbol(holder_expr)));
   }
   ASSERT_EQ(".prototype", period_pos);
   Vector<const char> property(holder_expr,
                               static_cast<int>(period_pos - holder_expr));
   Handle<JSFunction> function = Handle<JSFunction>::cast(
-      GetProperty(global, Factory::LookupSymbol(property)));
+      GetProperty(global, factory->LookupSymbol(property)));
   return Handle<JSObject>(JSObject::cast(function->prototype()));
 }
 
@@ -1425,7 +1640,7 @@
 static void InstallBuiltinFunctionId(Handle<JSObject> holder,
                                      const char* function_name,
                                      BuiltinFunctionId id) {
-  Handle<String> name = Factory::LookupAsciiSymbol(function_name);
+  Handle<String> name = FACTORY->LookupAsciiSymbol(function_name);
   Object* function_object = holder->GetProperty(*name)->ToObjectUnchecked();
   Handle<JSFunction> function(JSFunction::cast(function_object));
   function->shared()->set_function_data(Smi::FromInt(id));
@@ -1457,7 +1672,7 @@
   int array_size = JSFunctionResultCache::kEntriesIndex + 2 * size;
   // Cannot use cast as object is not fully initialized yet.
   JSFunctionResultCache* cache = reinterpret_cast<JSFunctionResultCache*>(
-      *Factory::NewFixedArrayWithHoles(array_size, TENURED));
+      *FACTORY->NewFixedArrayWithHoles(array_size, TENURED));
   cache->set(JSFunctionResultCache::kFactoryIndex, factory);
   cache->MakeZeroSize();
   return cache;
@@ -1471,7 +1686,7 @@
 #undef F
   ;
 
-  Handle<FixedArray> caches = Factory::NewFixedArray(kNumberOfCaches, TENURED);
+  Handle<FixedArray> caches = FACTORY->NewFixedArray(kNumberOfCaches, TENURED);
 
   int index = 0;
 
@@ -1490,19 +1705,17 @@
 
 void Genesis::InitializeNormalizedMapCaches() {
   Handle<FixedArray> array(
-      Factory::NewFixedArray(NormalizedMapCache::kEntries, TENURED));
+      FACTORY->NewFixedArray(NormalizedMapCache::kEntries, TENURED));
   global_context()->set_normalized_map_cache(NormalizedMapCache::cast(*array));
 }
 
 
-int BootstrapperActive::nesting_ = 0;
-
-
 bool Bootstrapper::InstallExtensions(Handle<Context> global_context,
                                      v8::ExtensionConfiguration* extensions) {
+  Isolate* isolate = Isolate::Current();
   BootstrapperActive active;
-  SaveContext saved_context;
-  Top::set_context(*global_context);
+  SaveContext saved_context(isolate);
+  isolate->set_context(*global_context);
   if (!Genesis::InstallExtensions(global_context, extensions)) return false;
   Genesis::InstallSpecialObjects(global_context);
   return true;
@@ -1510,20 +1723,21 @@
 
 
 void Genesis::InstallSpecialObjects(Handle<Context> global_context) {
+  Factory* factory = Isolate::Current()->factory();
   HandleScope scope;
   Handle<JSGlobalObject> js_global(
       JSGlobalObject::cast(global_context->global()));
   // Expose the natives in global if a name for it is specified.
   if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) != 0) {
     Handle<String> natives_string =
-        Factory::LookupAsciiSymbol(FLAG_expose_natives_as);
+        factory->LookupAsciiSymbol(FLAG_expose_natives_as);
     SetLocalPropertyNoThrow(js_global, natives_string,
                             Handle<JSObject>(js_global->builtins()), DONT_ENUM);
   }
 
   Handle<Object> Error = GetProperty(js_global, "Error");
   if (Error->IsJSObject()) {
-    Handle<String> name = Factory::LookupAsciiSymbol("stackTraceLimit");
+    Handle<String> name = factory->LookupAsciiSymbol("stackTraceLimit");
     SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
                             name,
                             Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
@@ -1533,18 +1747,19 @@
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Expose the debug global object in global if a name for it is specified.
   if (FLAG_expose_debug_as != NULL && strlen(FLAG_expose_debug_as) != 0) {
+    Debug* debug = Isolate::Current()->debug();
     // If loading fails we just bail out without installing the
     // debugger but without tanking the whole context.
-    if (!Debug::Load()) return;
+    if (!debug->Load()) return;
     // Set the security token for the debugger context to the same as
     // the shell global context to allow calling between these (otherwise
     // exposing debug global object doesn't make much sense).
-    Debug::debug_context()->set_security_token(
+    debug->debug_context()->set_security_token(
         global_context->security_token());
 
     Handle<String> debug_string =
-        Factory::LookupAsciiSymbol(FLAG_expose_debug_as);
-    Handle<Object> global_proxy(Debug::debug_context()->global_proxy());
+        factory->LookupAsciiSymbol(FLAG_expose_debug_as);
+    Handle<Object> global_proxy(debug->debug_context()->global_proxy());
     SetLocalPropertyNoThrow(js_global, debug_string, global_proxy, DONT_ENUM);
   }
 #endif
@@ -1553,6 +1768,10 @@
 
 bool Genesis::InstallExtensions(Handle<Context> global_context,
                                 v8::ExtensionConfiguration* extensions) {
+  // TODO(isolates): Extensions on multiple isolates may take a little more
+  //                 effort. (The external API reads 'ignore'-- does that mean
+  //                 we can break the interface?)
+
   // Clear coloring of extension list
   v8::RegisteredExtension* current = v8::RegisteredExtension::first_extension();
   while (current != NULL) {
@@ -1620,17 +1839,18 @@
   for (int i = 0; i < extension->dependency_count(); i++) {
     if (!InstallExtension(extension->dependencies()[i])) return false;
   }
+  Isolate* isolate = Isolate::Current();
   Vector<const char> source = CStrVector(extension->source());
-  Handle<String> source_code = Factory::NewStringFromAscii(source);
+  Handle<String> source_code = isolate->factory()->NewStringFromAscii(source);
   bool result = CompileScriptCached(CStrVector(extension->name()),
                                     source_code,
-                                    &extensions_cache,
+                                    isolate->bootstrapper()->extensions_cache(),
                                     extension,
-                                    Handle<Context>(Top::context()),
+                                    Handle<Context>(isolate->context()),
                                     false);
-  ASSERT(Top::has_pending_exception() != result);
+  ASSERT(isolate->has_pending_exception() != result);
   if (!result) {
-    Top::clear_pending_exception();
+    isolate->clear_pending_exception();
   }
   current->set_state(v8::INSTALLED);
   return result;
@@ -1641,7 +1861,7 @@
   HandleScope scope;
   for (int i = 0; i < Builtins::NumberOfJavaScriptBuiltins(); i++) {
     Builtins::JavaScript id = static_cast<Builtins::JavaScript>(i);
-    Handle<String> name = Factory::LookupAsciiSymbol(Builtins::GetName(id));
+    Handle<String> name = FACTORY->LookupAsciiSymbol(Builtins::GetName(id));
     Object* function_object = builtins->GetPropertyNoExceptionThrown(*name);
     Handle<JSFunction> function
         = Handle<JSFunction>(JSFunction::cast(function_object));
@@ -1690,12 +1910,13 @@
   ASSERT(object->IsInstanceOf(
       FunctionTemplateInfo::cast(object_template->constructor())));
 
+  Isolate* isolate = Isolate::Current();
   bool pending_exception = false;
   Handle<JSObject> obj =
       Execution::InstantiateObject(object_template, &pending_exception);
   if (pending_exception) {
-    ASSERT(Top::has_pending_exception());
-    Top::clear_pending_exception();
+    ASSERT(isolate->has_pending_exception());
+    isolate->clear_pending_exception();
     return false;
   }
   TransferObject(obj, object);
@@ -1743,6 +1964,7 @@
           break;
         }
         case MAP_TRANSITION:
+        case EXTERNAL_ARRAY_TRANSITION:
         case CONSTANT_TRANSITION:
         case NULL_DESCRIPTOR:
           // Ignore non-properties.
@@ -1786,7 +2008,7 @@
   // Cloning the elements array is sufficient.
   Handle<FixedArray> from_elements =
       Handle<FixedArray>(FixedArray::cast(from->elements()));
-  Handle<FixedArray> to_elements = Factory::CopyFixedArray(from_elements);
+  Handle<FixedArray> to_elements = FACTORY->CopyFixedArray(from_elements);
   to->set_elements(*to_elements);
 }
 
@@ -1802,29 +2024,31 @@
 
   // Transfer the prototype (new map is needed).
   Handle<Map> old_to_map = Handle<Map>(to->map());
-  Handle<Map> new_to_map = Factory::CopyMapDropTransitions(old_to_map);
+  Handle<Map> new_to_map = FACTORY->CopyMapDropTransitions(old_to_map);
   new_to_map->set_prototype(from->map()->prototype());
   to->set_map(*new_to_map);
 }
 
 
 void Genesis::MakeFunctionInstancePrototypeWritable() {
-  // Make a new function map so all future functions
-  // will have settable and enumerable prototype properties.
-  HandleScope scope;
+  // The maps with writable prototype are created in CreateEmptyFunction
+  // and CreateStrictModeFunctionMaps respectively. Initially the maps are
+  // created with read-only prototype for JS builtins processing.
+  ASSERT(!function_instance_map_writable_prototype_.is_null());
+  ASSERT(!strict_mode_function_instance_map_writable_prototype_.is_null());
 
-  Handle<DescriptorArray> function_map_descriptors =
-      ComputeFunctionInstanceDescriptor(ADD_WRITEABLE_PROTOTYPE);
-  Handle<Map> fm = Factory::CopyMapDropDescriptors(Top::function_map());
-  fm->set_instance_descriptors(*function_map_descriptors);
-  fm->set_function_with_prototype(true);
-  Top::context()->global_context()->set_function_map(*fm);
+  // Replace function instance maps to make prototype writable.
+  global_context()->set_function_map(
+    *function_instance_map_writable_prototype_);
+  global_context()->set_strict_mode_function_map(
+    *strict_mode_function_instance_map_writable_prototype_);
 }
 
 
 Genesis::Genesis(Handle<Object> global_object,
                  v8::Handle<v8::ObjectTemplate> global_template,
                  v8::ExtensionConfiguration* extensions) {
+  Isolate* isolate = Isolate::Current();
   result_ = Handle<Context>::null();
   // If V8 isn't running and cannot be initialized, just return.
   if (!V8::IsRunning() && !V8::Initialize(NULL)) return;
@@ -1832,18 +2056,15 @@
   // Before creating the roots we must save the context and restore it
   // on all function exits.
   HandleScope scope;
-  SaveContext saved_context;
+  SaveContext saved_context(isolate);
 
   Handle<Context> new_context = Snapshot::NewContextFromSnapshot();
   if (!new_context.is_null()) {
     global_context_ =
-      Handle<Context>::cast(GlobalHandles::Create(*new_context));
+        Handle<Context>::cast(isolate->global_handles()->Create(*new_context));
     AddToWeakGlobalContextList(*global_context_);
-    Top::set_context(*global_context_);
-    i::Counters::contexts_created_by_snapshot.Increment();
-    JSFunction* empty_function =
-        JSFunction::cast(global_context_->function_map()->prototype());
-    empty_function_ = Handle<JSFunction>(empty_function);
+    isolate->set_context(*global_context_);
+    isolate->counters()->contexts_created_by_snapshot()->Increment();
     Handle<GlobalObject> inner_global;
     Handle<JSGlobalProxy> global_proxy =
         CreateNewGlobals(global_template,
@@ -1858,6 +2079,7 @@
     // We get here if there was no context snapshot.
     CreateRoots();
     Handle<JSFunction> empty_function = CreateEmptyFunction();
+    CreateStrictModeFunctionMaps(empty_function);
     Handle<GlobalObject> inner_global;
     Handle<JSGlobalProxy> global_proxy =
         CreateNewGlobals(global_template, global_object, &inner_global);
@@ -1870,7 +2092,7 @@
     MakeFunctionInstancePrototypeWritable();
 
     if (!ConfigureGlobalObjects(global_template)) return;
-    i::Counters::contexts_created_from_scratch.Increment();
+    isolate->counters()->contexts_created_from_scratch()->Increment();
   }
 
   result_ = global_context_;
@@ -1881,46 +2103,28 @@
 
 // Reserve space for statics needing saving and restoring.
 int Bootstrapper::ArchiveSpacePerThread() {
-  return BootstrapperActive::ArchiveSpacePerThread();
+  return sizeof(NestingCounterType);
 }
 
 
 // Archive statics that are thread local.
 char* Bootstrapper::ArchiveState(char* to) {
-  return BootstrapperActive::ArchiveState(to);
+  *reinterpret_cast<NestingCounterType*>(to) = nesting_;
+  nesting_ = 0;
+  return to + sizeof(NestingCounterType);
 }
 
 
 // Restore statics that are thread local.
 char* Bootstrapper::RestoreState(char* from) {
-  return BootstrapperActive::RestoreState(from);
+  nesting_ = *reinterpret_cast<NestingCounterType*>(from);
+  return from + sizeof(NestingCounterType);
 }
 
 
 // Called when the top-level V8 mutex is destroyed.
 void Bootstrapper::FreeThreadResources() {
-  ASSERT(!BootstrapperActive::IsActive());
-}
-
-
-// Reserve space for statics needing saving and restoring.
-int BootstrapperActive::ArchiveSpacePerThread() {
-  return sizeof(nesting_);
-}
-
-
-// Archive statics that are thread local.
-char* BootstrapperActive::ArchiveState(char* to) {
-  *reinterpret_cast<int*>(to) = nesting_;
-  nesting_ = 0;
-  return to + sizeof(nesting_);
-}
-
-
-// Restore statics that are thread local.
-char* BootstrapperActive::RestoreState(char* from) {
-  nesting_ = *reinterpret_cast<int*>(from);
-  return from + sizeof(nesting_);
+  ASSERT(!IsActive());
 }
 
 } }  // namespace v8::internal