Version 1.3.5

Optimize initialization of some arrays in the builtins.

Fix mac-nm script to support filenames with spaces.

Support for using the V8 profiler when V8 is embedded in a Windows DLL.

Changed typeof RegExp from 'object' to 'function' for compatibility. Fixed bug where regexps were not callable across contexts.

Added context independent script compilation to the API.

Added API call to get the stack trace for an exception.

Added API for getting object mirrors.

Make sure that SSE3 instructions are used whenever possible even when running off a snapshot generated without using SSE3 instructions.

Tweaked the handling of the initial size and growth policy of the heap.

Added native code generation for RegExp to 64-bit version.

Added JavaScript debugger support to 64-bit version.



git-svn-id: http://v8.googlecode.com/svn/trunk@2722 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 4bfd8d5..c59661d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2009-08-19: Version 1.3.5
+
+        Optimize initialization of some arrays in the builtins.
+
+        Fix mac-nm script to support filenames with spaces.
+
+        Support for using the V8 profiler when V8 is embedded in a Windows DLL.
+
+        Changed typeof RegExp from 'object' to 'function' for compatibility.
+        Fixed bug where regexps were not callable across contexts.
+
+        Added context independent script compilation to the API.
+
+        Added API call to get the stack trace for an exception.
+
+        Added API for getting object mirrors.
+
+        Make sure that SSE3 instructions are used whenever possible even when
+        running off a snapshot generated without using SSE3 instructions.
+
+        Tweaked the handling of the initial size and growth policy of the heap.
+
+        Added native code generation for RegExp to 64-bit version.
+
+        Added JavaScript debugger support to 64-bit version.
+
+
 2009-08-13: Version 1.3.4
 
         Added a readline() command to the d8 shell.
diff --git a/SConstruct b/SConstruct
index c981ef9..efd34db 100644
--- a/SConstruct
+++ b/SConstruct
@@ -101,6 +101,9 @@
     'regexp:native': {
       'arch:ia32' : {
         'CPPDEFINES': ['V8_NATIVE_REGEXP']
+      },
+      'arch:x64' : {
+        'CPPDEFINES': ['V8_NATIVE_REGEXP']
       }
     }
   },
@@ -166,7 +169,7 @@
     },
     'arch:x64': {
       'CPPDEFINES':   ['V8_TARGET_ARCH_X64'],
-      'CCFLAGS':      ['-fno-strict-aliasing', '-m64'],
+      'CCFLAGS':      ['-m64'],
       'LINKFLAGS':    ['-m64'],
     },
     'prof:oprofile': {
@@ -716,7 +719,11 @@
     result = []
     result += source.get('all', [])
     for (name, value) in self.options.iteritems():
-      result += source.get(name + ':' + value, [])
+      source_value = source.get(name + ':' + value, [])
+      if type(source_value) == dict:
+        result += self.GetRelevantSources(source_value)
+      else:
+        result += source_value
     return sorted(result)
 
   def AppendFlags(self, options, added):
diff --git a/include/v8-debug.h b/include/v8-debug.h
index 345d331..3c5c923 100644
--- a/include/v8-debug.h
+++ b/include/v8-debug.h
@@ -228,9 +228,14 @@
   *   }
   * \endcode
   */
-  static Handle<Value> Call(v8::Handle<v8::Function> fun,
+  static Local<Value> Call(v8::Handle<v8::Function> fun,
                             Handle<Value> data = Handle<Value>());
 
+  /**
+   * Returns a mirror object for the given object.
+   */
+  static Local<Value> GetMirror(v8::Handle<v8::Value> obj);
+
  /**
   * Enable the V8 builtin debug agent. The debugger agent will listen on the
   * supplied TCP/IP port for remote debugger connection.
diff --git a/include/v8.h b/include/v8.h
index d8de00c..a0cc4ea 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -513,10 +513,36 @@
 class V8EXPORT Script {
  public:
 
+   /**
+    * Compiles the specified script. The ScriptOrigin* and ScriptData*
+    * parameters are owned by the caller of Script::Compile. No
+    * references to these objects are kept after compilation finishes.
+    *
+    * The script object returned is context independent; when run it
+    * will use the currently entered context.
+    */
+   static Local<Script> New(Handle<String> source,
+                            ScriptOrigin* origin = NULL,
+                            ScriptData* pre_data = NULL);
+
+   /**
+    * Compiles the specified script using the specified file name
+    * object (typically a string) as the script's origin.
+    *
+    * The script object returned is context independent; when run it
+    * will use the currently entered context.
+    */
+   static Local<Script> New(Handle<String> source,
+                            Handle<Value> file_name);
+
   /**
    * Compiles the specified script. The ScriptOrigin* and ScriptData*
    * parameters are owned by the caller of Script::Compile. No
    * references to these objects are kept after compilation finishes.
+   *
+   * The script object returned is bound to the context that was active
+   * when this function was called.  When run it will always use this
+   * context.
    */
   static Local<Script> Compile(Handle<String> source,
                                ScriptOrigin* origin = NULL,
@@ -525,12 +551,20 @@
   /**
    * Compiles the specified script using the specified file name
    * object (typically a string) as the script's origin.
+   *
+   * The script object returned is bound to the context that was active
+   * when this function was called.  When run it will always use this
+   * context.
    */
   static Local<Script> Compile(Handle<String> source,
                                Handle<Value> file_name);
 
   /**
-   * Runs the script returning the resulting value.
+   * Runs the script returning the resulting value.  If the script is
+   * context independent (created using ::New) it will be run in the
+   * currently entered context.  If it is context specific (created
+   * using ::Compile) it will be run in the context in which it was
+   * compiled.
    */
   Local<Value> Run();
 
@@ -2256,6 +2290,12 @@
   Local<Value> Exception() const;
 
   /**
+   * Returns the .stack property of the thrown object.  If no .stack
+   * property is present an empty handle is returned.
+   */
+  Local<Value> StackTrace() const;
+
+  /**
    * Returns the message associated with this exception.  If there is
    * no message associated an empty handle is returned.
    *
diff --git a/src/SConscript b/src/SConscript
index a9669a1..6a38c1a 100755
--- a/src/SConscript
+++ b/src/SConscript
@@ -63,24 +63,32 @@
     'arm/register-allocator-arm.cc', 'arm/stub-cache-arm.cc',
     'arm/virtual-frame-arm.cc'
   ],
-  'arch:ia32': [
-    'ia32/assembler-ia32.cc', 'ia32/builtins-ia32.cc', 'ia32/cfg-ia32.cc',
-    'ia32/codegen-ia32.cc', 'ia32/cpu-ia32.cc', 'ia32/disasm-ia32.cc',
-    'ia32/debug-ia32.cc', 'ia32/frames-ia32.cc', 'ia32/ic-ia32.cc',
-    'ia32/jump-target-ia32.cc', 'ia32/macro-assembler-ia32.cc',
-    'ia32/regexp-macro-assembler-ia32.cc',
-    'ia32/register-allocator-ia32.cc', 'ia32/stub-cache-ia32.cc',
-    'ia32/virtual-frame-ia32.cc'
-  ],
-  'arch:x64': [
-    'x64/assembler-x64.cc', 'x64/builtins-x64.cc', 'x64/cfg-x64.cc',
-    'x64/codegen-x64.cc', 'x64/cpu-x64.cc', 'x64/disasm-x64.cc',
-    'x64/debug-x64.cc', 'x64/frames-x64.cc', 'x64/ic-x64.cc',
-    'x64/jump-target-x64.cc', 'x64/macro-assembler-x64.cc',
-    # 'x64/regexp-macro-assembler-x64.cc',
-    'x64/register-allocator-x64.cc',
-    'x64/stub-cache-x64.cc', 'x64/virtual-frame-x64.cc'
-  ],
+  'arch:ia32': {
+    'all': [
+      'ia32/assembler-ia32.cc', 'ia32/builtins-ia32.cc', 'ia32/cfg-ia32.cc',
+      'ia32/codegen-ia32.cc', 'ia32/cpu-ia32.cc', 'ia32/disasm-ia32.cc',
+      'ia32/debug-ia32.cc', 'ia32/frames-ia32.cc', 'ia32/ic-ia32.cc',
+      'ia32/jump-target-ia32.cc', 'ia32/macro-assembler-ia32.cc',
+      'ia32/register-allocator-ia32.cc', 'ia32/stub-cache-ia32.cc',
+      'ia32/virtual-frame-ia32.cc'
+    ],
+    'regexp:native': [
+      'ia32/regexp-macro-assembler-ia32.cc',
+    ]
+  },
+  'arch:x64': {
+    'all': [
+      'x64/assembler-x64.cc', 'x64/builtins-x64.cc', 'x64/cfg-x64.cc',
+      'x64/codegen-x64.cc', 'x64/cpu-x64.cc', 'x64/disasm-x64.cc',
+      'x64/debug-x64.cc', 'x64/frames-x64.cc', 'x64/ic-x64.cc',
+      'x64/jump-target-x64.cc', 'x64/macro-assembler-x64.cc',
+      'x64/register-allocator-x64.cc',
+      'x64/stub-cache-x64.cc', 'x64/virtual-frame-x64.cc'
+    ],
+    'regexp:native': [
+      'x64/regexp-macro-assembler-x64.cc'
+    ]
+  },
   'simulator:arm': ['arm/simulator-arm.cc'],
   'os:freebsd': ['platform-freebsd.cc', 'platform-posix.cc'],
   'os:linux':   ['platform-linux.cc', 'platform-posix.cc'],
diff --git a/src/api.cc b/src/api.cc
index 0dc4fd7..88cf2bcd 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1046,7 +1046,7 @@
 
 ScriptData* ScriptData::PreCompile(const char* input, int length) {
   unibrow::Utf8InputBuffer<> buf(input, length);
-  return i::PreParse(&buf, NULL);
+  return i::PreParse(i::Handle<i::String>(), &buf, NULL);
 }
 
 
@@ -1058,11 +1058,11 @@
 // --- S c r i p t ---
 
 
-Local<Script> Script::Compile(v8::Handle<String> source,
-                              v8::ScriptOrigin* origin,
-                              v8::ScriptData* script_data) {
-  ON_BAILOUT("v8::Script::Compile()", return Local<Script>());
-  LOG_API("Script::Compile");
+Local<Script> Script::New(v8::Handle<String> source,
+                          v8::ScriptOrigin* origin,
+                          v8::ScriptData* script_data) {
+  ON_BAILOUT("v8::Script::New()", return Local<Script>());
+  LOG_API("Script::New");
   ENTER_V8;
   i::Handle<i::String> str = Utils::OpenHandle(*source);
   i::Handle<i::Object> name_obj;
@@ -1096,6 +1096,27 @@
                                                               pre_data);
   has_pending_exception = boilerplate.is_null();
   EXCEPTION_BAILOUT_CHECK(Local<Script>());
+  return Local<Script>(ToApi<Script>(boilerplate));
+}
+
+
+Local<Script> Script::New(v8::Handle<String> source,
+                          v8::Handle<Value> file_name) {
+  ScriptOrigin origin(file_name);
+  return New(source, &origin);
+}
+
+
+Local<Script> Script::Compile(v8::Handle<String> source,
+                              v8::ScriptOrigin* origin,
+                              v8::ScriptData* script_data) {
+  ON_BAILOUT("v8::Script::Compile()", return Local<Script>());
+  LOG_API("Script::Compile");
+  ENTER_V8;
+  Local<Script> generic = New(source, origin, script_data);
+  if (generic.IsEmpty())
+    return generic;
+  i::Handle<i::JSFunction> boilerplate = Utils::OpenHandle(*generic);
   i::Handle<i::JSFunction> result =
       i::Factory::NewFunctionFromBoilerplate(boilerplate,
                                              i::Top::global_context());
@@ -1118,6 +1139,10 @@
   {
     HandleScope scope;
     i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
+    if (fun->IsBoilerplate()) {
+      fun = i::Factory::NewFunctionFromBoilerplate(fun,
+                                                   i::Top::global_context());
+    }
     EXCEPTION_PREAMBLE();
     i::Handle<i::Object> receiver(i::Top::context()->global_proxy());
     i::Handle<i::Object> result =
@@ -1194,6 +1219,22 @@
 }
 
 
+v8::Local<Value> v8::TryCatch::StackTrace() const {
+  if (HasCaught()) {
+    i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
+    if (!raw_obj->IsJSObject()) return v8::Local<Value>();
+    v8::HandleScope scope;
+    i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj));
+    i::Handle<i::String> name = i::Factory::LookupAsciiSymbol("stack");
+    if (!obj->HasProperty(*name))
+      return v8::Local<Value>();
+    return scope.Close(v8::Utils::ToLocal(i::GetProperty(obj, name)));
+  } else {
+    return v8::Local<Value>();
+  }
+}
+
+
 v8::Local<v8::Message> v8::TryCatch::Message() const {
   if (HasCaught() && message_ != i::Smi::FromInt(0)) {
     i::Object* message = reinterpret_cast<i::Object*>(message_);
@@ -2593,8 +2634,13 @@
   i::Handle<i::Context> env;
   {
     ENTER_V8;
+#if defined(ANDROID)
+    // On mobile device, full GC is expensive, leave it to the system to
+    // decide when should make a full GC.
+#else
     // Give the heap a chance to cleanup if we've disposed contexts.
     i::Heap::CollectAllGarbageIfContextDisposed();
+#endif
     v8::Handle<ObjectTemplate> proxy_template = global_template;
     i::Handle<i::FunctionTemplateInfo> proxy_constructor;
     i::Handle<i::FunctionTemplateInfo> global_constructor;
@@ -3549,10 +3595,10 @@
 }
 
 
-Handle<Value> Debug::Call(v8::Handle<v8::Function> fun,
-                          v8::Handle<v8::Value> data) {
-  if (!i::V8::IsRunning()) return Handle<Value>();
-  ON_BAILOUT("v8::Debug::Call()", return Handle<Value>());
+Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
+                         v8::Handle<v8::Value> data) {
+  if (!i::V8::IsRunning()) return Local<Value>();
+  ON_BAILOUT("v8::Debug::Call()", return Local<Value>());
   ENTER_V8;
   i::Handle<i::Object> result;
   EXCEPTION_PREAMBLE();
@@ -3570,6 +3616,28 @@
 }
 
 
+Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
+  if (!i::V8::IsRunning()) return Local<Value>();
+  ON_BAILOUT("v8::Debug::GetMirror()", return Local<Value>());
+  ENTER_V8;
+  v8::HandleScope scope;
+  i::Debug::Load();
+  i::Handle<i::JSObject> debug(i::Debug::debug_context()->global());
+  i::Handle<i::String> name = i::Factory::LookupAsciiSymbol("MakeMirror");
+  i::Handle<i::Object> fun_obj = i::GetProperty(debug, name);
+  i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
+  v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
+  const int kArgc = 1;
+  v8::Handle<v8::Value> argv[kArgc] = { obj };
+  EXCEPTION_PREAMBLE();
+  v8::Handle<v8::Value> result = v8_fun->Call(Utils::ToLocal(debug),
+                                              kArgc,
+                                              argv);
+  EXCEPTION_BAILOUT_CHECK(Local<Value>());
+  return scope.Close(result);
+}
+
+
 bool Debug::EnableAgent(const char* name, int port) {
   return i::Debugger::StartAgent(name, port);
 }
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index eeab4a7..b3ebb8b 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -430,7 +430,10 @@
 
   // Distance between the instruction referring to the address of the call
   // target (ldr pc, [target addr in const pool]) and the return address
-  static const int kTargetAddrToReturnAddrDist = sizeof(Instr);
+  static const int kPatchReturnSequenceLength = sizeof(Instr);
+  // Distance between start of patched return sequence and the emitted address
+  // to jump to.
+  static const int kPatchReturnSequenceAddressOffset = 1;
 
 
   // ---------------------------------------------------------------------------
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index b5332ec..28524c8 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -39,7 +39,7 @@
 
 
 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
-  // TODO(1238487): Don't pass the function in a static variable.
+  // TODO(428): Don't pass the function in a static variable.
   __ mov(ip, Operand(ExternalReference::builtin_passed_function()));
   __ str(r1, MemOperand(ip, 0));
 
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index d3507ec..40b0ac8 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -5890,16 +5890,11 @@
   Label throw_out_of_memory_exception;
   Label throw_normal_exception;
 
-  // Call into the runtime system. Collect garbage before the call if
-  // running with --gc-greedy set.
-  if (FLAG_gc_greedy) {
-    Failure* failure = Failure::RetryAfterGC(0);
-    __ mov(r0, Operand(reinterpret_cast<intptr_t>(failure)));
-  }
+  // Call into the runtime system.
   GenerateCore(masm, &throw_normal_exception,
                &throw_out_of_memory_exception,
                frame_type,
-               FLAG_gc_greedy,
+               false,
                false);
 
   // Do space-specific GC and retry runtime call.
diff --git a/src/arm/codegen-arm.h b/src/arm/codegen-arm.h
index 80d1d56..70a7b27 100644
--- a/src/arm/codegen-arm.h
+++ b/src/arm/codegen-arm.h
@@ -152,14 +152,9 @@
 #endif
 
   static void SetFunctionInfo(Handle<JSFunction> fun,
-                              int length,
-                              int function_token_position,
-                              int start_position,
-                              int end_position,
-                              bool is_expression,
+                              FunctionLiteral* lit,
                               bool is_toplevel,
-                              Handle<Script> script,
-                              Handle<String> inferred_name);
+                              Handle<Script> script);
 
   // Accessors
   MacroAssembler* masm() { return masm_; }
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 875c91e..4b02e2d 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -132,7 +132,7 @@
   // and the target address of the call would be referenced by the first
   // instruction rather than the second one, which would make it harder to patch
   // (two instructions before the return address, instead of one).
-  ASSERT(kTargetAddrToReturnAddrDist == sizeof(Instr));
+  ASSERT(kPatchReturnSequenceLength == sizeof(Instr));
 }
 
 
diff --git a/src/assembler.h b/src/assembler.h
index 879ee54..1ddc8a3 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -216,6 +216,9 @@
 
   // Patch the code with a call.
   void PatchCodeWithCall(Address target, int guard_bytes);
+  // Check whether the current instruction is currently a call
+  // sequence (whether naturally or a return sequence overwritten
+  // to enter the debugger).
   INLINE(bool IsCallInstruction());
 
 #ifdef ENABLE_DISASSEMBLER
diff --git a/src/ast.h b/src/ast.h
index 3a309ac..ea83712 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -111,6 +111,7 @@
 // Typedef only introduced to avoid unreadable code.
 // Please do appreciate the required space in "> >".
 typedef ZoneList<Handle<String> > ZoneStringList;
+typedef ZoneList<Handle<Object> > ZoneObjectList;
 
 
 class AstNode: public ZoneObject {
@@ -1226,6 +1227,9 @@
                   int materialized_literal_count,
                   bool contains_array_literal,
                   int expected_property_count,
+                  bool has_only_this_property_assignments,
+                  bool has_only_simple_this_property_assignments,
+                  Handle<FixedArray> this_property_assignments,
                   int num_parameters,
                   int start_position,
                   int end_position,
@@ -1236,6 +1240,10 @@
         materialized_literal_count_(materialized_literal_count),
         contains_array_literal_(contains_array_literal),
         expected_property_count_(expected_property_count),
+        has_only_this_property_assignments_(has_only_this_property_assignments),
+        has_only_simple_this_property_assignments_(
+            has_only_simple_this_property_assignments),
+        this_property_assignments_(this_property_assignments),
         num_parameters_(num_parameters),
         start_position_(start_position),
         end_position_(end_position),
@@ -1265,6 +1273,15 @@
   int materialized_literal_count() { return materialized_literal_count_; }
   bool contains_array_literal() { return contains_array_literal_; }
   int expected_property_count() { return expected_property_count_; }
+  bool has_only_this_property_assignments() {
+      return has_only_this_property_assignments_;
+  }
+  bool has_only_simple_this_property_assignments() {
+      return has_only_simple_this_property_assignments_;
+  }
+  Handle<FixedArray> this_property_assignments() {
+      return this_property_assignments_;
+  }
   int num_parameters() { return num_parameters_; }
 
   bool AllowsLazyCompilation();
@@ -1291,6 +1308,9 @@
   int materialized_literal_count_;
   bool contains_array_literal_;
   int expected_property_count_;
+  bool has_only_this_property_assignments_;
+  bool has_only_simple_this_property_assignments_;
+  Handle<FixedArray> this_property_assignments_;
   int num_parameters_;
   int start_position_;
   int end_position_;
diff --git a/src/builtins.cc b/src/builtins.cc
index 1ea0245..dbd18f8 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -61,7 +61,7 @@
 // ----------------------------------------------------------------------------
 
 
-// TODO(1238487): We should consider passing whether or not the
+// TODO(428): We should consider passing whether or not the
 // builtin was invoked as a constructor as part of the
 // arguments. Maybe we also want to pass the called function?
 #define BUILTIN(name)                                                   \
@@ -336,9 +336,7 @@
   HandleScope scope;
   bool is_construct = CalledAsConstructor();
 
-  // TODO(1238487): This is not nice. We need to get rid of this
-  // kludgy behavior and start handling API calls in a more direct
-  // way - maybe compile specialized stubs lazily?.
+  // TODO(428): Remove use of static variable, handle API callbacks directly.
   Handle<JSFunction> function =
       Handle<JSFunction>(JSFunction::cast(Builtins::builtin_passed_function));
 
diff --git a/src/codegen.cc b/src/codegen.cc
index 7a4bb12..8e516c0 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -243,23 +243,22 @@
 // in the full script source. When counting characters in the script source the
 // the first character is number 0 (not 1).
 void CodeGenerator::SetFunctionInfo(Handle<JSFunction> fun,
-                                    int length,
-                                    int function_token_position,
-                                    int start_position,
-                                    int end_position,
-                                    bool is_expression,
+                                    FunctionLiteral* lit,
                                     bool is_toplevel,
-                                    Handle<Script> script,
-                                    Handle<String> inferred_name) {
-  fun->shared()->set_length(length);
-  fun->shared()->set_formal_parameter_count(length);
+                                    Handle<Script> script) {
+  fun->shared()->set_length(lit->num_parameters());
+  fun->shared()->set_formal_parameter_count(lit->num_parameters());
   fun->shared()->set_script(*script);
-  fun->shared()->set_function_token_position(function_token_position);
-  fun->shared()->set_start_position(start_position);
-  fun->shared()->set_end_position(end_position);
-  fun->shared()->set_is_expression(is_expression);
+  fun->shared()->set_function_token_position(lit->function_token_position());
+  fun->shared()->set_start_position(lit->start_position());
+  fun->shared()->set_end_position(lit->end_position());
+  fun->shared()->set_is_expression(lit->is_expression());
   fun->shared()->set_is_toplevel(is_toplevel);
-  fun->shared()->set_inferred_name(*inferred_name);
+  fun->shared()->set_inferred_name(*lit->inferred_name());
+  fun->shared()->SetThisPropertyAssignmentsInfo(
+      lit->has_only_this_property_assignments(),
+      lit->has_only_simple_this_property_assignments(),
+      *lit->this_property_assignments());
 }
 
 
@@ -317,11 +316,7 @@
                                       node->materialized_literal_count(),
                                       node->contains_array_literal(),
                                       code);
-  CodeGenerator::SetFunctionInfo(function, node->num_parameters(),
-                                 node->function_token_position(),
-                                 node->start_position(), node->end_position(),
-                                 node->is_expression(), false, script_,
-                                 node->inferred_name());
+  CodeGenerator::SetFunctionInfo(function, node, false, script_);
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // Notify debugger that a new function has been added.
diff --git a/src/compilation-cache.cc b/src/compilation-cache.cc
index ec5b39c..8dd9ec1 100644
--- a/src/compilation-cache.cc
+++ b/src/compilation-cache.cc
@@ -290,7 +290,6 @@
   HandleScope scope;
   ASSERT(boilerplate->IsBoilerplate());
   Handle<CompilationCacheTable> table = GetTable(0);
-  // TODO(X64): -fstrict-aliasing causes a problem with table.  Fix it.
   CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
 }
 
diff --git a/src/compiler.cc b/src/compiler.cc
index 5607f29..feff492 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -219,11 +219,8 @@
                                       lit->contains_array_literal(),
                                       code);
 
-  CodeGenerator::SetFunctionInfo(fun, lit->scope()->num_parameters(),
-                                 RelocInfo::kNoPosition,
-                                 lit->start_position(), lit->end_position(),
-                                 lit->is_expression(), true, script,
-                                 lit->inferred_name());
+  ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
+  CodeGenerator::SetFunctionInfo(fun, lit, true, script);
 
   // Hint to the runtime system used when allocating space for initial
   // property space by setting the expected number of properties for
@@ -269,7 +266,7 @@
     if (pre_data == NULL && source_length >= FLAG_min_preparse_length) {
       Access<SafeStringInputBuffer> buf(&safe_string_input_buffer);
       buf->Reset(source.location());
-      pre_data = PreParse(buf.value(), extension);
+      pre_data = PreParse(source, buf.value(), extension);
     }
 
     // Create a script object describing the script to be compiled.
diff --git a/src/debug.cc b/src/debug.cc
index 18536f5..f2a2814 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -1452,14 +1452,15 @@
   // Find the call address in the running code. This address holds the call to
   // either a DebugBreakXXX or to the debug break return entry code if the
   // break point is still active after processing the break point.
-  Address addr = frame->pc() - Assembler::kTargetAddrToReturnAddrDist;
+  Address addr = frame->pc() - Assembler::kPatchReturnSequenceLength;
 
   // Check if the location is at JS exit.
   bool at_js_exit = false;
   RelocIterator it(debug_info->code());
   while (!it.done()) {
     if (RelocInfo::IsJSReturn(it.rinfo()->rmode())) {
-      at_js_exit = it.rinfo()->pc() == addr - 1;
+      at_js_exit = (it.rinfo()->pc() ==
+                        addr - Assembler::kPatchReturnSequenceAddressOffset);
     }
     it.next();
   }
@@ -1477,8 +1478,9 @@
       addr +=  original_code->instruction_start() - code->instruction_start();
     }
 
-    // Move one byte back to where the call instruction was placed.
-    thread_local_.after_break_target_ = addr - 1;
+    // Move back to where the call instruction sequence started.
+    thread_local_.after_break_target_ =
+        addr - Assembler::kPatchReturnSequenceAddressOffset;
   } else {
     // Check if there still is a debug break call at the target address. If the
     // break point has been removed it will have disappeared. If it have
diff --git a/src/debug.h b/src/debug.h
index 970dbbe..5b0273a 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -238,7 +238,10 @@
   // Returns whether the operation succeeded.
   static bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared);
 
+  // Returns true if the current stub call is patched to call the debugger.
   static bool IsDebugBreak(Address addr);
+  // Returns true if the current return statement has been patched to be
+  // a debugger breakpoint.
   static bool IsDebugBreakAtReturn(RelocInfo* rinfo);
 
   // Check whether a code stub with the specified major key is a possible break
@@ -366,6 +369,7 @@
 
   // The x64 JS return sequence is padded with int3 to make it large
   // enough to hold a call instruction when the debugger patches it.
+  static const int kX64CallInstructionLength = 13;
   static const int kX64JSReturnSequenceLength = 13;
 
   // Code generator routines.
diff --git a/src/execution.cc b/src/execution.cc
index 4ab6b61..9080f5e 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -174,12 +174,7 @@
 
   // Regular expressions can be called as functions in both Firefox
   // and Safari so we allow it too.
-  bool is_regexp =
-      object->IsHeapObject() &&
-      (HeapObject::cast(*object)->map()->constructor() ==
-       *Top::regexp_function());
-
-  if (is_regexp) {
+  if (object->IsJSRegExp()) {
     Handle<String> exec = Factory::exec_symbol();
     return Handle<Object>(object->GetProperty(*exec));
   }
diff --git a/src/execution.h b/src/execution.h
index 126b172..fba696e 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -206,8 +206,13 @@
   static void DisableInterrupts();
 
   static const uintptr_t kLimitSize = kPointerSize * 128 * KB;
+#ifdef V8_TARGET_ARCH_X64
+  static const uintptr_t kInterruptLimit = V8_UINT64_C(0xfffffffffffffffe);
+  static const uintptr_t kIllegalLimit = V8_UINT64_C(0xffffffffffffffff);
+#else
   static const uintptr_t kInterruptLimit = 0xfffffffe;
   static const uintptr_t kIllegalLimit = 0xffffffff;
+#endif
 
   class ThreadLocal {
    public:
diff --git a/src/factory.cc b/src/factory.cc
index 36554df..bb6987b 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -87,8 +87,10 @@
 }
 
 
-Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string) {
-  CALL_HEAP_FUNCTION(Heap::AllocateStringFromTwoByte(string), String);
+Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
+                                             PretenureFlag pretenure) {
+  CALL_HEAP_FUNCTION(Heap::AllocateStringFromTwoByte(string, pretenure),
+                     String);
 }
 
 
diff --git a/src/factory.h b/src/factory.h
index 4db5d4e..ddf71de 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -92,7 +92,8 @@
       Vector<const char> str,
       PretenureFlag pretenure = NOT_TENURED);
 
-  static Handle<String> NewStringFromTwoByte(Vector<const uc16> str);
+  static Handle<String> NewStringFromTwoByte(Vector<const uc16> str,
+      PretenureFlag pretenure = NOT_TENURED);
 
   // Allocates and partially initializes a TwoByte String. The characters of
   // the string are uninitialized. Currently used in regexp code only, where
diff --git a/src/handles-inl.h b/src/handles-inl.h
index 6013c5b..8478bb5 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -39,7 +39,7 @@
 template<class T>
 Handle<T>::Handle(T* obj) {
   ASSERT(!obj->IsFailure());
-  location_ = reinterpret_cast<T**>(HandleScope::CreateHandle(obj));
+  location_ = HandleScope::CreateHandle(obj);
 }
 
 
diff --git a/src/handles.h b/src/handles.h
index ba2694f..8c9cbeb 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -82,7 +82,7 @@
   }
 
   static Handle<T> null() { return Handle<T>(); }
-  bool is_null() {return location_ == NULL; }
+  bool is_null() { return location_ == NULL; }
 
   // Closes the given scope, but lets this handle escape. See
   // implementation in api.h.
@@ -119,15 +119,18 @@
   static int NumberOfHandles();
 
   // Creates a new handle with the given value.
-  static inline Object** CreateHandle(Object* value) {
-    void** result = current_.next;
-    if (result == current_.limit) result = Extend();
+  template <typename T>
+  static inline T** CreateHandle(T* value) {
+    void** cur = current_.next;
+    if (cur == current_.limit) cur = Extend();
     // Update the current next field, set the value in the created
     // handle, and return the result.
-    ASSERT(result < current_.limit);
-    current_.next = result + 1;
-    *reinterpret_cast<Object**>(result) = value;
-    return reinterpret_cast<Object**>(result);
+    ASSERT(cur < current_.limit);
+    current_.next = cur + 1;
+
+    T** result = reinterpret_cast<T**>(cur);
+    *result = value;
+    return result;
   }
 
  private:
diff --git a/src/heap.cc b/src/heap.cc
index f8d22a2..7d6e442 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -73,6 +73,10 @@
 int Heap::semispace_size_  = 512*KB;
 int Heap::old_generation_size_ = 128*MB;
 int Heap::initial_semispace_size_ = 128*KB;
+#elseif defined(V8_TARGET_ARCH_X64)
+int Heap::semispace_size_  = 8*MB;
+int Heap::old_generation_size_ = 1*GB;
+int Heap::initial_semispace_size_ = 1*MB;
 #else
 int Heap::semispace_size_  = 4*MB;
 int Heap::old_generation_size_ = 512*MB;
@@ -277,7 +281,9 @@
 int Heap::SizeOfObjects() {
   int total = 0;
   AllSpaces spaces;
-  while (Space* space = spaces.next()) total += space->Size();
+  while (Space* space = spaces.next()) {
+    total += space->Size();
+  }
   return total;
 }
 
@@ -1048,6 +1054,7 @@
   map->set_constructor(null_value());
   map->set_instance_size(instance_size);
   map->set_inobject_properties(0);
+  map->set_pre_allocated_property_fields(0);
   map->set_instance_descriptors(empty_descriptor_array());
   map->set_code_cache(empty_fixed_array());
   map->set_unused_property_fields(0);
@@ -1605,6 +1612,9 @@
   share->set_start_position_and_type(0);
   share->set_debug_info(undefined_value());
   share->set_inferred_name(empty_string());
+  share->set_compiler_hints(0);
+  share->set_this_property_assignments_count(0);
+  share->set_this_property_assignments(undefined_value());
   return result;
 }
 
@@ -2044,16 +2054,10 @@
 Object* Heap::AllocateInitialMap(JSFunction* fun) {
   ASSERT(!fun->has_initial_map());
 
-  // First create a new map with the expected number of properties being
-  // allocated in-object.
-  int expected_nof_properties = fun->shared()->expected_nof_properties();
-  int instance_size = JSObject::kHeaderSize +
-                      expected_nof_properties * kPointerSize;
-  if (instance_size > JSObject::kMaxInstanceSize) {
-    instance_size = JSObject::kMaxInstanceSize;
-    expected_nof_properties = (instance_size - JSObject::kHeaderSize) /
-                              kPointerSize;
-  }
+  // First create a new map with the size and number of in-object properties
+  // suggested by the function.
+  int instance_size = fun->shared()->CalculateInstanceSize();
+  int in_object_properties = fun->shared()->CalculateInObjectProperties();
   Object* map_obj = Heap::AllocateMap(JS_OBJECT_TYPE, instance_size);
   if (map_obj->IsFailure()) return map_obj;
 
@@ -2066,9 +2070,33 @@
     if (prototype->IsFailure()) return prototype;
   }
   Map* map = Map::cast(map_obj);
-  map->set_inobject_properties(expected_nof_properties);
-  map->set_unused_property_fields(expected_nof_properties);
+  map->set_inobject_properties(in_object_properties);
+  map->set_unused_property_fields(in_object_properties);
   map->set_prototype(prototype);
+
+  // If the function has only simple this property assignments add field
+  // descriptors for these to the initial map as the object cannot be
+  // constructed without having these properties.
+  ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields);
+  if (fun->shared()->has_only_this_property_assignments() &&
+      fun->shared()->this_property_assignments_count() > 0) {
+    int count = fun->shared()->this_property_assignments_count();
+    if (count > in_object_properties) {
+      count = in_object_properties;
+    }
+    DescriptorArray* descriptors = *Factory::NewDescriptorArray(count);
+    if (descriptors->IsFailure()) return descriptors;
+    for (int i = 0; i < count; i++) {
+      String* name = fun->shared()->GetThisPropertyAssignmentName(i);
+      ASSERT(name->IsSymbol());
+      FieldDescriptor field(name, i, NONE);
+      descriptors->Set(i, &field);
+    }
+    descriptors->Sort();
+    map->set_instance_descriptors(descriptors);
+    map->set_pre_allocated_property_fields(count);
+    map->set_unused_property_fields(in_object_properties - count);
+  }
   return map;
 }
 
@@ -2100,7 +2128,11 @@
   ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
 
   // Allocate the backing storage for the properties.
-  int prop_size = map->unused_property_fields() - map->inobject_properties();
+  int prop_size =
+      map->pre_allocated_property_fields() +
+      map->unused_property_fields() -
+      map->inobject_properties();
+  ASSERT(prop_size >= 0);
   Object* properties = AllocateFixedArray(prop_size, pretenure);
   if (properties->IsFailure()) return properties;
 
@@ -2593,6 +2625,7 @@
 
 
 Object* Heap::AllocateFixedArray(int length) {
+  ASSERT(length >= 0);
   if (length == 0) return empty_fixed_array();
   Object* result = AllocateRawFixedArray(length);
   if (!result->IsFailure()) {
diff --git a/src/heap.h b/src/heap.h
index 179f9af..ec1e21a 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -852,7 +852,11 @@
 
   static const int kMaxMapSpaceSize = 8*MB;
 
+#if defined(V8_TARGET_ARCH_X64)
+  static const int kMaxObjectSizeInNewSpace = 512*KB;
+#else
   static const int kMaxObjectSizeInNewSpace = 256*KB;
+#endif
 
   static NewSpace new_space_;
   static OldSpace* old_pointer_space_;
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index b648055..6a90e07 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -437,7 +437,10 @@
 
   // Distance between the address of the code target in the call instruction
   // and the return address
-  static const int kTargetAddrToReturnAddrDist = kPointerSize;
+  static const int kPatchReturnSequenceLength = kPointerSize;
+  // Distance between start of patched return sequence and the emitted address
+  // to jump to.
+  static const int kPatchReturnSequenceAddressOffset = 1;  // JMP imm32.
 
 
   // ---------------------------------------------------------------------------
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index a70a9d2..6de9de6 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -37,7 +37,7 @@
 
 
 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
-  // TODO(1238487): Don't pass the function in a static variable.
+  // TODO(428): Don't pass the function in a static variable.
   ExternalReference passed = ExternalReference::builtin_passed_function();
   __ mov(Operand::StaticVariable(passed), edi);
 
@@ -180,12 +180,16 @@
     // eax: initial map
     // ebx: JSObject
     // edi: start of next object
+    // Calculate the total number of properties described by the map.
     __ movzx_b(edx, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
-    __ movzx_b(ecx, FieldOperand(eax, Map::kInObjectPropertiesOffset));
+    __ movzx_b(ecx, FieldOperand(eax, Map::kPreAllocatedPropertyFieldsOffset));
+    __ add(edx, Operand(ecx));
     // Calculate unused properties past the end of the in-object properties.
+    __ movzx_b(ecx, FieldOperand(eax, Map::kInObjectPropertiesOffset));
     __ sub(edx, Operand(ecx));
     // Done if no extra properties are to be allocated.
     __ j(zero, &allocated);
+    __ Assert(positive, "Property allocation count failed.");
 
     // Scale the number of elements by pointer size and add the header for
     // FixedArrays to the start of the next object calculation from above.
@@ -321,6 +325,7 @@
   __ pop(ecx);
   __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  // 1 ~ receiver
   __ push(ecx);
+  __ IncrementCounter(&Counters::constructed_objects, 1);
   __ ret(0);
 }
 
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 9542b16..b8b3db6 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -6752,11 +6752,10 @@
       // Reserve space for converted numbers.
       __ sub(Operand(esp), Immediate(2 * kPointerSize));
 
-      bool use_sse3 = CpuFeatures::IsSupported(CpuFeatures::SSE3);
-      if (use_sse3) {
+      if (use_sse3_) {
         // Truncate the operands to 32-bit integers and check for
         // exceptions in doing so.
-         CpuFeatures::Scope scope(CpuFeatures::SSE3);
+        CpuFeatures::Scope scope(CpuFeatures::SSE3);
         __ fisttp_s(Operand(esp, 0 * kPointerSize));
         __ fisttp_s(Operand(esp, 1 * kPointerSize));
         __ fnstsw_ax();
@@ -6841,7 +6840,7 @@
       // the runtime system.
       __ bind(&operand_conversion_failure);
       __ add(Operand(esp), Immediate(2 * kPointerSize));
-      if (use_sse3) {
+      if (use_sse3_) {
         // If we've used the SSE3 instructions for truncating the
         // floating point values to integers and it failed, we have a
         // pending #IA exception. Clear it.
@@ -7671,16 +7670,11 @@
   Label throw_out_of_memory_exception;
   Label throw_normal_exception;
 
-  // Call into the runtime system. Collect garbage before the call if
-  // running with --gc-greedy set.
-  if (FLAG_gc_greedy) {
-    Failure* failure = Failure::RetryAfterGC(0);
-    __ mov(eax, Immediate(reinterpret_cast<int32_t>(failure)));
-  }
+  // Call into the runtime system.
   GenerateCore(masm, &throw_normal_exception,
                &throw_out_of_memory_exception,
                frame_type,
-               FLAG_gc_greedy,
+               false,
                false);
 
   // Do space-specific GC and retry runtime call.
diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h
index 1d0cc8b..afdbffe 100644
--- a/src/ia32/codegen-ia32.h
+++ b/src/ia32/codegen-ia32.h
@@ -299,14 +299,9 @@
 #endif
 
   static void SetFunctionInfo(Handle<JSFunction> fun,
-                              int length,
-                              int function_token_position,
-                              int start_position,
-                              int end_position,
-                              bool is_expression,
+                              FunctionLiteral* lit,
                               bool is_toplevel,
-                              Handle<Script> script,
-                              Handle<String> inferred_name);
+                              Handle<Script> script);
 
   // Accessors
   MacroAssembler* masm() { return masm_; }
@@ -623,6 +618,7 @@
                       OverwriteMode mode,
                       GenericBinaryFlags flags)
       : op_(op), mode_(mode), flags_(flags) {
+    use_sse3_ = CpuFeatures::IsSupported(CpuFeatures::SSE3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
 
@@ -632,6 +628,7 @@
   Token::Value op_;
   OverwriteMode mode_;
   GenericBinaryFlags flags_;
+  bool use_sse3_;
 
   const char* GetName();
 
@@ -644,9 +641,10 @@
   }
 #endif
 
-  // Minor key encoding in 16 bits FOOOOOOOOOOOOOMM.
+  // Minor key encoding in 16 bits FSOOOOOOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
-  class OpBits: public BitField<Token::Value, 2, 13> {};
+  class OpBits: public BitField<Token::Value, 2, 12> {};
+  class SSE3Bits: public BitField<bool, 14, 1> {};
   class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {};
 
   Major MajorKey() { return GenericBinaryOp; }
@@ -654,7 +652,8 @@
     // Encode the parameters in a unique 16 bit value.
     return OpBits::encode(op_)
            | ModeBits::encode(mode_)
-           | FlagBits::encode(flags_);
+           | FlagBits::encode(flags_)
+           | SSE3Bits::encode(use_sse3_);
   }
   void Generate(MacroAssembler* masm);
 };
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
index 9913a39..4ef0862 100644
--- a/src/ia32/debug-ia32.cc
+++ b/src/ia32/debug-ia32.cc
@@ -195,8 +195,8 @@
 
 
 void Debug::GenerateReturnDebugBreakEntry(MacroAssembler* masm) {
-  // OK to clobber ebx as we are returning from a JS function in the code
-  // generated by Ia32CodeGenerator::ExitJSFrame.
+  // OK to clobber ebx as we are returning from a JS function through the code
+  // generated by CodeGenerator::GenerateReturnSequence()
   ExternalReference debug_break_return =
       ExternalReference(Debug_Address::DebugBreakReturn());
   __ mov(ebx, Operand::StaticVariable(debug_break_return));
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 08ffe2f..fa9b8a2 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -840,7 +840,7 @@
 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
   // The address of the instruction following the call.
   Address test_instruction_address =
-      address + Assembler::kTargetAddrToReturnAddrDist;
+      address + Assembler::kPatchReturnSequenceLength;
   // If the instruction following the call is not a test eax, nothing
   // was inlined.
   if (*test_instruction_address != kTestEaxByte) return false;
@@ -867,7 +867,7 @@
 
 static bool PatchInlinedMapCheck(Address address, Object* map) {
   Address test_instruction_address =
-      address + Assembler::kTargetAddrToReturnAddrDist;
+      address + Assembler::kPatchReturnSequenceLength;
   // The keyed load has a fast inlined case if the IC call instruction
   // is immediately followed by a test instruction.
   if (*test_instruction_address != kTestEaxByte) return false;
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 7782aa9..e362cd3 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -82,8 +82,8 @@
   //   page_start + kObjectStartOffset + objectSize
   // where objectSize is FixedArray::kHeaderSize + kPointerSize * array_length.
   // Add the delta between the end of the normal RSet and the start of the
-  // extra RSet to 'object', so that addressing the bit using 'pointer_offset'
-  // hits the extra RSet words.
+  // extra RSet to 'page_start', so that addressing the bit using
+  // 'pointer_offset' hits the extra RSet words.
   masm->lea(page_start,
             Operand(page_start, array_length, times_pointer_size,
                     Page::kObjectStartOffset + FixedArray::kHeaderSize
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index a49c1f5..bc81076 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -38,6 +38,7 @@
 namespace v8 {
 namespace internal {
 
+#ifdef V8_NATIVE_REGEXP
 /*
  * This assembler uses the following register assignment convention
  * - edx : current character. Must be loaded using LoadCurrentCharacter
@@ -54,7 +55,7 @@
  *
  * Each call to a public method should retain this convention.
  * The stack will have the following structure:
- *       - stack_area_top     (High end of the memory area to use as
+ *       - stack_area_base     (High end of the memory area to use as
  *                             backtracking stack)
  *       - at_start           (if 1, start at start of string, if 0, don't)
  *       - int* capture_array (int[num_saved_registers_], for output).
@@ -78,13 +79,13 @@
  * character of the string). The remaining registers starts out as garbage.
  *
  * The data up to the return address must be placed there by the calling
- * code, e.g., by calling the code entry as cast to:
+ * code, by calling the code entry as cast to a function with the signature:
  * int (*match)(String* input_string,
  *              Address start,
  *              Address end,
  *              int* capture_output_array,
  *              bool at_start,
- *              byte* stack_area_top)
+ *              byte* stack_area_base)
  */
 
 #define __ ACCESS_MASM(masm_)
@@ -93,7 +94,6 @@
     Mode mode,
     int registers_to_save)
     : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
-      constants_(kRegExpConstantsSize),
       mode_(mode),
       num_registers_(registers_to_save),
       num_saved_registers_(registers_to_save),
@@ -156,13 +156,6 @@
 }
 
 
-void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
-                                           Label* bitmap,
-                                           Label* on_zero) {
-  UNIMPLEMENTED();
-}
-
-
 void RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) {
   __ cmp(current_character(), c);
   BranchOrBacktrack(equal, on_equal);
@@ -217,15 +210,9 @@
     BranchOrBacktrack(greater, on_failure);
   }
 
-  Label backtrack;
   if (on_failure == NULL) {
-    // Avoid inlining the Backtrack macro for each test.
-    Label skip_backtrack;
-    __ jmp(&skip_backtrack);
-    __ bind(&backtrack);
-    Backtrack();
-    __ bind(&skip_backtrack);
-    on_failure = &backtrack;
+    // Instead of inlining a backtrack, (re)use the global backtrack target.
+    on_failure = &backtrack_label_;
   }
 
   for (int i = 0; i < str.length(); i++) {
@@ -581,34 +568,6 @@
   }
 }
 
-void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap(
-    uc16 start,
-    Label* half_nibble_map,
-    const Vector<Label*>& destinations) {
-  UNIMPLEMENTED();
-}
-
-
-void RegExpMacroAssemblerIA32::DispatchByteMap(
-    uc16 start,
-    Label* byte_map,
-    const Vector<Label*>& destinations) {
-  UNIMPLEMENTED();
-}
-
-
-void RegExpMacroAssemblerIA32::DispatchHighByteMap(
-    byte start,
-    Label* byte_map,
-    const Vector<Label*>& destinations) {
-  UNIMPLEMENTED();
-}
-
-
-void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
-  UNIMPLEMENTED();  // Has no use.
-}
-
 
 void RegExpMacroAssemblerIA32::Fail() {
   ASSERT(FAILURE == 0);  // Return value for failure is zero.
@@ -668,17 +627,17 @@
   __ mov(edi, Operand(ebp, kInputStart));
   // Set up edi to be negative offset from string end.
   __ sub(edi, Operand(esi));
-  if (num_saved_registers_ > 0) {
+  // Set eax to address of char before start of input
+  // (effectively string position -1).
+  __ lea(eax, Operand(edi, -char_size()));
+  // Store this value in a local variable, for use when clearing
+  // position registers.
+  __ mov(Operand(ebp, kInputStartMinusOne), eax);
+  if (num_saved_registers_ > 0) {  // Always is, if generated from a regexp.
     // Fill saved registers with initial value = start offset - 1
     // Fill in stack push order, to avoid accessing across an unwritten
     // page (a problem on Windows).
     __ mov(ecx, kRegisterZero);
-    // Set eax to address of char before start of input
-    // (effectively string position -1).
-    __ lea(eax, Operand(edi, -char_size()));
-    // Store this value in a local variable, for use when clearing
-    // position registers.
-    __ mov(Operand(ebp, kInputStartMinusOne), eax);
     Label init_loop;
     __ bind(&init_loop);
     __ mov(Operand(ebp, ecx, times_1, +0), eax);
@@ -942,139 +901,8 @@
 }
 
 
-RegExpMacroAssemblerIA32::Result RegExpMacroAssemblerIA32::Match(
-    Handle<Code> regexp_code,
-    Handle<String> subject,
-    int* offsets_vector,
-    int offsets_vector_length,
-    int previous_index) {
-
-  ASSERT(subject->IsFlat());
-  ASSERT(previous_index >= 0);
-  ASSERT(previous_index <= subject->length());
-
-  // No allocations before calling the regexp, but we can't use
-  // AssertNoAllocation, since regexps might be preempted, and another thread
-  // might do allocation anyway.
-
-  String* subject_ptr = *subject;
-  // Character offsets into string.
-  int start_offset = previous_index;
-  int end_offset = subject_ptr->length();
-
-  bool is_ascii = subject->IsAsciiRepresentation();
-
-  if (StringShape(subject_ptr).IsCons()) {
-    subject_ptr = ConsString::cast(subject_ptr)->first();
-  } else if (StringShape(subject_ptr).IsSliced()) {
-    SlicedString* slice = SlicedString::cast(subject_ptr);
-    start_offset += slice->start();
-    end_offset += slice->start();
-    subject_ptr = slice->buffer();
-  }
-  // Ensure that an underlying string has the same ascii-ness.
-  ASSERT(subject_ptr->IsAsciiRepresentation() == is_ascii);
-  ASSERT(subject_ptr->IsExternalString() || subject_ptr->IsSeqString());
-  // String is now either Sequential or External
-  int char_size_shift = is_ascii ? 0 : 1;
-  int char_length = end_offset - start_offset;
-
-  const byte* input_start =
-      StringCharacterPosition(subject_ptr, start_offset);
-  int byte_length = char_length << char_size_shift;
-  const byte* input_end = input_start + byte_length;
-  RegExpMacroAssemblerIA32::Result res = Execute(*regexp_code,
-                                                 subject_ptr,
-                                                 start_offset,
-                                                 input_start,
-                                                 input_end,
-                                                 offsets_vector,
-                                                 previous_index == 0);
-
-  if (res == SUCCESS) {
-    // Capture values are relative to start_offset only.
-    // Convert them to be relative to start of string.
-    for (int i = 0; i < offsets_vector_length; i++) {
-      if (offsets_vector[i] >= 0) {
-        offsets_vector[i] += previous_index;
-      }
-    }
-  }
-
-  return res;
-}
-
 // Private methods:
 
-static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize;
-
-RegExpMacroAssemblerIA32::Result RegExpMacroAssemblerIA32::Execute(
-    Code* code,
-    String* input,
-    int start_offset,
-    const byte* input_start,
-    const byte* input_end,
-    int* output,
-    bool at_start) {
-  typedef int (*matcher)(String*, int, const byte*,
-                         const byte*, int*, int, Address);
-  matcher matcher_func = FUNCTION_CAST<matcher>(code->entry());
-
-  int at_start_val = at_start ? 1 : 0;
-
-  // Ensure that the minimum stack has been allocated.
-  RegExpStack stack;
-  Address stack_top = RegExpStack::stack_top();
-
-  int result = matcher_func(input,
-                            start_offset,
-                            input_start,
-                            input_end,
-                            output,
-                            at_start_val,
-                            stack_top);
-  ASSERT(result <= SUCCESS);
-  ASSERT(result >= RETRY);
-
-  if (result == EXCEPTION && !Top::has_pending_exception()) {
-    // We detected a stack overflow (on the backtrack stack) in RegExp code,
-    // but haven't created the exception yet.
-    Top::StackOverflow();
-  }
-  return static_cast<Result>(result);
-}
-
-
-int RegExpMacroAssemblerIA32::CaseInsensitiveCompareUC16(Address byte_offset1,
-                                                         Address byte_offset2,
-                                                         size_t byte_length) {
-  // This function is not allowed to cause a garbage collection.
-  // A GC might move the calling generated code and invalidate the
-  // return address on the stack.
-  ASSERT(byte_length % 2 == 0);
-  uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1);
-  uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2);
-  size_t length = byte_length >> 1;
-
-  for (size_t i = 0; i < length; i++) {
-    unibrow::uchar c1 = substring1[i];
-    unibrow::uchar c2 = substring2[i];
-    if (c1 != c2) {
-      unibrow::uchar s1[1] = { c1 };
-      canonicalize.get(c1, '\0', s1);
-      if (s1[0] != c2) {
-        unibrow::uchar s2[1] = { c2 };
-        canonicalize.get(c2, '\0', s2);
-        if (s1[0] != s2[0]) {
-          return 0;
-        }
-      }
-    }
-  }
-  return 1;
-}
-
-
 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) {
   int num_arguments = 3;
   FrameAlign(num_arguments, scratch);
@@ -1096,35 +924,6 @@
 }
 
 
-const byte* RegExpMacroAssemblerIA32::StringCharacterPosition(String* subject,
-                                                              int start_index) {
-  // Not just flat, but ultra flat.
-  ASSERT(subject->IsExternalString() || subject->IsSeqString());
-  ASSERT(start_index >= 0);
-  ASSERT(start_index <= subject->length());
-  if (subject->IsAsciiRepresentation()) {
-    const byte* address;
-    if (StringShape(subject).IsExternal()) {
-      const char* data = ExternalAsciiString::cast(subject)->resource()->data();
-      address = reinterpret_cast<const byte*>(data);
-    } else {
-      ASSERT(subject->IsSeqAsciiString());
-      char* data = SeqAsciiString::cast(subject)->GetChars();
-      address = reinterpret_cast<const byte*>(data);
-    }
-    return address + start_index;
-  }
-  const uc16* data;
-  if (StringShape(subject).IsExternal()) {
-    data = ExternalTwoByteString::cast(subject)->resource()->data();
-  } else {
-    ASSERT(subject->IsSeqTwoByteString());
-    data = SeqTwoByteString::cast(subject)->GetChars();
-  }
-  return reinterpret_cast<const byte*>(data + start_index);
-}
-
-
 int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
                                                    Code* re_code,
                                                    Address re_frame) {
@@ -1198,18 +997,18 @@
 
 
 Address RegExpMacroAssemblerIA32::GrowStack(Address stack_pointer,
-                                            Address* stack_top) {
+                                            Address* stack_base) {
   size_t size = RegExpStack::stack_capacity();
-  Address old_stack_top = RegExpStack::stack_top();
-  ASSERT(old_stack_top == *stack_top);
-  ASSERT(stack_pointer <= old_stack_top);
-  ASSERT(static_cast<size_t>(old_stack_top - stack_pointer) <= size);
-  Address new_stack_top = RegExpStack::EnsureCapacity(size * 2);
-  if (new_stack_top == NULL) {
+  Address old_stack_base = RegExpStack::stack_base();
+  ASSERT(old_stack_base == *stack_base);
+  ASSERT(stack_pointer <= old_stack_base);
+  ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size);
+  Address new_stack_base = RegExpStack::EnsureCapacity(size * 2);
+  if (new_stack_base == NULL) {
     return NULL;
   }
-  *stack_top = new_stack_top;
-  return new_stack_top - (old_stack_top - stack_pointer);
+  *stack_base = new_stack_base;
+  return new_stack_base - (old_stack_base - stack_pointer);
 }
 
 
@@ -1373,11 +1172,8 @@
 }
 
 
-void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg,
-                                                         ArraySlice* buffer) {
-  __ mov(reg, buffer->array());
-  __ add(Operand(reg), Immediate(buffer->base_offset()));
-}
-
 #undef __
+
+#endif  // V8_NATIVE_REGEXP
+
 }}  // namespace v8::internal
diff --git a/src/ia32/regexp-macro-assembler-ia32.h b/src/ia32/regexp-macro-assembler-ia32.h
index c3d9155..d114392 100644
--- a/src/ia32/regexp-macro-assembler-ia32.h
+++ b/src/ia32/regexp-macro-assembler-ia32.h
@@ -31,21 +31,16 @@
 namespace v8 {
 namespace internal {
 
+#ifndef V8_NATIVE_REGEXP
 class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
  public:
-  // Type of input string to generate code for.
-  enum Mode { ASCII = 1, UC16 = 2 };
-  // Result of calling the generated RegExp code:
-  // RETRY: Something significant changed during execution, and the matching
-  //        should be retried from scratch.
-  // EXCEPTION: Something failed during execution. If no exception has been
-  //        thrown, it's an internal out-of-memory, and the caller should
-  //        throw the exception.
-  // FAILURE: Matching failed.
-  // SUCCESS: Matching succeeded, and the output array has been filled with
-  //        capture positions.
-  enum Result { RETRY = -2, EXCEPTION = -1, FAILURE = 0, SUCCESS = 1 };
+  RegExpMacroAssemblerIA32() { }
+  virtual ~RegExpMacroAssemblerIA32() { }
+};
 
+#else
+class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler {
+ public:
   RegExpMacroAssemblerIA32(Mode mode, int registers_to_save);
   virtual ~RegExpMacroAssemblerIA32();
   virtual int stack_limit_slack();
@@ -54,7 +49,6 @@
   virtual void Backtrack();
   virtual void Bind(Label* label);
   virtual void CheckAtStart(Label* on_at_start);
-  virtual void CheckBitmap(uc16 start, Label* bitmap, Label* on_zero);
   virtual void CheckCharacter(uint32_t c, Label* on_equal);
   virtual void CheckCharacterAfterAnd(uint32_t c,
                                       uint32_t mask,
@@ -88,16 +82,6 @@
                                           int cp_offset,
                                           bool check_offset,
                                           Label* on_no_match);
-  virtual void DispatchByteMap(uc16 start,
-                               Label* byte_map,
-                               const Vector<Label*>& destinations);
-  virtual void DispatchHalfNibbleMap(uc16 start,
-                                     Label* half_nibble_map,
-                                     const Vector<Label*>& destinations);
-  virtual void DispatchHighByteMap(byte start,
-                                   Label* byte_map,
-                                   const Vector<Label*>& destinations);
-  virtual void EmitOrLink(Label* label);
   virtual void Fail();
   virtual Handle<Object> GetCode(Handle<String> source);
   virtual void GoTo(Label* label);
@@ -123,20 +107,6 @@
   virtual void ClearRegisters(int reg_from, int reg_to);
   virtual void WriteStackPointerToRegister(int reg);
 
-  static Result Match(Handle<Code> regexp,
-                      Handle<String> subject,
-                      int* offsets_vector,
-                      int offsets_vector_length,
-                      int previous_index);
-
-  static Result Execute(Code* code,
-                        String* input,
-                        int start_offset,
-                        const byte* input_start,
-                        const byte* input_end,
-                        int* output,
-                        bool at_start);
-
  private:
   // Offsets from ebp of function parameters and stored registers.
   static const int kFramePointer = 0;
@@ -163,16 +133,6 @@
 
   // Initial size of code buffer.
   static const size_t kRegExpCodeSize = 1024;
-  // Initial size of constant buffers allocated during compilation.
-  static const int kRegExpConstantsSize = 256;
-
-  static const byte* StringCharacterPosition(String* subject, int start_index);
-
-  // Compares two-byte strings case insensitively.
-  // Called from generated RegExp code.
-  static int CaseInsensitiveCompareUC16(Address byte_offset1,
-                                        Address byte_offset2,
-                                        size_t byte_length);
 
   // Load a number of characters at the given offset from the
   // current position, into the current-character register.
@@ -218,11 +178,6 @@
   // is NULL, in which case it is a conditional Backtrack.
   void BranchOrBacktrack(Condition condition, Label* to, Hint hint = no_hint);
 
-  // Load the address of a "constant buffer" (a slice of a byte array)
-  // into a register. The address is computed from the ByteArray* address
-  // and an offset. Uses no extra registers.
-  void LoadConstantBufferAddress(Register reg, ArraySlice* buffer);
-
   // Call and return internally in the generated code in a way that
   // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
   inline void SafeCall(Label* to);
@@ -258,10 +213,6 @@
 
   MacroAssembler* masm_;
 
-  // Constant buffer provider. Allocates external storage for storing
-  // constants.
-  ByteArrayProvider constants_;
-
   // Which mode to generate code for (ASCII or UC16).
   Mode mode_;
 
@@ -281,6 +232,7 @@
   Label check_preempt_label_;
   Label stack_overflow_label_;
 };
+#endif  // V8_NATIVE_REGEXP
 
 }}  // namespace v8::internal
 
diff --git a/src/ic-inl.h b/src/ic-inl.h
index 08304d8..38d61dc 100644
--- a/src/ic-inl.h
+++ b/src/ic-inl.h
@@ -38,7 +38,7 @@
 
 Address IC::address() {
   // Get the address of the call.
-  Address result = pc() - Assembler::kTargetAddrToReturnAddrDist;
+  Address result = pc() - Assembler::kPatchReturnSequenceLength;
 
 #ifdef ENABLE_DEBUGGER_SUPPORT
   // First check if any break points are active if not just return the address
diff --git a/src/ic.cc b/src/ic.cc
index f4d74c9..393ccbf 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -122,7 +122,7 @@
   // Get the address of the call site in the active code. This is the
   // place where the call to DebugBreakXXX is and where the IC
   // normally would be.
-  Address addr = pc() - Assembler::kTargetAddrToReturnAddrDist;
+  Address addr = pc() - Assembler::kPatchReturnSequenceLength;
   // Return the address in the original code. This is the place where
   // the call which has been overwritten by the DebugBreakXXX resides
   // and the place where the inline cache system should look.
diff --git a/src/ic.h b/src/ic.h
index 860b7e6..007b035 100644
--- a/src/ic.h
+++ b/src/ic.h
@@ -390,7 +390,7 @@
   // Support for patching the map that is checked in an inlined
   // version of keyed store.
   // The address is the patch point for the IC call
-  // (Assembler::kTargetAddrToReturnAddrDist before the end of
+  // (Assembler::kPatchReturnSequenceLength before the end of
   // the call/return address).
   // The map is the new map that the inlined code should check against.
   static bool PatchInlinedStore(Address address, Object* map);
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index bd51102..06208aa 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -43,6 +43,7 @@
 #include "regexp-macro-assembler-irregexp.h"
 #include "regexp-stack.h"
 
+#ifdef V8_NATIVE_REGEXP
 #if V8_TARGET_ARCH_IA32
 #include "ia32/macro-assembler-ia32.h"
 #include "ia32/regexp-macro-assembler-ia32.h"
@@ -54,6 +55,7 @@
 #else
 #error Unsupported target architecture.
 #endif
+#endif
 
 #include "interpreter-irregexp.h"
 
@@ -270,10 +272,11 @@
 // If compilation fails, an exception is thrown and this function
 // returns false.
 bool RegExpImpl::EnsureCompiledIrregexp(Handle<JSRegExp> re, bool is_ascii) {
+  Object* compiled_code = re->DataAt(JSRegExp::code_index(is_ascii));
 #ifdef V8_NATIVE_REGEXP
-  if (re->DataAt(JSRegExp::code_index(is_ascii))->IsCode()) return true;
+  if (compiled_code->IsCode()) return true;
 #else  // ! V8_NATIVE_REGEXP (RegExp interpreter code)
-  if (re->DataAt(JSRegExp::code_index(is_ascii))->IsByteArray()) return true;
+  if (compiled_code->IsByteArray()) return true;
 #endif
   return CompileIrregexp(re, is_ascii);
 }
@@ -414,33 +417,36 @@
 
   // Dispatch to the correct RegExp implementation.
   Handle<FixedArray> regexp(FixedArray::cast(jsregexp->data()));
+
 #ifdef V8_NATIVE_REGEXP
-#if V8_TARGET_ARCH_IA32
+#ifdef V8_TARGET_ARCH_ARM
+  UNIMPLEMENTED();
+#else  // Native regexp supported.
   OffsetsVector captures(number_of_capture_registers);
   int* captures_vector = captures.vector();
-  RegExpMacroAssemblerIA32::Result res;
+  NativeRegExpMacroAssembler::Result res;
   do {
     bool is_ascii = subject->IsAsciiRepresentation();
     if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) {
       return Handle<Object>::null();
     }
     Handle<Code> code(RegExpImpl::IrregexpNativeCode(*regexp, is_ascii));
-    res = RegExpMacroAssemblerIA32::Match(code,
-                                          subject,
-                                          captures_vector,
-                                          captures.length(),
-                                          previous_index);
+    res = NativeRegExpMacroAssembler::Match(code,
+                                            subject,
+                                            captures_vector,
+                                            captures.length(),
+                                            previous_index);
     // If result is RETRY, the string have changed representation, and we
     // must restart from scratch.
-  } while (res == RegExpMacroAssemblerIA32::RETRY);
-  if (res == RegExpMacroAssemblerIA32::EXCEPTION) {
+  } while (res == NativeRegExpMacroAssembler::RETRY);
+  if (res == NativeRegExpMacroAssembler::EXCEPTION) {
     ASSERT(Top::has_pending_exception());
     return Handle<Object>::null();
   }
-  ASSERT(res == RegExpMacroAssemblerIA32::SUCCESS
-      || res == RegExpMacroAssemblerIA32::FAILURE);
+  ASSERT(res == NativeRegExpMacroAssembler::SUCCESS
+      || res == NativeRegExpMacroAssembler::FAILURE);
 
-  if (res != RegExpMacroAssemblerIA32::SUCCESS) return Factory::null_value();
+  if (res != NativeRegExpMacroAssembler::SUCCESS) return Factory::null_value();
 
   array = Handle<FixedArray>(FixedArray::cast(last_match_info->elements()));
   ASSERT(array->length() >= number_of_capture_registers + kLastMatchOverhead);
@@ -449,10 +455,9 @@
     SetCapture(*array, i, captures_vector[i]);
     SetCapture(*array, i + 1, captures_vector[i + 1]);
   }
-#else  // !V8_TARGET_ARCH_IA32
-    UNREACHABLE();
-#endif  // V8_TARGET_ARCH_IA32
-#else  // !V8_NATIVE_REGEXP
+#endif  // Native regexp supported.
+
+#else  // ! V8_NATIVE_REGEXP
   bool is_ascii = subject->IsAsciiRepresentation();
   if (!EnsureCompiledIrregexp(jsregexp, is_ascii)) {
     return Handle<Object>::null();
@@ -4457,38 +4462,36 @@
 
   NodeInfo info = *node->info();
 
+  // Create the correct assembler for the architecture.
 #ifdef V8_NATIVE_REGEXP
-#ifdef V8_TARGET_ARCH_ARM
-  // ARM native regexp not implemented yet.
-  UNREACHABLE();
-#endif
-#ifdef V8_TARGET_ARCH_X64
-  // X64 native regexp not implemented yet.
-  UNREACHABLE();
-#endif
+  // Native regexp implementation.
+
+  NativeRegExpMacroAssembler::Mode mode =
+      is_ascii ? NativeRegExpMacroAssembler::ASCII
+               : NativeRegExpMacroAssembler::UC16;
+
 #ifdef V8_TARGET_ARCH_IA32
-  RegExpMacroAssemblerIA32::Mode mode;
-  if (is_ascii) {
-    mode = RegExpMacroAssemblerIA32::ASCII;
-  } else {
-    mode = RegExpMacroAssemblerIA32::UC16;
-  }
   RegExpMacroAssemblerIA32 macro_assembler(mode,
                                            (data->capture_count + 1) * 2);
-  return compiler.Assemble(&macro_assembler,
-                           node,
-                           data->capture_count,
-                           pattern);
 #endif
+#ifdef V8_TARGET_ARCH_X64
+  RegExpMacroAssemblerX64 macro_assembler(mode,
+                                          (data->capture_count + 1) * 2);
+#endif
+#ifdef V8_TARGET_ARCH_ARM
+  UNIMPLEMENTED();
+#endif
+
 #else  // ! V8_NATIVE_REGEXP
-  // Interpreted regexp.
+  // Interpreted regexp implementation.
   EmbeddedVector<byte, 1024> codes;
   RegExpMacroAssemblerIrregexp macro_assembler(codes);
+#endif
+
   return compiler.Assemble(&macro_assembler,
                            node,
                            data->capture_count,
                            pattern);
-#endif  // V8_NATIVE_REGEXP
 }
 
 }}  // namespace v8::internal
diff --git a/src/math.js b/src/math.js
index db75cb2..e3d266e 100644
--- a/src/math.js
+++ b/src/math.js
@@ -184,6 +184,7 @@
 function SetupMath() {
   // Setup math constants.
   // ECMA-262, section 15.8.1.1.
+  %OptimizeObjectForAddingMultipleProperties($Math, 8);
   %SetProperty($Math,
                "E",
                2.7182818284590452354,
@@ -219,6 +220,7 @@
                "SQRT2",
                1.4142135623730951,
                DONT_ENUM |  DONT_DELETE | READ_ONLY);
+  %TransformToFastProperties($Math);
 
   // Setup non-enumerable functions of the Math object and
   // set their names.
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index 40001f9..e97b207 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -371,9 +371,9 @@
   VerifyHeapPointer(properties());
   VerifyHeapPointer(elements());
   if (HasFastProperties()) {
-    CHECK(map()->unused_property_fields() ==
-          (map()->inobject_properties() + properties()->length() -
-           map()->NextFreePropertyIndex()));
+    CHECK_EQ(map()->unused_property_fields(),
+             (map()->inobject_properties() + properties()->length() -
+              map()->NextFreePropertyIndex()));
   }
 }
 
@@ -462,6 +462,7 @@
   HeapObject::PrintHeader("Map");
   PrintF(" - type: %s\n", TypeToString(instance_type()));
   PrintF(" - instance size: %d\n", instance_size());
+  PrintF(" - inobject properties: %d\n", inobject_properties());
   PrintF(" - unused property fields: %d\n", unused_property_fields());
   if (is_hidden_prototype()) {
     PrintF(" - hidden_prototype\n");
@@ -619,6 +620,12 @@
   PrintF("\n - debug info = ");
   debug_info()->ShortPrint();
   PrintF("\n - length = %d", length());
+  PrintF("\n - has_only_this_property_assignments = %d",
+         has_only_this_property_assignments());
+  PrintF("\n - has_only_simple_this_property_assignments = %d",
+         has_only_simple_this_property_assignments());
+  PrintF("\n - this_property_assignments = ");
+  this_property_assignments()->ShortPrint();
   PrintF("\n");
 }
 
diff --git a/src/objects-inl.h b/src/objects-inl.h
index a3bd3ce..7b750b6 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -91,7 +91,13 @@
   }
 
 
-#define BOOL_ACCESSORS(holder, field, name, offset) \
+#define BOOL_GETTER(holder, field, name, offset)           \
+  bool holder::name() {                                    \
+    return BooleanBit::get(field(), offset);               \
+  }                                                        \
+
+
+#define BOOL_ACCESSORS(holder, field, name, offset)        \
   bool holder::name() {                                    \
     return BooleanBit::get(field(), offset);               \
   }                                                        \
@@ -1937,6 +1943,11 @@
 }
 
 
+int Map::pre_allocated_property_fields() {
+  return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
+}
+
+
 int HeapObject::SizeFromMap(Map* map) {
   InstanceType instance_type = map->instance_type();
   // Only inline the most frequent cases.
@@ -1969,6 +1980,14 @@
 }
 
 
+void Map::set_pre_allocated_property_fields(int value) {
+  ASSERT(0 <= value && value < 256);
+  WRITE_BYTE_FIELD(this,
+                   kPreAllocatedPropertyFieldsOffset,
+                   static_cast<byte>(value));
+}
+
+
 InstanceType Map::instance_type() {
   return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
 }
@@ -2298,6 +2317,8 @@
 ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
 ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
 ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
+ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
+          kThisPropertyAssignmentsOffset)
 
 BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
                kHiddenPrototypeBit)
@@ -2308,6 +2329,13 @@
                kIsExpressionBit)
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
                kIsTopLevelBit)
+BOOL_GETTER(SharedFunctionInfo, compiler_hints,
+            has_only_this_property_assignments,
+            kHasOnlyThisPropertyAssignments)
+BOOL_GETTER(SharedFunctionInfo, compiler_hints,
+            has_only_simple_this_property_assignments,
+            kHasOnlySimpleThisPropertyAssignments)
+
 
 INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
 INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
@@ -2319,6 +2347,10 @@
 INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
 INT_ACCESSORS(SharedFunctionInfo, function_token_position,
               kFunctionTokenPositionOffset)
+INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
+              kCompilerHintsOffset)
+INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
+              kThisPropertyAssignmentsCountOffset)
 
 
 void SharedFunctionInfo::DontAdaptArguments() {
diff --git a/src/objects.cc b/src/objects.cc
index c3051b8..e4a3a67 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4780,6 +4780,48 @@
 }
 
 
+int SharedFunctionInfo::CalculateInstanceSize() {
+  int instance_size =
+      JSObject::kHeaderSize +
+      expected_nof_properties() * kPointerSize;
+  if (instance_size > JSObject::kMaxInstanceSize) {
+    instance_size = JSObject::kMaxInstanceSize;
+  }
+  return instance_size;
+}
+
+
+int SharedFunctionInfo::CalculateInObjectProperties() {
+  return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize;
+}
+
+
+void SharedFunctionInfo::SetThisPropertyAssignmentsInfo(
+    bool only_this_property_assignments,
+    bool only_simple_this_property_assignments,
+    FixedArray* assignments) {
+  ASSERT(this_property_assignments()->IsUndefined());
+  set_compiler_hints(BooleanBit::set(compiler_hints(),
+                                     kHasOnlyThisPropertyAssignments,
+                                     only_this_property_assignments));
+  set_compiler_hints(BooleanBit::set(compiler_hints(),
+                                     kHasOnlySimpleThisPropertyAssignments,
+                                     only_simple_this_property_assignments));
+  set_this_property_assignments(assignments);
+  set_this_property_assignments_count(assignments->length() / 3);
+}
+
+
+String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) {
+  Object* obj = this_property_assignments();
+  ASSERT(obj->IsFixedArray());
+  ASSERT(index < this_property_assignments_count());
+  obj = FixedArray::cast(obj)->get(index * 3);
+  ASSERT(obj->IsString());
+  return String::cast(obj);
+}
+
+
 // Support function for printing the source code to a StringStream
 // without any allocation in the heap.
 void SharedFunctionInfo::SourceCodePrint(StringStream* accumulator,
@@ -4826,6 +4868,8 @@
   IteratePointers(v, kNameOffset, kConstructStubOffset + kPointerSize);
   IteratePointers(v, kInstanceClassNameOffset, kScriptOffset + kPointerSize);
   IteratePointers(v, kDebugInfoOffset, kInferredNameOffset + kPointerSize);
+  IteratePointers(v, kThisPropertyAssignmentsOffset,
+      kThisPropertyAssignmentsOffset + kPointerSize);
 }
 
 
diff --git a/src/objects.h b/src/objects.h
index 03f0f3d..a402961 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2704,6 +2704,10 @@
   inline int inobject_properties();
   inline void set_inobject_properties(int value);
 
+  // Count of property fields pre-allocated in the object when first allocated.
+  inline int pre_allocated_property_fields();
+  inline void set_pre_allocated_property_fields(int value);
+
   // Instance type.
   inline InstanceType instance_type();
   inline void set_instance_type(InstanceType value);
@@ -2869,6 +2873,8 @@
   void MapVerify();
 #endif
 
+  static const int kMaxPreAllocatedPropertyFields = 255;
+
   // Layout description.
   static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
   static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
@@ -2882,7 +2888,8 @@
   // Byte offsets within kInstanceSizesOffset.
   static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
   static const int kInObjectPropertiesOffset = kInstanceSizesOffset + 1;
-  // The bytes at positions 2 and 3 are not in use at the moment.
+  static const int kPreAllocatedPropertyFieldsOffset = kInstanceSizesOffset + 2;
+  // The byte at position 3 is not in use at the moment.
 
   // Byte offsets within kInstanceAttributesOffset attributes.
   static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
@@ -3090,10 +3097,42 @@
   inline bool is_toplevel();
   inline void set_is_toplevel(bool value);
 
+  // Bit field containing various information collected by the compiler to
+  // drive optimization.
+  inline int compiler_hints();
+  inline void set_compiler_hints(int value);
+
+  // Add information on assignments of the form this.x = ...;
+  void SetThisPropertyAssignmentsInfo(
+      bool has_only_this_property_assignments,
+      bool has_only_simple_this_property_assignments,
+      FixedArray* this_property_assignments);
+
+  // Indicate that this function only consists of assignments of the form
+  // this.x = ...;.
+  inline bool has_only_this_property_assignments();
+
+  // Indicate that this function only consists of assignments of the form
+  // this.x = y; where y is either a constant or refers to an argument.
+  inline bool has_only_simple_this_property_assignments();
+
+  // For functions which only contains this property assignments this provides
+  // access to the names for the properties assigned.
+  DECL_ACCESSORS(this_property_assignments, Object)
+  inline int this_property_assignments_count();
+  inline void set_this_property_assignments_count(int value);
+  String* GetThisPropertyAssignmentName(int index);
+
   // [source code]: Source code for the function.
   bool HasSourceCode();
   Object* GetSourceCode();
 
+  // Calculate the instance size.
+  int CalculateInstanceSize();
+
+  // Calculate the number of in-object properties.
+  int CalculateInObjectProperties();
+
   // Dispatched behavior.
   void SharedFunctionInfoIterateBody(ObjectVisitor* v);
   // Set max_length to -1 for unlimited length.
@@ -3129,7 +3168,12 @@
   static const int kScriptOffset = kExternalReferenceDataOffset + kPointerSize;
   static const int kDebugInfoOffset = kScriptOffset + kPointerSize;
   static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
-  static const int kSize = kInferredNameOffset + kPointerSize;
+  static const int kCompilerHintsOffset = kInferredNameOffset + kPointerSize;
+  static const int kThisPropertyAssignmentsOffset =
+      kCompilerHintsOffset + kPointerSize;
+  static const int kThisPropertyAssignmentsCountOffset =
+      kThisPropertyAssignmentsOffset + kPointerSize;
+  static const int kSize = kThisPropertyAssignmentsCountOffset + kPointerSize;
 
  private:
   // Bit positions in length_and_flg.
@@ -3146,6 +3190,10 @@
   static const int kStartPositionShift = 2;
   static const int kStartPositionMask = ~((1 << kStartPositionShift) - 1);
 
+  // Bit positions in compiler_hints.
+  static const int kHasOnlyThisPropertyAssignments = 0;
+  static const int kHasOnlySimpleThisPropertyAssignments = 1;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(SharedFunctionInfo);
 };
 
diff --git a/src/parser.cc b/src/parser.cc
index 348c12a..5cc6341 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -97,7 +97,7 @@
 
   // Pre-parse the program from the character stream; returns true on
   // success, false if a stack-overflow happened during parsing.
-  bool PreParseProgram(unibrow::CharacterStream* stream);
+  bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream);
 
   void ReportMessage(const char* message, Vector<const char*> args);
   virtual void ReportMessageAt(Scanner::Location loc,
@@ -678,6 +678,25 @@
   void set_contains_array_literal() { contains_array_literal_ = true; }
   bool contains_array_literal() { return contains_array_literal_; }
 
+  void SetThisPropertyAssignmentInfo(
+      bool only_this_property_assignments,
+      bool only_simple_this_property_assignments,
+      Handle<FixedArray> this_property_assignments) {
+    only_this_property_assignments_ = only_this_property_assignments;
+    only_simple_this_property_assignments_ =
+        only_simple_this_property_assignments;
+    this_property_assignments_ = this_property_assignments;
+  }
+  bool only_this_property_assignments() {
+    return only_this_property_assignments_;
+  }
+  bool only_simple_this_property_assignments() {
+    return only_simple_this_property_assignments_;
+  }
+  Handle<FixedArray> this_property_assignments() {
+    return this_property_assignments_;
+  }
+
   void AddProperty() { expected_property_count_++; }
   int expected_property_count() { return expected_property_count_; }
  private:
@@ -695,6 +714,10 @@
   // Properties count estimation.
   int expected_property_count_;
 
+  bool only_this_property_assignments_;
+  bool only_simple_this_property_assignments_;
+  Handle<FixedArray> this_property_assignments_;
+
   // Bookkeeping
   Parser* parser_;
   TemporaryScope* parent_;
@@ -707,6 +730,9 @@
   : materialized_literal_count_(0),
     contains_array_literal_(false),
     expected_property_count_(0),
+    only_this_property_assignments_(false),
+    only_simple_this_property_assignments_(false),
+    this_property_assignments_(Factory::empty_fixed_array()),
     parser_(parser),
     parent_(parser->temp_scope_) {
   parser->temp_scope_ = this;
@@ -1167,13 +1193,14 @@
 }
 
 
-bool Parser::PreParseProgram(unibrow::CharacterStream* stream) {
+bool Parser::PreParseProgram(Handle<String> source,
+                             unibrow::CharacterStream* stream) {
   HistogramTimerScope timer(&Counters::pre_parse);
   StackGuard guard;
   AssertNoZoneAllocation assert_no_zone_allocation;
   AssertNoAllocation assert_no_allocation;
   NoHandleAllocation no_handle_allocation;
-  scanner_.Init(Handle<String>(), stream, 0);
+  scanner_.Init(source, stream, 0);
   ASSERT(target_stack_ == NULL);
   mode_ = PARSE_EAGERLY;
   DummyScope top_scope;
@@ -1217,12 +1244,20 @@
     bool ok = true;
     ParseSourceElements(&body, Token::EOS, &ok);
     if (ok) {
-      result = NEW(FunctionLiteral(no_name, top_scope_,
-                                   body.elements(),
-                                   temp_scope.materialized_literal_count(),
-                                   temp_scope.contains_array_literal(),
-                                   temp_scope.expected_property_count(),
-                                   0, 0, source->length(), false));
+      result = NEW(FunctionLiteral(
+          no_name,
+          top_scope_,
+          body.elements(),
+          temp_scope.materialized_literal_count(),
+          temp_scope.contains_array_literal(),
+          temp_scope.expected_property_count(),
+          temp_scope.only_this_property_assignments(),
+          temp_scope.only_simple_this_property_assignments(),
+          temp_scope.this_property_assignments(),
+          0,
+          0,
+          source->length(),
+          false));
     } else if (scanner().stack_overflow()) {
       Top::StackOverflow();
     }
@@ -1313,9 +1348,23 @@
 }
 
 
+// Base class containing common code for the different finder classes used by
+// the parser.
+class ParserFinder {
+ protected:
+  ParserFinder() {}
+  static Assignment* AsAssignment(Statement* stat) {
+    if (stat == NULL) return NULL;
+    ExpressionStatement* exp_stat = stat->AsExpressionStatement();
+    if (exp_stat == NULL) return NULL;
+    return exp_stat->expression()->AsAssignment();
+  }
+};
+
+
 // An InitializationBlockFinder finds and marks sequences of statements of the
 // form x.y.z.a = ...; x.y.z.b = ...; etc.
-class InitializationBlockFinder {
+class InitializationBlockFinder : public ParserFinder {
  public:
   InitializationBlockFinder()
     : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {}
@@ -1340,13 +1389,6 @@
   }
 
  private:
-  static Assignment* AsAssignment(Statement* stat) {
-    if (stat == NULL) return NULL;
-    ExpressionStatement* exp_stat = stat->AsExpressionStatement();
-    if (exp_stat == NULL) return NULL;
-    return exp_stat->expression()->AsAssignment();
-  }
-
   // Returns true if the expressions appear to denote the same object.
   // In the context of initialization blocks, we only consider expressions
   // of the form 'x.y.z'.
@@ -1417,6 +1459,161 @@
 };
 
 
+// A ThisNamedPropertyAssigmentFinder finds and marks statements of the form
+// this.x = ...;, where x is a named property. It also determines whether a
+// function contains only assignments of this type.
+class ThisNamedPropertyAssigmentFinder : public ParserFinder {
+ public:
+  ThisNamedPropertyAssigmentFinder()
+      : only_this_property_assignments_(true),
+        only_simple_this_property_assignments_(true),
+        names_(NULL),
+        assigned_arguments_(NULL),
+        assigned_constants_(NULL) {}
+
+  void Update(Scope* scope, Statement* stat) {
+    // Bail out if function already has non this property assignment
+    // statements.
+    if (!only_this_property_assignments_) {
+      return;
+    }
+
+    // Check whether this statement is of the form this.x = ...;
+    Assignment* assignment = AsAssignment(stat);
+    if (IsThisPropertyAssignment(assignment)) {
+      HandleThisPropertyAssignment(scope, assignment);
+    } else {
+      only_this_property_assignments_ = false;
+      only_simple_this_property_assignments_ = false;
+    }
+  }
+
+  // Returns whether only statements of the form this.x = ...; was encountered.
+  bool only_this_property_assignments() {
+    return only_this_property_assignments_;
+  }
+
+  // Returns whether only statements of the form this.x = y; where y is either a
+  // constant or a function argument was encountered.
+  bool only_simple_this_property_assignments() {
+    return only_simple_this_property_assignments_;
+  }
+
+  // Returns a fixed array containing three elements for each assignment of the
+  // form this.x = y;
+  Handle<FixedArray> GetThisPropertyAssignments() {
+    if (names_ == NULL) {
+      return Factory::empty_fixed_array();
+    }
+    ASSERT(names_ != NULL);
+    ASSERT(assigned_arguments_ != NULL);
+    ASSERT_EQ(names_->length(), assigned_arguments_->length());
+    ASSERT_EQ(names_->length(), assigned_constants_->length());
+    Handle<FixedArray> assignments =
+        Factory::NewFixedArray(names_->length() * 3);
+    for (int i = 0; i < names_->length(); i++) {
+      assignments->set(i * 3, *names_->at(i));
+      assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i)));
+      assignments->set(i * 3 + 2, *assigned_constants_->at(i));
+    }
+    return assignments;
+  }
+
+ private:
+  bool IsThisPropertyAssignment(Assignment* assignment) {
+    if (assignment != NULL) {
+      Property* property = assignment->target()->AsProperty();
+      return assignment->op() == Token::ASSIGN
+             && property != NULL
+             && property->obj()->AsVariableProxy() != NULL
+             && property->obj()->AsVariableProxy()->is_this();
+    }
+    return false;
+  }
+
+  void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) {
+    // Check that the property assigned to is a named property.
+    Property* property = assignment->target()->AsProperty();
+    ASSERT(property != NULL);
+    Literal* literal = property->key()->AsLiteral();
+    uint32_t dummy;
+    if (literal != NULL &&
+        literal->handle()->IsString() &&
+        !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
+      Handle<String> key = Handle<String>::cast(literal->handle());
+
+      // Check whether the value assigned is either a constant or matches the
+      // name of one of the arguments to the function.
+      if (assignment->value()->AsLiteral() != NULL) {
+        // Constant assigned.
+        Literal* literal = assignment->value()->AsLiteral();
+        AssignmentFromConstant(key, literal->handle());
+      } else if (assignment->value()->AsVariableProxy() != NULL) {
+        // Variable assigned.
+        Handle<String> name =
+            assignment->value()->AsVariableProxy()->name();
+        // Check whether the variable assigned matches an argument name.
+        int index = -1;
+        for (int i = 0; i < scope->num_parameters(); i++) {
+          if (*scope->parameter(i)->name() == *name) {
+            // Assigned from function argument.
+            index = i;
+            break;
+          }
+        }
+        if (index != -1) {
+          AssignmentFromParameter(key, index);
+        } else {
+          AssignmentFromSomethingElse(key);
+        }
+      } else {
+        AssignmentFromSomethingElse(key);
+      }
+    }
+  }
+
+  void AssignmentFromParameter(Handle<String> name, int index) {
+    EnsureAllocation();
+    names_->Add(name);
+    assigned_arguments_->Add(index);
+    assigned_constants_->Add(Factory::undefined_value());
+  }
+
+  void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
+    EnsureAllocation();
+    names_->Add(name);
+    assigned_arguments_->Add(-1);
+    assigned_constants_->Add(value);
+  }
+
+  void AssignmentFromSomethingElse(Handle<String> name) {
+    EnsureAllocation();
+    names_->Add(name);
+    assigned_arguments_->Add(-1);
+    assigned_constants_->Add(Factory::undefined_value());
+
+    // The this assignment is not a simple one.
+    only_simple_this_property_assignments_ = false;
+  }
+
+  void EnsureAllocation() {
+    if (names_ == NULL) {
+      ASSERT(assigned_arguments_ == NULL);
+      ASSERT(assigned_constants_ == NULL);
+      names_ = new ZoneStringList(4);
+      assigned_arguments_ = new ZoneList<int>(4);
+      assigned_constants_ = new ZoneObjectList(4);
+    }
+  }
+
+  bool only_this_property_assignments_;
+  bool only_simple_this_property_assignments_;
+  ZoneStringList* names_;
+  ZoneList<int>* assigned_arguments_;
+  ZoneObjectList* assigned_constants_;
+};
+
+
 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
                                   int end_token,
                                   bool* ok) {
@@ -1431,15 +1628,33 @@
 
   ASSERT(processor != NULL);
   InitializationBlockFinder block_finder;
+  ThisNamedPropertyAssigmentFinder this_property_assignment_finder;
   while (peek() != end_token) {
     Statement* stat = ParseStatement(NULL, CHECK_OK);
     if (stat == NULL || stat->IsEmpty()) continue;
     // We find and mark the initialization blocks on top level code only.
     // This is because the optimization prevents reuse of the map transitions,
     // so it should be used only for code that will only be run once.
-    if (top_scope_->is_global_scope()) block_finder.Update(stat);
+    if (top_scope_->is_global_scope()) {
+      block_finder.Update(stat);
+    }
+    // Find and mark all assignments to named properties in this (this.x =)
+    if (top_scope_->is_function_scope()) {
+      this_property_assignment_finder.Update(top_scope_, stat);
+    }
     processor->Add(stat);
   }
+
+  // Propagate the collected information on this property assignments.
+  if (top_scope_->is_function_scope()) {
+    if (this_property_assignment_finder.only_this_property_assignments()) {
+      temp_scope_->SetThisPropertyAssignmentInfo(
+          this_property_assignment_finder.only_this_property_assignments(),
+          this_property_assignment_finder.
+              only_simple_this_property_assignments(),
+          this_property_assignment_finder.GetThisPropertyAssignments());
+    }
+  }
   return 0;
 }
 
@@ -3506,6 +3721,9 @@
     int materialized_literal_count;
     int expected_property_count;
     bool contains_array_literal;
+    bool only_this_property_assignments;
+    bool only_simple_this_property_assignments;
+    Handle<FixedArray> this_property_assignments;
     if (is_lazily_compiled && pre_data() != NULL) {
       FunctionEntry entry = pre_data()->GetFunctionEnd(start_pos);
       int end_pos = entry.end_pos();
@@ -3513,12 +3731,20 @@
       scanner_.SeekForward(end_pos);
       materialized_literal_count = entry.literal_count();
       expected_property_count = entry.property_count();
+      only_this_property_assignments = false;
+      only_simple_this_property_assignments = false;
+      this_property_assignments = Factory::empty_fixed_array();
       contains_array_literal = entry.contains_array_literal();
     } else {
       ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
       materialized_literal_count = temp_scope.materialized_literal_count();
       expected_property_count = temp_scope.expected_property_count();
       contains_array_literal = temp_scope.contains_array_literal();
+      only_this_property_assignments =
+          temp_scope.only_this_property_assignments();
+      only_simple_this_property_assignments =
+          temp_scope.only_simple_this_property_assignments();
+      this_property_assignments = temp_scope.this_property_assignments();
     }
 
     Expect(Token::RBRACE, CHECK_OK);
@@ -3533,10 +3759,18 @@
     }
 
     FunctionLiteral* function_literal =
-        NEW(FunctionLiteral(name, top_scope_,
-                            body.elements(), materialized_literal_count,
-                            contains_array_literal, expected_property_count,
-                            num_parameters, start_pos, end_pos,
+        NEW(FunctionLiteral(name,
+                            top_scope_,
+                            body.elements(),
+                            materialized_literal_count,
+                            contains_array_literal,
+                            expected_property_count,
+                            only_this_property_assignments,
+                            only_simple_this_property_assignments,
+                            this_property_assignments,
+                            num_parameters,
+                            start_pos,
+                            end_pos,
                             function_name->length() > 0));
     if (!is_pre_parsing_) {
       function_literal->set_function_token_position(function_token_position);
@@ -4593,7 +4827,8 @@
 }
 
 
-ScriptDataImpl* PreParse(unibrow::CharacterStream* stream,
+ScriptDataImpl* PreParse(Handle<String> source,
+                         unibrow::CharacterStream* stream,
                          v8::Extension* extension) {
   Handle<Script> no_script;
   bool allow_natives_syntax =
@@ -4601,7 +4836,7 @@
       FLAG_allow_natives_syntax ||
       Bootstrapper::IsActive();
   PreParser parser(no_script, allow_natives_syntax, extension);
-  if (!parser.PreParseProgram(stream)) return NULL;
+  if (!parser.PreParseProgram(source, stream)) return NULL;
   // The list owns the backing store so we need to clone the vector.
   // That way, the result will be exactly the right size rather than
   // the expected 50% too large.
diff --git a/src/parser.h b/src/parser.h
index c029c4b..86e1f74 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -143,7 +143,8 @@
                          ScriptDataImpl* pre_data);
 
 
-ScriptDataImpl* PreParse(unibrow::CharacterStream* stream,
+ScriptDataImpl* PreParse(Handle<String> source,
+                         unibrow::CharacterStream* stream,
                          v8::Extension* extension);
 
 
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 633b2c2..0a2d990 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -54,6 +54,10 @@
 #define _WIN32_WINNT 0x500
 #endif
 
+#ifdef  _WIN64
+#error Windows 64-bit blatforms not supported
+#endif
+
 #include <windows.h>
 
 #include <time.h>  // For LocalOffset() implementation.
diff --git a/src/regexp-macro-assembler-irregexp.cc b/src/regexp-macro-assembler-irregexp.cc
index eea3c23..21b622e 100644
--- a/src/regexp-macro-assembler-irregexp.cc
+++ b/src/regexp-macro-assembler-irregexp.cc
@@ -375,37 +375,6 @@
 }
 
 
-void RegExpMacroAssemblerIrregexp::CheckBitmap(uc16 start,
-                                           Label* bitmap,
-                                           Label* on_zero) {
-  UNIMPLEMENTED();
-}
-
-
-void RegExpMacroAssemblerIrregexp::DispatchHalfNibbleMap(
-    uc16 start,
-    Label* half_nibble_map,
-    const Vector<Label*>& table) {
-  UNIMPLEMENTED();
-}
-
-
-void RegExpMacroAssemblerIrregexp::DispatchByteMap(
-    uc16 start,
-    Label* byte_map,
-    const Vector<Label*>& table) {
-  UNIMPLEMENTED();
-}
-
-
-void RegExpMacroAssemblerIrregexp::DispatchHighByteMap(
-    byte start,
-    Label* byte_map,
-    const Vector<Label*>& table) {
-  UNIMPLEMENTED();
-}
-
-
 void RegExpMacroAssemblerIrregexp::CheckCharacters(
   Vector<const uc16> str,
   int cp_offset,
diff --git a/src/regexp-macro-assembler-irregexp.h b/src/regexp-macro-assembler-irregexp.h
index 597046c..dd64e7a 100644
--- a/src/regexp-macro-assembler-irregexp.h
+++ b/src/regexp-macro-assembler-irregexp.h
@@ -52,7 +52,6 @@
   // The byte-code interpreter checks on each push anyway.
   virtual int stack_limit_slack() { return 1; }
   virtual void Bind(Label* label);
-  virtual void EmitOrLink(Label* label);
   virtual void AdvanceCurrentPosition(int by);  // Signed cp change.
   virtual void PopCurrentPosition();
   virtual void PushCurrentPosition();
@@ -100,16 +99,6 @@
                                int cp_offset,
                                Label* on_failure,
                                bool check_end_of_string);
-  virtual void CheckBitmap(uc16 start, Label* bitmap, Label* on_zero);
-  virtual void DispatchHalfNibbleMap(uc16 start,
-                                     Label* half_nibble_map,
-                                     const Vector<Label*>& destinations);
-  virtual void DispatchByteMap(uc16 start,
-                               Label* byte_map,
-                               const Vector<Label*>& destinations);
-  virtual void DispatchHighByteMap(byte start,
-                                   Label* byte_map,
-                                   const Vector<Label*>& destinations);
   virtual void IfRegisterLT(int register_index, int comparand, Label* if_lt);
   virtual void IfRegisterGE(int register_index, int comparand, Label* if_ge);
   virtual void IfRegisterEqPos(int register_index, Label* if_eq);
@@ -119,6 +108,7 @@
  private:
   void Expand();
   // Code and bitmap emission.
+  inline void EmitOrLink(Label* label);
   inline void Emit32(uint32_t x);
   inline void Emit16(uint32_t x);
   inline void Emit(uint32_t bc, uint32_t arg);
diff --git a/src/regexp-macro-assembler-tracer.cc b/src/regexp-macro-assembler-tracer.cc
index 30eb485..0aad337 100644
--- a/src/regexp-macro-assembler-tracer.cc
+++ b/src/regexp-macro-assembler-tracer.cc
@@ -53,12 +53,6 @@
 }
 
 
-void RegExpMacroAssemblerTracer::EmitOrLink(Label* label) {
-  PrintF(" EmitOrLink(label[%08x]);\n", label);
-  assembler_->EmitOrLink(label);
-}
-
-
 void RegExpMacroAssemblerTracer::AdvanceCurrentPosition(int by) {
   PrintF(" AdvanceCurrentPosition(by=%d);\n", by);
   assembler_->AdvanceCurrentPosition(by);
@@ -311,13 +305,6 @@
 }
 
 
-void RegExpMacroAssemblerTracer::CheckBitmap(uc16 start, Label* bitmap,
-                                             Label* on_zero) {
-  PrintF(" CheckBitmap(start=u%04x, <bitmap>, label[%08x]);\n", start, on_zero);
-  assembler_->CheckBitmap(start, bitmap, on_zero);
-}
-
-
 bool RegExpMacroAssemblerTracer::CheckSpecialCharacterClass(
     uc16 type,
     int cp_offset,
@@ -338,51 +325,6 @@
 }
 
 
-void RegExpMacroAssemblerTracer::DispatchHalfNibbleMap(
-    uc16 start,
-    Label* half_nibble_map,
-    const Vector<Label*>& destinations) {
-  PrintF(" DispatchHalfNibbleMap(start=u%04x, <half_nibble_map>, [", start);
-  for (int i = 0; i < destinations.length(); i++) {
-    if (i > 0)
-      PrintF(", ");
-    PrintF("label[%08x]", destinations[i]);
-  }
-  PrintF(");\n");
-  assembler_->DispatchHalfNibbleMap(start, half_nibble_map, destinations);
-}
-
-
-void RegExpMacroAssemblerTracer::DispatchByteMap(
-    uc16 start,
-    Label* byte_map,
-    const Vector<Label*>& destinations) {
-  PrintF(" DispatchByteMap(start=u%04x, <byte_map>, [", start);
-  for (int i = 0; i < destinations.length(); i++) {
-    if (i > 0)
-      PrintF(", ");
-    PrintF("label[%08x]", destinations[i]);
-  }
-  PrintF(");\n");
-  assembler_->DispatchByteMap(start, byte_map, destinations);
-}
-
-
-void RegExpMacroAssemblerTracer::DispatchHighByteMap(
-    byte start,
-    Label* byte_map,
-    const Vector<Label*>& destinations) {
-  PrintF(" DispatchHighByteMap(start=u%04x, <byte_map>, [", start);
-  for (int i = 0; i < destinations.length(); i++) {
-    if (i > 0)
-      PrintF(", ");
-    PrintF("label[%08x]", destinations[i]);
-  }
-  PrintF(");\n");
-  assembler_->DispatchHighByteMap(start, byte_map, destinations);
-}
-
-
 void RegExpMacroAssemblerTracer::IfRegisterLT(int register_index,
                                               int comparand, Label* if_lt) {
   PrintF(" IfRegisterLT(register=%d, number=%d, label[%08x]);\n",
diff --git a/src/regexp-macro-assembler-tracer.h b/src/regexp-macro-assembler-tracer.h
index 0fd73f3..28434d7 100644
--- a/src/regexp-macro-assembler-tracer.h
+++ b/src/regexp-macro-assembler-tracer.h
@@ -43,7 +43,6 @@
   virtual void Backtrack();
   virtual void Bind(Label* label);
   virtual void CheckAtStart(Label* on_at_start);
-  virtual void CheckBitmap(uc16 start, Label* bitmap, Label* on_zero);
   virtual void CheckCharacter(uint32_t c, Label* on_equal);
   virtual void CheckCharacterAfterAnd(uint32_t c,
                                       uint32_t and_with,
@@ -73,19 +72,6 @@
                                           int cp_offset,
                                           bool check_offset,
                                           Label* on_no_match);
-  virtual void DispatchByteMap(
-      uc16 start,
-      Label* byte_map,
-      const Vector<Label*>& destinations);
-  virtual void DispatchHalfNibbleMap(
-      uc16 start,
-      Label* half_nibble_map,
-      const Vector<Label*>& destinations);
-  virtual void DispatchHighByteMap(
-      byte start,
-      Label* byte_map,
-      const Vector<Label*>& destinations);
-  virtual void EmitOrLink(Label* label);
   virtual void Fail();
   virtual Handle<Object> GetCode(Handle<String> source);
   virtual void GoTo(Label* label);
diff --git a/src/regexp-macro-assembler.cc b/src/regexp-macro-assembler.cc
index 8dede30..7f830fe 100644
--- a/src/regexp-macro-assembler.cc
+++ b/src/regexp-macro-assembler.cc
@@ -25,10 +25,10 @@
 // (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 <string.h>
 #include "v8.h"
 #include "ast.h"
 #include "assembler.h"
+#include "regexp-stack.h"
 #include "regexp-macro-assembler.h"
 
 namespace v8 {
@@ -42,38 +42,176 @@
 }
 
 
-ByteArrayProvider::ByteArrayProvider(unsigned int initial_size)
-  : byte_array_size_(initial_size),
-    current_byte_array_(),
-    current_byte_array_free_offset_(initial_size) {}
+#ifdef V8_NATIVE_REGEXP  // Avoid unused code, e.g., on ARM.
+
+NativeRegExpMacroAssembler::NativeRegExpMacroAssembler() {
+}
 
 
-ArraySlice ByteArrayProvider::GetBuffer(unsigned int size,
-                                        unsigned int elem_size) {
-  ASSERT(size > 0);
-  size_t byte_size = size * elem_size;
-  int free_offset = current_byte_array_free_offset_;
-  // align elements
-  free_offset += elem_size - 1;
-  free_offset = free_offset - (free_offset % elem_size);
+NativeRegExpMacroAssembler::~NativeRegExpMacroAssembler() {
+}
 
-  if (free_offset + byte_size > byte_array_size_) {
-    if (byte_size > (byte_array_size_ / 2)) {
-      Handle<ByteArray> solo_buffer(Factory::NewByteArray(byte_size, TENURED));
-      return ArraySlice(solo_buffer, 0);
+const byte* NativeRegExpMacroAssembler::StringCharacterPosition(
+    String* subject,
+    int start_index) {
+  // Not just flat, but ultra flat.
+  ASSERT(subject->IsExternalString() || subject->IsSeqString());
+  ASSERT(start_index >= 0);
+  ASSERT(start_index <= subject->length());
+  if (subject->IsAsciiRepresentation()) {
+    const byte* address;
+    if (StringShape(subject).IsExternal()) {
+      const char* data = ExternalAsciiString::cast(subject)->resource()->data();
+      address = reinterpret_cast<const byte*>(data);
+    } else {
+      ASSERT(subject->IsSeqAsciiString());
+      char* data = SeqAsciiString::cast(subject)->GetChars();
+      address = reinterpret_cast<const byte*>(data);
     }
-    current_byte_array_ = Factory::NewByteArray(byte_array_size_, TENURED);
-    free_offset = 0;
+    return address + start_index;
   }
-  current_byte_array_free_offset_ = free_offset + byte_size;
-  return ArraySlice(current_byte_array_, free_offset);
+  const uc16* data;
+  if (StringShape(subject).IsExternal()) {
+    data = ExternalTwoByteString::cast(subject)->resource()->data();
+  } else {
+    ASSERT(subject->IsSeqTwoByteString());
+    data = SeqTwoByteString::cast(subject)->GetChars();
+  }
+  return reinterpret_cast<const byte*>(data + start_index);
 }
 
 
-template <typename T>
-ArraySlice ByteArrayProvider::GetBuffer(Vector<T> values) {
-  ArraySlice slice = GetBuffer(values.length(), sizeof(T));
-  memcpy(slice.location(), values.start(), values.length() * sizeof(T));
-  return slice;
+NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
+    Handle<Code> regexp_code,
+    Handle<String> subject,
+    int* offsets_vector,
+    int offsets_vector_length,
+    int previous_index) {
+
+  ASSERT(subject->IsFlat());
+  ASSERT(previous_index >= 0);
+  ASSERT(previous_index <= subject->length());
+
+  // No allocations before calling the regexp, but we can't use
+  // AssertNoAllocation, since regexps might be preempted, and another thread
+  // might do allocation anyway.
+
+  String* subject_ptr = *subject;
+  // Character offsets into string.
+  int start_offset = previous_index;
+  int end_offset = subject_ptr->length();
+
+  bool is_ascii = subject->IsAsciiRepresentation();
+
+  if (StringShape(subject_ptr).IsCons()) {
+    subject_ptr = ConsString::cast(subject_ptr)->first();
+  } else if (StringShape(subject_ptr).IsSliced()) {
+    SlicedString* slice = SlicedString::cast(subject_ptr);
+    start_offset += slice->start();
+    end_offset += slice->start();
+    subject_ptr = slice->buffer();
+  }
+  // Ensure that an underlying string has the same ascii-ness.
+  ASSERT(subject_ptr->IsAsciiRepresentation() == is_ascii);
+  ASSERT(subject_ptr->IsExternalString() || subject_ptr->IsSeqString());
+  // String is now either Sequential or External
+  int char_size_shift = is_ascii ? 0 : 1;
+  int char_length = end_offset - start_offset;
+
+  const byte* input_start =
+      StringCharacterPosition(subject_ptr, start_offset);
+  int byte_length = char_length << char_size_shift;
+  const byte* input_end = input_start + byte_length;
+  Result res = Execute(*regexp_code,
+                       subject_ptr,
+                       start_offset,
+                       input_start,
+                       input_end,
+                       offsets_vector,
+                       previous_index == 0);
+
+  if (res == SUCCESS) {
+    // Capture values are relative to start_offset only.
+    // Convert them to be relative to start of string.
+    for (int i = 0; i < offsets_vector_length; i++) {
+      if (offsets_vector[i] >= 0) {
+        offsets_vector[i] += previous_index;
+      }
+    }
+  }
+
+  return res;
 }
+
+
+NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
+    Code* code,
+    String* input,
+    int start_offset,
+    const byte* input_start,
+    const byte* input_end,
+    int* output,
+    bool at_start) {
+  typedef int (*matcher)(String*, int, const byte*,
+                         const byte*, int*, int, Address);
+  matcher matcher_func = FUNCTION_CAST<matcher>(code->entry());
+
+  int at_start_val = at_start ? 1 : 0;
+
+  // Ensure that the minimum stack has been allocated.
+  RegExpStack stack;
+  Address stack_base = RegExpStack::stack_base();
+
+  int result = matcher_func(input,
+                            start_offset,
+                            input_start,
+                            input_end,
+                            output,
+                            at_start_val,
+                            stack_base);
+  ASSERT(result <= SUCCESS);
+  ASSERT(result >= RETRY);
+
+  if (result == EXCEPTION && !Top::has_pending_exception()) {
+    // We detected a stack overflow (on the backtrack stack) in RegExp code,
+    // but haven't created the exception yet.
+    Top::StackOverflow();
+  }
+  return static_cast<Result>(result);
+}
+
+
+static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize;
+
+int NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16(
+    Address byte_offset1,
+    Address byte_offset2,
+    size_t byte_length) {
+  // This function is not allowed to cause a garbage collection.
+  // A GC might move the calling generated code and invalidate the
+  // return address on the stack.
+  ASSERT(byte_length % 2 == 0);
+  uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1);
+  uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2);
+  size_t length = byte_length >> 1;
+
+  for (size_t i = 0; i < length; i++) {
+    unibrow::uchar c1 = substring1[i];
+    unibrow::uchar c2 = substring2[i];
+    if (c1 != c2) {
+      unibrow::uchar s1[1] = { c1 };
+      canonicalize.get(c1, '\0', s1);
+      if (s1[0] != c2) {
+        unibrow::uchar s2[1] = { c2 };
+        canonicalize.get(c2, '\0', s2);
+        if (s1[0] != s2[0]) {
+          return 0;
+        }
+      }
+    }
+  }
+  return 1;
+}
+
+#endif  // V8_NATIVE_REGEXP
 } }  // namespace v8::internal
diff --git a/src/regexp-macro-assembler.h b/src/regexp-macro-assembler.h
index 4849864..e590827 100644
--- a/src/regexp-macro-assembler.h
+++ b/src/regexp-macro-assembler.h
@@ -46,6 +46,7 @@
   enum IrregexpImplementation {
     kIA32Implementation,
     kARMImplementation,
+    kX64Implementation,
     kBytecodeImplementation
   };
 
@@ -67,12 +68,6 @@
   virtual void Backtrack() = 0;
   virtual void Bind(Label* label) = 0;
   virtual void CheckAtStart(Label* on_at_start) = 0;
-  // Check the current character against a bitmap.  The range of the current
-  // character must be from start to start + length_of_bitmap_in_bits.
-  virtual void CheckBitmap(
-      uc16 start,           // The bitmap is indexed from this character.
-      Label* bitmap,        // Where the bitmap is emitted.
-      Label* on_zero) = 0;  // Where to go if the bit is 0.  Fall through on 1.
   // Dispatch after looking the current character up in a 2-bits-per-entry
   // map.  The destinations vector has up to 4 labels.
   virtual void CheckCharacter(uint32_t c, Label* on_equal) = 0;
@@ -132,23 +127,6 @@
                                           Label* on_no_match) {
     return false;
   }
-  // Dispatch after looking the current character up in a byte map.  The
-  // destinations vector has up to 256 labels.
-  virtual void DispatchByteMap(
-      uc16 start,
-      Label* byte_map,
-      const Vector<Label*>& destinations) = 0;
-  virtual void DispatchHalfNibbleMap(
-      uc16 start,
-      Label* half_nibble_map,
-      const Vector<Label*>& destinations) = 0;
-  // Dispatch after looking the high byte of the current character up in a byte
-  // map.  The destinations vector has up to 256 labels.
-  virtual void DispatchHighByteMap(
-      byte start,
-      Label* byte_map,
-      const Vector<Label*>& destinations) = 0;
-  virtual void EmitOrLink(Label* label) = 0;
   virtual void Fail() = 0;
   virtual Handle<Object> GetCode(Handle<String> source) = 0;
   virtual void GoTo(Label* label) = 0;
@@ -181,51 +159,53 @@
   virtual void WriteCurrentPositionToRegister(int reg, int cp_offset) = 0;
   virtual void ClearRegisters(int reg_from, int reg_to) = 0;
   virtual void WriteStackPointerToRegister(int reg) = 0;
-
- private:
 };
 
 
-struct ArraySlice {
+#ifdef V8_NATIVE_REGEXP  // Avoid compiling unused code.
+
+class NativeRegExpMacroAssembler: public RegExpMacroAssembler {
  public:
-  ArraySlice(Handle<ByteArray> array, size_t offset)
-    : array_(array), offset_(offset) {}
-  Handle<ByteArray> array() { return array_; }
-  // Offset in the byte array data.
-  size_t offset() { return offset_; }
-  // Offset from the ByteArray pointer.
-  size_t base_offset() {
-    return ByteArray::kHeaderSize - kHeapObjectTag + offset_;
-  }
-  void* location() {
-    return reinterpret_cast<void*>(array_->GetDataStartAddress() + offset_);
-  }
-  template <typename T>
-  T& at(int idx) {
-    return reinterpret_cast<T*>(array_->GetDataStartAddress() + offset_)[idx];
-  }
- private:
-  Handle<ByteArray> array_;
-  size_t offset_;
+  // Type of input string to generate code for.
+  enum Mode { ASCII = 1, UC16 = 2 };
+
+  // Result of calling generated native RegExp code.
+  // RETRY: Something significant changed during execution, and the matching
+  //        should be retried from scratch.
+  // EXCEPTION: Something failed during execution. If no exception has been
+  //        thrown, it's an internal out-of-memory, and the caller should
+  //        throw the exception.
+  // FAILURE: Matching failed.
+  // SUCCESS: Matching succeeded, and the output array has been filled with
+  //        capture positions.
+  enum Result { RETRY = -2, EXCEPTION = -1, FAILURE = 0, SUCCESS = 1 };
+
+  NativeRegExpMacroAssembler();
+  virtual ~NativeRegExpMacroAssembler();
+
+  static Result Match(Handle<Code> regexp,
+                      Handle<String> subject,
+                      int* offsets_vector,
+                      int offsets_vector_length,
+                      int previous_index);
+
+  // Compares two-byte strings case insensitively.
+  // Called from generated RegExp code.
+  static int CaseInsensitiveCompareUC16(Address byte_offset1,
+                                        Address byte_offset2,
+                                        size_t byte_length);
+
+  static const byte* StringCharacterPosition(String* subject, int start_index);
+
+  static Result Execute(Code* code,
+                        String* input,
+                        int start_offset,
+                        const byte* input_start,
+                        const byte* input_end,
+                        int* output,
+                        bool at_start);
 };
-
-
-class ByteArrayProvider {
- public:
-  explicit ByteArrayProvider(unsigned int initial_size);
-  // Provides a place to put "size" elements of size "element_size".
-  // The information can be stored in the provided ByteArray at the "offset".
-  // The offset is aligned to the element size.
-  ArraySlice GetBuffer(unsigned int size,
-                       unsigned int element_size);
-  template <typename T>
-  ArraySlice GetBuffer(Vector<T> values);
- private:
-  size_t byte_array_size_;
-  Handle<ByteArray> current_byte_array_;
-  int current_byte_array_free_offset_;
-};
-
+#endif  // V8_NATIVE_REGEXP
 } }  // namespace v8::internal
 
 #endif  // V8_REGEXP_MACRO_ASSEMBLER_H_
diff --git a/src/regexp-stack.h b/src/regexp-stack.h
index 6c090da..99cf33c 100644
--- a/src/regexp-stack.h
+++ b/src/regexp-stack.h
@@ -48,7 +48,7 @@
   ~RegExpStack();  // Releases the stack if it has grown.
 
   // Gives the top of the memory used as stack.
-  static Address stack_top() {
+  static Address stack_base() {
     ASSERT(thread_local_.memory_size_ != 0);
     return thread_local_.memory_ + thread_local_.memory_size_;
   }
@@ -74,7 +74,7 @@
 
  private:
   // Artificial limit used when no memory has been allocated.
-  static const uint32_t kMemoryTop = 0xffffffff;
+  static const uintptr_t kMemoryTop = static_cast<uintptr_t>(-1);
 
   // Minimal size of allocated stack area.
   static const size_t kMinimumStackSize = 1 * KB;
diff --git a/src/runtime.cc b/src/runtime.cc
index 0da4be8..b3e8aa4 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1022,6 +1022,30 @@
 }
 
 
+static Object* Runtime_OptimizeObjectForAddingMultipleProperties(
+    Arguments args) {
+  HandleScope scope;
+  ASSERT(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSObject, object, 0);
+  CONVERT_SMI_CHECKED(properties, args[1]);
+  if (object->HasFastProperties()) {
+    NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
+  }
+  return *object;
+}
+
+
+static Object* Runtime_TransformToFastProperties(Arguments args) {
+  HandleScope scope;
+  ASSERT(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSObject, object, 0);
+  if (!object->HasFastProperties() && !object->IsGlobalObject()) {
+    TransformToFastProperties(object, 0);
+  }
+  return *object;
+}
+
+
 static Object* Runtime_RegExpExec(Arguments args) {
   HandleScope scope;
   ASSERT(args.length() == 4);
@@ -3075,7 +3099,7 @@
       }
       ASSERT(heap_obj->IsUndefined());
       return Heap::undefined_symbol();
-    case JS_FUNCTION_TYPE:
+    case JS_FUNCTION_TYPE: case JS_REGEXP_TYPE:
       return Heap::function_symbol();
     default:
       // For any kind of object not handled above, the spec rule for
@@ -4356,6 +4380,8 @@
     Handle<Code> stub = ComputeConstructStub(map);
     function->shared()->set_construct_stub(*stub);
   }
+  Counters::constructed_objects.Increment();
+  Counters::constructed_objects_runtime.Increment();
   return *result;
 }
 
diff --git a/src/runtime.h b/src/runtime.h
index cdf21dc..d47ca18 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -247,6 +247,8 @@
   F(InitializeVarGlobal, -1 /* 1 or 2 */) \
   F(InitializeConstGlobal, 2) \
   F(InitializeConstContextSlot, 3) \
+  F(OptimizeObjectForAddingMultipleProperties, 2) \
+  F(TransformToFastProperties, 1) \
   \
   /* Debugging */ \
   F(DebugPrint, 1) \
diff --git a/src/scanner.cc b/src/scanner.cc
index 24a6d4b..720dc35 100644
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -92,18 +92,7 @@
 
 
 UTF16Buffer::UTF16Buffer()
-  : pos_(0),
-    pushback_buffer_(0),
-    last_(0),
-    stream_(NULL) { }
-
-
-void UTF16Buffer::Initialize(Handle<String> data,
-                             unibrow::CharacterStream* input) {
-  data_ = data;
-  pos_ = 0;
-  stream_ = input;
-}
+    : pos_(0), size_(0) { }
 
 
 Handle<String> UTF16Buffer::SubString(int start, int end) {
@@ -111,14 +100,27 @@
 }
 
 
-void UTF16Buffer::PushBack(uc32 ch) {
+// CharacterStreamUTF16Buffer
+CharacterStreamUTF16Buffer::CharacterStreamUTF16Buffer()
+    : pushback_buffer_(0), last_(0), stream_(NULL) { }
+
+
+void CharacterStreamUTF16Buffer::Initialize(Handle<String> data,
+                                            unibrow::CharacterStream* input) {
+  data_ = data;
+  pos_ = 0;
+  stream_ = input;
+}
+
+
+void CharacterStreamUTF16Buffer::PushBack(uc32 ch) {
   pushback_buffer()->Add(last_);
   last_ = ch;
   pos_--;
 }
 
 
-uc32 UTF16Buffer::Advance() {
+uc32 CharacterStreamUTF16Buffer::Advance() {
   // NOTE: It is of importance to Persian / Farsi resources that we do
   // *not* strip format control characters in the scanner; see
   //
@@ -135,7 +137,7 @@
     uc32 next = stream_->GetNext();
     return last_ = next;
   } else {
-    // note: currently the following increment is necessary to avoid a
+    // Note: currently the following increment is necessary to avoid a
     // test-parser problem!
     pos_++;
     return last_ = static_cast<uc32>(-1);
@@ -143,13 +145,53 @@
 }
 
 
-void UTF16Buffer::SeekForward(int pos) {
+void CharacterStreamUTF16Buffer::SeekForward(int pos) {
   pos_ = pos;
   ASSERT(pushback_buffer()->is_empty());
   stream_->Seek(pos);
 }
 
 
+// TwoByteStringUTF16Buffer
+TwoByteStringUTF16Buffer::TwoByteStringUTF16Buffer()
+    : raw_data_(NULL) { }
+
+
+void TwoByteStringUTF16Buffer::Initialize(
+     Handle<ExternalTwoByteString> data) {
+  ASSERT(!data.is_null());
+
+  data_ = data;
+  pos_ = 0;
+
+  raw_data_ = data->resource()->data();
+  size_ = data->length();
+}
+
+
+uc32 TwoByteStringUTF16Buffer::Advance() {
+  if (pos_ < size_) {
+    return raw_data_[pos_++];
+  } else {
+    // note: currently the following increment is necessary to avoid a
+    // test-parser problem!
+    pos_++;
+    return static_cast<uc32>(-1);
+  }
+}
+
+
+void TwoByteStringUTF16Buffer::PushBack(uc32 ch) {
+  pos_--;
+  ASSERT(pos_ >= 0 && raw_data_[pos_] == ch);
+}
+
+
+void TwoByteStringUTF16Buffer::SeekForward(int pos) {
+  pos_ = pos;
+}
+
+
 // ----------------------------------------------------------------------------
 // Scanner
 
@@ -161,7 +203,15 @@
 void Scanner::Init(Handle<String> source, unibrow::CharacterStream* stream,
     int position) {
   // Initialize the source buffer.
-  source_.Initialize(source, stream);
+  if (!source.is_null() && StringShape(*source).IsExternalTwoByte()) {
+    two_byte_string_buffer_.Initialize(
+        Handle<ExternalTwoByteString>::cast(source));
+    source_ = &two_byte_string_buffer_;
+  } else {
+    char_stream_buffer_.Initialize(source, stream);
+    source_ = &char_stream_buffer_;
+  }
+
   position_ = position;
 
   // Reset literals buffer
@@ -180,7 +230,7 @@
 
 
 Handle<String> Scanner::SubString(int start, int end) {
-  return source_.SubString(start - position_, end - position_);
+  return source_->SubString(start - position_, end - position_);
 }
 
 
@@ -223,17 +273,6 @@
 }
 
 
-void Scanner::Advance() {
-  c0_ = source_.Advance();
-}
-
-
-void Scanner::PushBack(uc32 ch) {
-  source_.PushBack(ch);
-  c0_ = ch;
-}
-
-
 static inline bool IsByteOrderMark(uc32 c) {
   // The Unicode value U+FFFE is guaranteed never to be assigned as a
   // Unicode character; this implies that in a Unicode context the
@@ -583,7 +622,7 @@
 
 
 void Scanner::SeekForward(int pos) {
-  source_.SeekForward(pos - 1);
+  source_->SeekForward(pos - 1);
   Advance();
   Scan();
 }
diff --git a/src/scanner.h b/src/scanner.h
index eea23a7..340da86 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -73,24 +73,53 @@
 class UTF16Buffer {
  public:
   UTF16Buffer();
+  virtual ~UTF16Buffer() {}
 
-  void Initialize(Handle<String> data, unibrow::CharacterStream* stream);
-  void PushBack(uc32 ch);
-  uc32 Advance();  // returns a value < 0 when the buffer end is reached
-  uint16_t CharAt(int index);
+  virtual void PushBack(uc32 ch) = 0;
+  // returns a value < 0 when the buffer end is reached
+  virtual uc32 Advance() = 0;
+  virtual void SeekForward(int pos) = 0;
+
   int pos() const { return pos_; }
   int size() const { return size_; }
   Handle<String> SubString(int start, int end);
-  List<uc32>* pushback_buffer() { return &pushback_buffer_; }
-  void SeekForward(int pos);
 
- private:
+ protected:
   Handle<String> data_;
   int pos_;
   int size_;
+};
+
+
+class CharacterStreamUTF16Buffer: public UTF16Buffer {
+ public:
+  CharacterStreamUTF16Buffer();
+  virtual ~CharacterStreamUTF16Buffer() {}
+  void Initialize(Handle<String> data, unibrow::CharacterStream* stream);
+  virtual void PushBack(uc32 ch);
+  virtual uc32 Advance();
+  virtual void SeekForward(int pos);
+
+ private:
   List<uc32> pushback_buffer_;
   uc32 last_;
   unibrow::CharacterStream* stream_;
+
+  List<uc32>* pushback_buffer() { return &pushback_buffer_; }
+};
+
+
+class TwoByteStringUTF16Buffer: public UTF16Buffer {
+ public:
+  TwoByteStringUTF16Buffer();
+  virtual ~TwoByteStringUTF16Buffer() {}
+  void Initialize(Handle<ExternalTwoByteString> data);
+  virtual void PushBack(uc32 ch);
+  virtual uc32 Advance();
+  virtual void SeekForward(int pos);
+
+ private:
+  const uint16_t* raw_data_;
 };
 
 
@@ -184,8 +213,11 @@
   static unibrow::Predicate<unibrow::WhiteSpace, 128> kIsWhiteSpace;
 
  private:
+  CharacterStreamUTF16Buffer char_stream_buffer_;
+  TwoByteStringUTF16Buffer two_byte_string_buffer_;
+
   // Source.
-  UTF16Buffer source_;
+  UTF16Buffer* source_;
   int position_;
 
   // Buffer to hold literal values (identifiers, strings, numbers)
@@ -219,8 +251,11 @@
   void TerminateLiteral();
 
   // Low-level scanning support.
-  void Advance();
-  void PushBack(uc32 ch);
+  void Advance() { c0_ = source_->Advance(); }
+  void PushBack(uc32 ch) {
+    source_->PushBack(ch);
+    c0_ = ch;
+  }
 
   bool SkipWhiteSpace();
   Token::Value SkipSingleLineComment();
@@ -243,7 +278,7 @@
 
   // Return the current source position.
   int source_pos() {
-    return source_.pos() - kCharacterLookaheadBufferSize + position_;
+    return source_->pos() - kCharacterLookaheadBufferSize + position_;
   }
 
   // Decodes a unicode escape-sequence which is part of an identifier.
diff --git a/src/scopes.cc b/src/scopes.cc
index 78ed035..25873fa 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -108,14 +108,31 @@
 
 
 // Dummy constructor
-Scope::Scope()
-  : inner_scopes_(0),
+Scope::Scope(Type type)
+  : outer_scope_(NULL),
+    inner_scopes_(0),
+    type_(type),
+    scope_name_(Factory::empty_symbol()),
     variables_(false),
     temps_(0),
     params_(0),
     dynamics_(NULL),
     unresolved_(0),
-    decls_(0) {
+    decls_(0),
+    receiver_(NULL),
+    function_(NULL),
+    arguments_(NULL),
+    arguments_shadow_(NULL),
+    illegal_redecl_(NULL),
+    scope_inside_with_(false),
+    scope_contains_with_(false),
+    scope_calls_eval_(false),
+    outer_scope_calls_eval_(false),
+    inner_scope_calls_eval_(false),
+    outer_scope_is_eval_scope_(false),
+    force_eager_compilation_(false),
+    num_stack_slots_(0),
+    num_heap_slots_(0) {
 }
 
 
diff --git a/src/scopes.h b/src/scopes.h
index 5767d9f..fc627df 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -93,7 +93,6 @@
     GLOBAL_SCOPE    // the top-level scope for a program or a top-level eval
   };
 
-  Scope();
   Scope(Scope* outer_scope, Type type);
 
   virtual ~Scope() { }
@@ -130,7 +129,7 @@
   Variable* DeclareGlobal(Handle<String> name);
 
   // Add a parameter to the parameter list. The parameter must have been
-  // declared via Declare. The same parameter may occur more then once in
+  // declared via Declare. The same parameter may occur more than once in
   // the parameter list; they must be added in source order, from left to
   // right.
   void AddParameter(Variable* var);
@@ -286,6 +285,8 @@
  protected:
   friend class ParserFactory;
 
+  explicit Scope(Type type);
+
   // Scope tree.
   Scope* outer_scope_;  // the immediately enclosing outer scope, or NULL
   ZoneList<Scope*> inner_scopes_;  // the immediately enclosed inner scopes
@@ -375,7 +376,7 @@
 
 class DummyScope : public Scope {
  public:
-  DummyScope() {
+  DummyScope() : Scope(GLOBAL_SCOPE) {
     outer_scope_ = this;
   }
 
diff --git a/src/spaces.cc b/src/spaces.cc
index 9f266cb..9227a87 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -726,47 +726,25 @@
   Page* top_page = AllocationTopPage();
   ASSERT(top_page->is_valid());
 
-  // Loop over the pages from the top page to the end of the space to count
-  // the number of pages to keep and find the last page to keep.
-  int free_pages = 0;
-  int pages_to_keep = 0;  // Of the free pages.
-  Page* last_page_to_keep = top_page;
-  Page* current_page = top_page->next_page();
-  // Loop over the pages to the end of the space.
-  while (current_page->is_valid()) {
-#if defined(ANDROID)
-    // Free all chunks if possible
-#else
-    // Advance last_page_to_keep every other step to end up at the midpoint.
-    if ((free_pages & 0x1) == 1) {
-      pages_to_keep++;
-      last_page_to_keep = last_page_to_keep->next_page();
-    }
-#endif
-    free_pages++;
-    current_page = current_page->next_page();
+  // Count the number of pages we would like to free.
+  int pages_to_free = 0;
+  for (Page* p = top_page->next_page(); p->is_valid(); p = p->next_page()) {
+    pages_to_free++;
   }
 
-  // Free pages after last_page_to_keep, and adjust the next_page link.
-  Page* p = MemoryAllocator::FreePages(last_page_to_keep->next_page());
-  MemoryAllocator::SetNextPage(last_page_to_keep, p);
+  // Free pages after top_page.
+  Page* p = MemoryAllocator::FreePages(top_page->next_page());
+  MemoryAllocator::SetNextPage(top_page, p);
 
-  // Since pages are only freed in whole chunks, we may have kept more
-  // than pages_to_keep.  Count the extra pages and cache the new last
-  // page in the space.
-  last_page_ = last_page_to_keep;
-  while (p->is_valid()) {
-    pages_to_keep++;
+  // Find out how many pages we failed to free and update last_page_.
+  // Please note pages can only be freed in whole chunks.
+  last_page_ = top_page;
+  for (Page* p = top_page->next_page(); p->is_valid(); p = p->next_page()) {
+    pages_to_free--;
     last_page_ = p;
-    p = p->next_page();
   }
 
-  // The difference between free_pages and pages_to_keep is the number of
-  // pages actually freed.
-  ASSERT(pages_to_keep <= free_pages);
-  int bytes_freed = (free_pages - pages_to_keep) * Page::kObjectAreaSize;
-  accounting_stats_.ShrinkSpace(bytes_freed);
-
+  accounting_stats_.ShrinkSpace(pages_to_free * Page::kObjectAreaSize);
   ASSERT(Capacity() == CountTotalPages() * Page::kObjectAreaSize);
 }
 
@@ -884,8 +862,6 @@
 
   ASSERT(initial_semispace_capacity <= maximum_semispace_capacity);
   ASSERT(IsPowerOf2(maximum_semispace_capacity));
-  maximum_capacity_ = maximum_semispace_capacity;
-  capacity_ = initial_semispace_capacity;
 
   // Allocate and setup the histogram arrays if necessary.
 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
@@ -898,15 +874,17 @@
 #undef SET_NAME
 #endif
 
-  ASSERT(size == 2 * maximum_capacity_);
+  ASSERT(size == 2 * maximum_semispace_capacity);
   ASSERT(IsAddressAligned(start, size, 0));
 
-  if (!to_space_.Setup(start, capacity_, maximum_capacity_)) {
+  if (!to_space_.Setup(start,
+                       initial_semispace_capacity,
+                       maximum_semispace_capacity)) {
     return false;
   }
-  if (!from_space_.Setup(start + maximum_capacity_,
-                         capacity_,
-                         maximum_capacity_)) {
+  if (!from_space_.Setup(start + maximum_semispace_capacity,
+                         initial_semispace_capacity,
+                         maximum_semispace_capacity)) {
     return false;
   }
 
@@ -938,7 +916,6 @@
 #endif
 
   start_ = NULL;
-  capacity_ = 0;
   allocation_info_.top = NULL;
   allocation_info_.limit = NULL;
   mc_forwarding_info_.top = NULL;
@@ -975,12 +952,11 @@
 
 
 bool NewSpace::Grow() {
-  ASSERT(capacity_ < maximum_capacity_);
+  ASSERT(Capacity() < MaximumCapacity());
   // TODO(1240712): Failure to double the from space can result in
   // semispaces of different sizes.  In the event of that failure, the
   // to space doubling should be rolled back before returning false.
   if (!to_space_.Grow() || !from_space_.Grow()) return false;
-  capacity_ = to_space_.Capacity() + from_space_.Capacity();
   allocation_info_.limit = to_space_.high();
   ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
   return true;
@@ -1104,10 +1080,9 @@
 
 bool SemiSpace::Grow() {
   // Commit 50% extra space but only up to maximum capacity.
-  int extra = RoundUp(capacity_ / 2, OS::AllocateAlignment());
-  if (capacity_ + extra > maximum_capacity_) {
-    extra = maximum_capacity_ - capacity_;
-  }
+  int maximum_extra = maximum_capacity_ - capacity_;
+  int extra = Min(RoundUp(capacity_ / 2, OS::AllocateAlignment()),
+                  maximum_extra);
   if (!MemoryAllocator::CommitBlock(high(), extra, executable())) {
     return false;
   }
diff --git a/src/spaces.h b/src/spaces.h
index 4760a42..f12e0e4 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -1054,6 +1054,10 @@
   // Returns the current capacity of the semi space.
   int Capacity() { return capacity_; }
 
+  // Returns the maximum capacity of the semi space.
+  int MaximumCapacity() { return maximum_capacity_; }
+
+
  private:
   // The current and maximum capacity of the space.
   int capacity_;
@@ -1164,12 +1168,18 @@
   // Return the allocated bytes in the active semispace.
   virtual int Size() { return top() - bottom(); }
   // Return the current capacity of a semispace.
-  int Capacity() { return capacity_; }
+  int Capacity() {
+    ASSERT(to_space_.Capacity() == from_space_.Capacity());
+    return to_space_.Capacity();
+  }
   // Return the available bytes without growing in the active semispace.
   int Available() { return Capacity() - Size(); }
 
   // Return the maximum capacity of a semispace.
-  int MaximumCapacity() { return maximum_capacity_; }
+  int MaximumCapacity() {
+    ASSERT(to_space_.MaximumCapacity() == from_space_.MaximumCapacity());
+    return to_space_.MaximumCapacity();
+  }
 
   // Return the address of the allocation pointer in the active semispace.
   Address top() { return allocation_info_.top; }
@@ -1275,10 +1285,6 @@
   }
 
  private:
-  // The current and maximum capacities of a semispace.
-  int capacity_;
-  int maximum_capacity_;
-
   // The semispaces.
   SemiSpace to_space_;
   SemiSpace from_space_;
@@ -1574,7 +1580,7 @@
   // Give a fixed sized block of memory to the space's free list.
   void Free(Address start) {
     free_list_.Free(start);
-    accounting_stats_.DeallocateBytes(Map::kSize);
+    accounting_stats_.DeallocateBytes(object_size_in_bytes_);
   }
 
   // Prepares for a mark-compact GC.
diff --git a/src/v8-counters.h b/src/v8-counters.h
index a62cd74..43cd5e3 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -139,6 +139,8 @@
   SC(named_store_global_inline_miss, V8.NamedStoreGlobalInlineMiss) \
   SC(call_global_inline, V8.CallGlobalInline)                       \
   SC(call_global_inline_miss, V8.CallGlobalInlineMiss)              \
+  SC(constructed_objects, V8.ConstructedObjects)                    \
+  SC(constructed_objects_runtime, V8.ConstructedObjectsRuntime)     \
   SC(for_in, V8.ForIn)                                              \
   SC(enum_cache_hits, V8.EnumCacheHits)                             \
   SC(enum_cache_misses, V8.EnumCacheMisses)                         \
diff --git a/src/v8natives.js b/src/v8natives.js
index 841c920..be92347 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -46,12 +46,16 @@
 
 // Helper function used to install functions on objects.
 function InstallFunctions(object, attributes, functions) {
+  if (functions.length >= 8) {
+    %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1);
+  }
   for (var i = 0; i < functions.length; i += 2) {
     var key = functions[i];
     var f = functions[i + 1];
     %FunctionSetName(f, key);
     %SetProperty(object, key, f, attributes);
   }
+  %TransformToFastProperties(object);
 }
 
 // Emulates JSC by installing functions on a hidden prototype that
@@ -453,9 +457,11 @@
 // ----------------------------------------------------------------------------
 
 function SetupNumber() {
+  %OptimizeObjectForAddingMultipleProperties($Number.prototype, 8);
   // Setup the constructor property on the Number prototype object.
   %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
 
+  %OptimizeObjectForAddingMultipleProperties($Number, 5);
   // ECMA-262 section 15.7.3.1.
   %SetProperty($Number,
                "MAX_VALUE",
@@ -479,6 +485,7 @@
                "POSITIVE_INFINITY",
                1/0,
                DONT_ENUM | DONT_DELETE | READ_ONLY);
+  %TransformToFastProperties($Number);
 
   // Setup non-enumerable functions on the Number prototype object.
   InstallFunctions($Number.prototype, DONT_ENUM, $Array(
diff --git a/src/version.cc b/src/version.cc
index 7bc52a8..26b009c 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // cannot be changed without changing the SCons build script.
 #define MAJOR_VERSION     1
 #define MINOR_VERSION     3
-#define BUILD_NUMBER      4
+#define BUILD_NUMBER      5
 #define PATCH_LEVEL       0
 #define CANDIDATE_VERSION false
 
diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h
index 196f2ee..f51a3ea 100644
--- a/src/x64/assembler-x64-inl.h
+++ b/src/x64/assembler-x64-inl.h
@@ -228,43 +228,47 @@
 
 
 bool RelocInfo::IsCallInstruction() {
-  UNIMPLEMENTED();  // IA32 code below.
-  return *pc_ == 0xE8;
+  // The recognized call sequence is:
+  //  movq(kScratchRegister, immediate64); call(kScratchRegister);
+  // It only needs to be distinguished from a return sequence
+  //  movq(rsp, rbp); pop(rbp); ret(n); int3 *6
+  // The 11th byte is int3 (0xCC) in the return sequence and
+  // REX.WB (0x48+register bit) for the call sequence.
+  return pc_[10] != 0xCC;
 }
 
 
 Address RelocInfo::call_address() {
-  UNIMPLEMENTED();  // IA32 code below.
   ASSERT(IsCallInstruction());
-  return Assembler::target_address_at(pc_ + 1);
+  return Assembler::target_address_at(
+      pc_ + Assembler::kPatchReturnSequenceAddressOffset);
 }
 
 
 void RelocInfo::set_call_address(Address target) {
-  UNIMPLEMENTED();  // IA32 code below.
   ASSERT(IsCallInstruction());
-  Assembler::set_target_address_at(pc_ + 1, target);
+  Assembler::set_target_address_at(
+      pc_ + Assembler::kPatchReturnSequenceAddressOffset,
+      target);
 }
 
 
 Object* RelocInfo::call_object() {
-  UNIMPLEMENTED();  // IA32 code below.
   ASSERT(IsCallInstruction());
   return *call_object_address();
 }
 
 
 void RelocInfo::set_call_object(Object* target) {
-  UNIMPLEMENTED();  // IA32 code below.
   ASSERT(IsCallInstruction());
   *call_object_address() = target;
 }
 
 
 Object** RelocInfo::call_object_address() {
-  UNIMPLEMENTED();  // IA32 code below.
   ASSERT(IsCallInstruction());
-  return reinterpret_cast<Object**>(pc_ + 1);
+  return reinterpret_cast<Object**>(
+      pc_ + Assembler::kPatchReturnSequenceAddressOffset);
 }
 
 // -----------------------------------------------------------------------------
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index b4fd678..a02557e 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -178,6 +178,13 @@
 }
 
 
+void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
+  // Patch the code at the current address with the supplied instructions.
+  for (int i = 0; i < instruction_count; i++) {
+    *(pc_ + i) = *(instructions + i);
+  }
+}
+
 // -----------------------------------------------------------------------------
 // Implementation of Operand
 
@@ -437,21 +444,43 @@
 }
 
 
-void Assembler::arithmetic_op(byte opcode, Register dst, Register src) {
+void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
-  emit_rex_64(dst, src);
+  emit_rex_64(reg, rm_reg);
   emit(opcode);
-  emit_modrm(dst, src);
+  emit_modrm(reg, rm_reg);
 }
 
 
-void Assembler::arithmetic_op_32(byte opcode, Register dst, Register src) {
+void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
-  emit_optional_rex_32(dst, src);
+  emit(0x66);
+  emit_optional_rex_32(reg, rm_reg);
   emit(opcode);
-  emit_modrm(dst, src);
+  emit_modrm(reg, rm_reg);
+}
+
+
+void Assembler::arithmetic_op_16(byte opcode,
+                                 Register reg,
+                                 const Operand& rm_reg) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0x66);
+  emit_optional_rex_32(reg, rm_reg);
+  emit(opcode);
+  emit_operand(reg, rm_reg);
+}
+
+
+void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_optional_rex_32(reg, rm_reg);
+  emit(opcode);
+  emit_modrm(reg, rm_reg);
 }
 
 
@@ -504,6 +533,47 @@
 }
 
 
+void Assembler::immediate_arithmetic_op_16(byte subcode,
+                                           Register dst,
+                                           Immediate src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0x66);  // Operand size override prefix.
+  emit_optional_rex_32(dst);
+  if (is_int8(src.value_)) {
+    emit(0x83);
+    emit_modrm(subcode, dst);
+    emit(src.value_);
+  } else if (dst.is(rax)) {
+    emit(0x05 | (subcode << 3));
+    emitl(src.value_);
+  } else {
+    emit(0x81);
+    emit_modrm(subcode, dst);
+    emitl(src.value_);
+  }
+}
+
+
+void Assembler::immediate_arithmetic_op_16(byte subcode,
+                                           const Operand& dst,
+                                           Immediate src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0x66);  // Operand size override prefix.
+  emit_optional_rex_32(dst);
+  if (is_int8(src.value_)) {
+    emit(0x83);
+    emit_operand(subcode, dst);
+    emit(src.value_);
+  } else {
+    emit(0x81);
+    emit_operand(subcode, dst);
+    emitl(src.value_);
+  }
+}
+
+
 void Assembler::immediate_arithmetic_op_32(byte subcode,
                                            Register dst,
                                            Immediate src) {
@@ -744,6 +814,14 @@
 }
 
 
+void Assembler::cmpb_al(Immediate imm8) {
+  ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit(0x3c);
+  emit(imm8.value_);
+}
+
 
 void Assembler::cpuid() {
   ASSERT(CpuFeatures::IsEnabled(CpuFeatures::CPUID));
@@ -1000,6 +1078,16 @@
 }
 
 
+void Assembler::jmp(const Operand& src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  // Opcode FF/4 m64
+  emit_optional_rex_32(src);
+  emit(0xFF);
+  emit_operand(0x4, src);
+}
+
+
 void Assembler::lea(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
@@ -1193,6 +1281,32 @@
 }
 
 
+/*
+ * Loads the ip-relative location of the src label into the target
+ * location (as a 32-bit offset sign extended to 64-bit).
+ */
+void Assembler::movl(const Operand& dst, Label* src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_optional_rex_32(dst);
+  emit(0xC7);
+  emit_operand(0, dst);
+  if (src->is_bound()) {
+    int offset = src->pos() - pc_offset() - sizeof(int32_t);
+    ASSERT(offset <= 0);
+    emitl(offset);
+  } else if (src->is_linked()) {
+    emitl(src->pos());
+    src->link_to(pc_offset() - sizeof(int32_t));
+  } else {
+    ASSERT(src->is_unused());
+    int32_t current = pc_offset();
+    emitl(current);
+    src->link_to(current);
+  }
+}
+
+
 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
   // If there is no relocation info, emit the value of the handle efficiently
   // (possibly using less that 8 bytes for the value).
@@ -1608,6 +1722,11 @@
 
 
 void Assembler::testl(Register reg, Immediate mask) {
+  // testl with a mask that fits in the low byte is exactly testb.
+  if (is_uint8(mask.value_)) {
+    testb(reg, mask);
+    return;
+  }
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
   if (reg.is(rax)) {
@@ -1623,6 +1742,11 @@
 
 
 void Assembler::testl(const Operand& op, Immediate mask) {
+  // testl with a mask that fits in the low byte is exactly testb.
+  if (is_uint8(mask.value_)) {
+    testb(op, mask);
+    return;
+  }
   EnsureSpace ensure_space(this);
   last_pc_ = pc_;
   emit_optional_rex_32(rax, op);
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 015fa68..9d602b9 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -442,8 +442,10 @@
 
   // Distance between the address of the code target in the call instruction
   // and the return address.  Checked in the debug build.
-  static const int kTargetAddrToReturnAddrDist = 3 + kPointerSize;
-
+  static const int kPatchReturnSequenceLength = 3 + kPointerSize;
+  // Distance between start of patched return sequence and the emitted address
+  // to jump to (movq = REX.W 0xB8+r.).
+  static const int kPatchReturnSequenceAddressOffset = 2;
 
   // ---------------------------------------------------------------------------
   // Code generation
@@ -496,13 +498,17 @@
   // Load a 32-bit immediate value, zero-extended to 64 bits.
   void movl(Register dst, Immediate imm32);
 
-  void movq(Register dst, const Operand& src);
-  // Sign extends immediate 32-bit value to 64 bits.
-  void movq(Register dst, Immediate x);
-  void movq(Register dst, Register src);
-
   // Move 64 bit register value to 64-bit memory location.
   void movq(const Operand& dst, Register src);
+  // Move 64 bit memory location to 64-bit register value.
+  void movq(Register dst, const Operand& src);
+  void movq(Register dst, Register src);
+  // Sign extends immediate 32-bit value to 64 bits.
+  void movq(Register dst, Immediate x);
+  // Move the offset of the label location relative to the current
+  // position (after the move) to the destination.
+  void movl(const Operand& dst, Label* src);
+
   // Move sign extended immediate to memory location.
   void movq(const Operand& dst, Immediate value);
   // New x64 instructions to load a 64-bit immediate into a register.
@@ -535,7 +541,11 @@
 
   // Arithmetics
   void addl(Register dst, Register src) {
-    arithmetic_op_32(0x03, dst, src);
+    if (dst.low_bits() == 4) {  // Forces SIB byte.
+      arithmetic_op_32(0x01, src, dst);
+    } else {
+      arithmetic_op_32(0x03, dst, src);
+    }
   }
 
   void addl(Register dst, Immediate src) {
@@ -574,10 +584,44 @@
     immediate_arithmetic_op_8(0x7, dst, src);
   }
 
+  void cmpb_al(Immediate src);
+
+  void cmpb(Register dst, Register src) {
+    arithmetic_op(0x3A, dst, src);
+  }
+
+  void cmpb(Register dst, const Operand& src) {
+    arithmetic_op(0x3A, dst, src);
+  }
+
+  void cmpb(const Operand& dst, Register src) {
+    arithmetic_op(0x38, src, dst);
+  }
+
   void cmpb(const Operand& dst, Immediate src) {
     immediate_arithmetic_op_8(0x7, dst, src);
   }
 
+  void cmpw(const Operand& dst, Immediate src) {
+    immediate_arithmetic_op_16(0x7, dst, src);
+  }
+
+  void cmpw(Register dst, Immediate src) {
+    immediate_arithmetic_op_16(0x7, dst, src);
+  }
+
+  void cmpw(Register dst, const Operand& src) {
+    arithmetic_op_16(0x3B, dst, src);
+  }
+
+  void cmpw(Register dst, Register src) {
+    arithmetic_op_16(0x3B, dst, src);
+  }
+
+  void cmpw(const Operand& dst, Register src) {
+    arithmetic_op_16(0x39, src, dst);
+  }
+
   void cmpl(Register dst, Register src) {
     arithmetic_op_32(0x3B, dst, src);
   }
@@ -794,6 +838,10 @@
     immediate_arithmetic_op_32(0x5, dst, src);
   }
 
+  void subb(Register dst, Immediate src) {
+    immediate_arithmetic_op_8(0x5, dst, src);
+  }
+
   void testb(Register reg, Immediate mask);
   void testb(const Operand& op, Immediate mask);
   void testl(Register dst, Register src);
@@ -871,6 +919,9 @@
   // Jump near absolute indirect (r64)
   void jmp(Register adr);
 
+  // Jump near absolute indirect (m64)
+  void jmp(const Operand& src);
+
   // Conditional jumps
   void j(Condition cc, Label* L);
 
@@ -1141,26 +1192,36 @@
   // AND, OR, XOR, or CMP.  The encodings of these operations are all
   // similar, differing just in the opcode or in the reg field of the
   // ModR/M byte.
-  void arithmetic_op(byte opcode, Register dst, Register src);
-  void arithmetic_op_32(byte opcode, Register dst, Register src);
+  void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
+  void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
+  void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
   void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
+  void arithmetic_op(byte opcode, Register reg, Register rm_reg);
   void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
   void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
   void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
-  // Operate on a 32-bit word in memory or register.
-  void immediate_arithmetic_op_32(byte subcode,
-                                  const Operand& dst,
-                                  Immediate src);
-  void immediate_arithmetic_op_32(byte subcode,
-                                  Register dst,
-                                  Immediate src);
   // Operate on a byte in memory or register.
   void immediate_arithmetic_op_8(byte subcode,
-                                 const Operand& dst,
-                                 Immediate src);
-  void immediate_arithmetic_op_8(byte subcode,
                                  Register dst,
                                  Immediate src);
+  void immediate_arithmetic_op_8(byte subcode,
+                                 const Operand& dst,
+                                 Immediate src);
+  // Operate on a word in memory or register.
+  void immediate_arithmetic_op_16(byte subcode,
+                                  Register dst,
+                                  Immediate src);
+  void immediate_arithmetic_op_16(byte subcode,
+                                  const Operand& dst,
+                                  Immediate src);
+  // Operate on a 32-bit word in memory or register.
+  void immediate_arithmetic_op_32(byte subcode,
+                                  Register dst,
+                                  Immediate src);
+  void immediate_arithmetic_op_32(byte subcode,
+                                  const Operand& dst,
+                                  Immediate src);
+
   // Emit machine code for a shift operation.
   void shift(Register dst, Immediate shift_amount, int subcode);
   void shift_32(Register dst, Immediate shift_amount, int subcode);
@@ -1180,6 +1241,7 @@
 
   friend class CodePatcher;
   friend class EnsureSpace;
+  friend class RegExpMacroAssemblerX64;
 
   // Code buffer:
   // The buffer into which code and relocation info are generated.
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 087aaff..6988d72 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -35,7 +35,7 @@
 #define __ ACCESS_MASM(masm)
 
 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
-  // TODO(1238487): Don't pass the function in a static variable.
+  // TODO(428): Don't pass the function in a static variable.
   ExternalReference passed = ExternalReference::builtin_passed_function();
   __ movq(kScratchRegister, passed.address(), RelocInfo::EXTERNAL_REFERENCE);
   __ movq(Operand(kScratchRegister, 0), rdi);
@@ -505,7 +505,14 @@
   Label rt_call, allocated;
   if (FLAG_inline_new) {
     Label undo_allocation;
-    // TODO(X64): Enable debugger support, using debug_step_in_fp.
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+    ExternalReference debug_step_in_fp =
+        ExternalReference::debug_step_in_fp_address();
+    __ movq(kScratchRegister, debug_step_in_fp);
+    __ cmpq(Operand(kScratchRegister, 0), Immediate(0));
+    __ j(not_equal, &rt_call);
+#endif
 
     // Verified that the constructor is a JSFunction.
     // Load the initial map and verify that it is in fact a map.
@@ -585,12 +592,16 @@
     // rax: initial map
     // rbx: JSObject
     // rdi: start of next object
+    // Calculate total properties described map.
     __ movzxbq(rdx, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset));
-    __ movzxbq(rcx, FieldOperand(rax, Map::kInObjectPropertiesOffset));
+    __ movzxbq(rcx, FieldOperand(rax, Map::kPreAllocatedPropertyFieldsOffset));
+    __ addq(rdx, rcx);
     // Calculate unused properties past the end of the in-object properties.
+    __ movzxbq(rcx, FieldOperand(rax, Map::kInObjectPropertiesOffset));
     __ subq(rdx, rcx);
     // Done if no extra properties are to be allocated.
     __ j(zero, &allocated);
+    __ Assert(positive, "Property allocation count failed.");
 
     // Scale the number of elements by pointer size and add the header for
     // FixedArrays to the start of the next object calculation from above.
@@ -726,6 +737,7 @@
   __ pop(rcx);
   __ lea(rsp, Operand(rsp, rbx, times_4, 1 * kPointerSize));  // 1 ~ receiver
   __ push(rcx);
+  __ IncrementCounter(&Counters::constructed_objects, 1);
   __ ret(0);
 }
 
@@ -823,10 +835,8 @@
   // Invoke the code.
   if (is_construct) {
     // Expects rdi to hold function pointer.
-    __ movq(kScratchRegister,
-            Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
+    __ Call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
             RelocInfo::CODE_TARGET);
-    __ call(kScratchRegister);
   } else {
     ParameterCount actual(rax);
     // Function must be in rdi.
diff --git a/src/x64/cfg-x64.cc b/src/x64/cfg-x64.cc
index 8d01ed2..34ddbbf 100644
--- a/src/x64/cfg-x64.cc
+++ b/src/x64/cfg-x64.cc
@@ -114,8 +114,8 @@
   int count = CfgGlobals::current()->fun()->scope()->num_parameters();
   __ ret((count + 1) * kPointerSize);
   // Add padding that will be overwritten by a debugger breakpoint.
-  // "movq rsp, rbp; pop rbp" has length 5.  "ret k" has length 2.
-  const int kPadding = Debug::kX64JSReturnSequenceLength - 5 - 2;
+  // "movq rsp, rbp; pop rbp" has length 4.  "ret k" has length 3.
+  const int kPadding = Debug::kX64JSReturnSequenceLength - 4 - 3;
   for (int i = 0; i < kPadding; ++i) {
     __ int3();
   }
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index b3df929..7fe6ebd 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -500,17 +500,19 @@
   return_value->ToRegister(rax);
 
   // Add a label for checking the size of the code used for returning.
+#ifdef DEBUG
   Label check_exit_codesize;
   masm_->bind(&check_exit_codesize);
+#endif
 
   // Leave the frame and return popping the arguments and the
   // receiver.
   frame_->Exit();
   masm_->ret((scope_->num_parameters() + 1) * kPointerSize);
   // Add padding that will be overwritten by a debugger breakpoint.
-  // frame_->Exit() generates "movq rsp, rbp; pop rbp" length 5.
-  // "ret k" has length 2.
-  const int kPadding = Debug::kX64JSReturnSequenceLength - 5 - 2;
+  // frame_->Exit() generates "movq rsp, rbp; pop rbp; ret k"
+  // with length 7 (3 + 1 + 3).
+  const int kPadding = Debug::kX64JSReturnSequenceLength - 7;
   for (int i = 0; i < kPadding; ++i) {
     masm_->int3();
   }
@@ -3084,26 +3086,19 @@
                                                   is_increment);
     }
 
-    Result tmp = allocator_->AllocateWithoutSpilling();
-    ASSERT(kSmiTagMask == 1 && kSmiTag == 0);
-    __ movl(tmp.reg(), Immediate(kSmiTagMask));
-    // Smi test.
     __ movq(kScratchRegister, new_value.reg());
     if (is_increment) {
       __ addl(kScratchRegister, Immediate(Smi::FromInt(1)));
     } else {
       __ subl(kScratchRegister, Immediate(Smi::FromInt(1)));
     }
-    // deferred->Branch(overflow);
-    __ cmovl(overflow, kScratchRegister, tmp.reg());
-    __ testl(kScratchRegister, tmp.reg());
-    tmp.Unuse();
+    // Smi test.
+    deferred->Branch(overflow);
+    __ testl(kScratchRegister, Immediate(kSmiTagMask));
     deferred->Branch(not_zero);
     __ movq(new_value.reg(), kScratchRegister);
-
     deferred->BindExit();
 
-
     // Postfix: store the old value in the allocated slot under the
     // reference.
     if (is_postfix) frame_->SetElementAt(target.size(), &old_value);
@@ -5738,6 +5733,13 @@
   ASSERT(cgen_->HasValidEntryRegisters());
   ASSERT(!is_illegal());
   MacroAssembler* masm = cgen_->masm();
+
+  // Record the source position for the property load.
+  Property* property = expression_->AsProperty();
+  if (property != NULL) {
+    cgen_->CodeForSourcePosition(property->position());
+  }
+
   switch (type_) {
     case SLOT: {
       Comment cmnt(masm, "[ Load from Slot");
@@ -6957,17 +6959,12 @@
   Label throw_out_of_memory_exception;
   Label throw_normal_exception;
 
-  // Call into the runtime system. Collect garbage before the call if
-  // running with --gc-greedy set.
-  if (FLAG_gc_greedy) {
-    Failure* failure = Failure::RetryAfterGC(0);
-    __ movq(rax, failure, RelocInfo::NONE);
-  }
+  // Call into the runtime system.
   GenerateCore(masm,
                &throw_normal_exception,
                &throw_out_of_memory_exception,
                frame_type,
-               FLAG_gc_greedy,
+               false,
                false);
 
   // Do space-specific GC and retry runtime call.
@@ -7536,11 +7533,10 @@
       // Reserve space for converted numbers.
       __ subq(rsp, Immediate(2 * kPointerSize));
 
-      bool use_sse3 = CpuFeatures::IsSupported(CpuFeatures::SSE3);
-      if (use_sse3) {
+      if (use_sse3_) {
         // Truncate the operands to 32-bit integers and check for
         // exceptions in doing so.
-         CpuFeatures::Scope scope(CpuFeatures::SSE3);
+        CpuFeatures::Scope scope(CpuFeatures::SSE3);
         __ fisttp_s(Operand(rsp, 0 * kPointerSize));
         __ fisttp_s(Operand(rsp, 1 * kPointerSize));
         __ fnstsw_ax();
@@ -7625,7 +7621,7 @@
       // the runtime system.
       __ bind(&operand_conversion_failure);
       __ addq(rsp, Immediate(2 * kPointerSize));
-      if (use_sse3) {
+      if (use_sse3_) {
         // If we've used the SSE3 instructions for truncating the
         // floating point values to integers and it failed, we have a
         // pending #IA exception. Clear it.
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index b1c61d8..bfdff56 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -299,14 +299,9 @@
 #endif
 
   static void SetFunctionInfo(Handle<JSFunction> fun,
-                              int length,
-                              int function_token_position,
-                              int start_position,
-                              int end_position,
-                              bool is_expression,
+                              FunctionLiteral* lit,
                               bool is_toplevel,
-                              Handle<Script> script,
-                              Handle<String> inferred_name);
+                              Handle<Script> script);
 
   // Accessors
   MacroAssembler* masm() { return masm_; }
@@ -624,6 +619,7 @@
                       OverwriteMode mode,
                       GenericBinaryFlags flags)
       : op_(op), mode_(mode), flags_(flags) {
+    use_sse3_ = CpuFeatures::IsSupported(CpuFeatures::SSE3);
     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
   }
 
@@ -633,6 +629,7 @@
   Token::Value op_;
   OverwriteMode mode_;
   GenericBinaryFlags flags_;
+  bool use_sse3_;
 
   const char* GetName();
 
@@ -645,17 +642,19 @@
   }
 #endif
 
-  // Minor key encoding in 16 bits FOOOOOOOOOOOOOMM.
+  // Minor key encoding in 16 bits FSOOOOOOOOOOOOMM.
   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
-  class OpBits: public BitField<Token::Value, 2, 13> {};
+  class OpBits: public BitField<Token::Value, 2, 12> {};
+  class SSE3Bits: public BitField<bool, 14, 1> {};
   class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {};
 
   Major MajorKey() { return GenericBinaryOp; }
   int MinorKey() {
     // Encode the parameters in a unique 16 bit value.
     return OpBits::encode(op_)
-           | ModeBits::encode(mode_)
-           | FlagBits::encode(flags_);
+        | ModeBits::encode(mode_)
+        | FlagBits::encode(flags_)
+        | SSE3Bits::encode(use_sse3_);
   }
   void Generate(MacroAssembler* masm);
 };
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
index 177eb90..f2bb62b 100644
--- a/src/x64/debug-x64.cc
+++ b/src/x64/debug-x64.cc
@@ -39,60 +39,176 @@
 
 bool Debug::IsDebugBreakAtReturn(v8::internal::RelocInfo* rinfo) {
   ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
-  // 11th byte of patch is 0x49, 11th byte of JS return is 0xCC (int3).
+  // 11th byte of patch is 0x49 (REX.WB byte of computed jump/call to r10),
+  // 11th byte of JS return is 0xCC (int3).
   ASSERT(*(rinfo->pc() + 10) == 0x49 || *(rinfo->pc() + 10) == 0xCC);
-  return (*(rinfo->pc() + 10) == 0x49);
+  return (*(rinfo->pc() + 10) != 0xCC);
 }
 
+#define __ ACCESS_MASM(masm)
+
+static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
+                                          RegList pointer_regs,
+                                          bool convert_call_to_jmp) {
+  // Save the content of all general purpose registers in memory. This copy in
+  // memory is later pushed onto the JS expression stack for the fake JS frame
+  // generated and also to the C frame generated on top of that. In the JS
+  // frame ONLY the registers containing pointers will be pushed on the
+  // expression stack. This causes the GC to update these pointers so that
+  // they will have the correct value when returning from the debugger.
+  __ SaveRegistersToMemory(kJSCallerSaved);
+
+  // Enter an internal frame.
+  __ EnterInternalFrame();
+
+  // Store the registers containing object pointers on the expression stack to
+  // make sure that these are correctly updated during GC.
+  __ PushRegistersFromMemory(pointer_regs);
+
+#ifdef DEBUG
+  __ RecordComment("// Calling from debug break to runtime - come in - over");
+#endif
+  __ xor_(rax, rax);  // No arguments (argc == 0).
+  __ movq(rbx, ExternalReference::debug_break());
+
+  CEntryDebugBreakStub ceb;
+  __ CallStub(&ceb);
+
+  // Restore the register values containing object pointers from the expression
+  // stack in the reverse order as they where pushed.
+  __ PopRegistersToMemory(pointer_regs);
+
+  // Get rid of the internal frame.
+  __ LeaveInternalFrame();
+
+  // If this call did not replace a call but patched other code then there will
+  // be an unwanted return address left on the stack. Here we get rid of that.
+  if (convert_call_to_jmp) {
+    __ pop(rax);
+  }
+
+  // Finally restore all registers.
+  __ RestoreRegistersFromMemory(kJSCallerSaved);
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference(Debug_Address::AfterBreakTarget());
+  __ movq(kScratchRegister, after_break_target);
+  __ jmp(Operand(kScratchRegister, 0));
+}
+
+
 void Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // Register state for keyed IC call call (from ic-x64.cc)
+  // ----------- S t a t e -------------
+  //  -- rax: number of arguments
+  // -----------------------------------
+  // The number of arguments in rax is not smi encoded.
+  Generate_DebugBreakCallHelper(masm, 0, false);
 }
 
+
 void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // Register state just before return from JS function (from codegen-x64.cc).
+  // rax is the actual number of arguments not encoded as a smi, see comment
+  // above IC call.
+  // ----------- S t a t e -------------
+  //  -- rax: number of arguments
+  // -----------------------------------
+  // The number of arguments in rax is not smi encoded.
+  Generate_DebugBreakCallHelper(masm, 0, false);
 }
 
+
 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // Register state for keyed IC load call (from ic-x64.cc).
+  // ----------- S t a t e -------------
+  //  No registers used on entry.
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, 0, false);
 }
 
+
 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // Register state for keyed IC load call (from ic-x64.cc).
+  // ----------- S t a t e -------------
+  //  -- rax    : value
+  // -----------------------------------
+  // Register rax contains an object that needs to be pushed on the
+  // expression stack of the fake JS frame.
+  Generate_DebugBreakCallHelper(masm, rax.bit(), false);
 }
 
+
 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // Register state for IC load call (from ic-x64.cc).
+  // ----------- S t a t e -------------
+  //  -- rcx    : name
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, rcx.bit(), false);
 }
 
+
 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // Register state just before return from JS function (from codegen-x64.cc).
+  // ----------- S t a t e -------------
+  //  -- rax: return value
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, rax.bit(), true);
 }
 
+
 void Debug::GenerateReturnDebugBreakEntry(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // OK to clobber rbx as we are returning from a JS function through the code
+  // generated by CodeGenerator::GenerateReturnSequence()
+  ExternalReference debug_break_return =
+      ExternalReference(Debug_Address::DebugBreakReturn());
+  __ movq(rbx, debug_break_return);
+  __ movq(rbx, Operand(rbx, 0));
+  __ addq(rbx, Immediate(Code::kHeaderSize - kHeapObjectTag));
+  __ jmp(rbx);
 }
 
+
 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // REgister state for IC store call (from ic-x64.cc).
+  // ----------- S t a t e -------------
+  //  -- rax    : value
+  //  -- rcx    : name
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), false);
 }
 
+
 void Debug::GenerateStubNoRegistersDebugBreak(MacroAssembler* masm) {
-  masm->int3();  // UNIMPLEMENTED
+  // Register state for stub CallFunction (from CallFunctionStub in ic-x64.cc).
+  // ----------- S t a t e -------------
+  //  No registers used on entry.
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, 0, false);
 }
 
+
+#undef __
+
+
 void BreakLocationIterator::ClearDebugBreakAtReturn() {
-  // TODO(X64): Implement this when we start setting Debug breaks.
-  UNIMPLEMENTED();
+  rinfo()->PatchCode(original_rinfo()->pc(),
+                     Debug::kX64JSReturnSequenceLength);
 }
 
+
 bool BreakLocationIterator::IsDebugBreakAtReturn()  {
-  // TODO(X64): Implement this when we start setting Debug breaks.
-  UNIMPLEMENTED();
-  return false;
+  return Debug::IsDebugBreakAtReturn(rinfo());
 }
 
+
 void BreakLocationIterator::SetDebugBreakAtReturn()  {
-  UNIMPLEMENTED();
+  ASSERT(Debug::kX64JSReturnSequenceLength >= Debug::kX64CallInstructionLength);
+  rinfo()->PatchCodeWithCall(Debug::debug_break_return_entry()->entry(),
+      Debug::kX64JSReturnSequenceLength - Debug::kX64CallInstructionLength);
 }
 
 #endif  // ENABLE_DEBUGGER_SUPPORT
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 86008eb..1c74a44 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -167,7 +167,7 @@
   // Arguments are address of start of call sequence that called
   // the IC,
   Address test_instruction_address =
-      address + Assembler::kTargetAddrToReturnAddrDist;
+      address + Assembler::kPatchReturnSequenceLength;
   // The keyed load has a fast inlined case if the IC call instruction
   // is immediately followed by a test instruction.
   if (*test_instruction_address != kTestEaxByte) return false;
@@ -845,7 +845,7 @@
 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
   // The address of the instruction following the call.
   Address test_instruction_address =
-      address + Assembler::kTargetAddrToReturnAddrDist;
+      address + Assembler::kPatchReturnSequenceLength;
   // If the instruction following the call is not a test eax, nothing
   // was inlined.
   if (*test_instruction_address != kTestEaxByte) return false;
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 2219a5a..8f8398d 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -262,8 +262,7 @@
 
 void MacroAssembler::CallStub(CodeStub* stub) {
   ASSERT(allow_stub_calls());  // calls are not allowed in some stubs
-  movq(kScratchRegister, stub->GetCode(), RelocInfo::CODE_TARGET);
-  call(kScratchRegister);
+  Call(stub->GetCode(), RelocInfo::CODE_TARGET);
 }
 
 
@@ -495,7 +494,6 @@
 
 
 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
-  WriteRecordedPositions();
   ASSERT(RelocInfo::IsCodeTarget(rmode));
   movq(kScratchRegister, code_object, rmode);
 #ifdef DEBUG
@@ -504,7 +502,7 @@
 #endif
   jmp(kScratchRegister);
 #ifdef DEBUG
-  ASSERT_EQ(kTargetAddrToReturnAddrDist,
+  ASSERT_EQ(kPatchReturnSequenceLength,
             SizeOfCodeGeneratedSince(&target) + kPointerSize);
 #endif
 }
@@ -523,8 +521,8 @@
 
 
 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
-  WriteRecordedPositions();
   ASSERT(RelocInfo::IsCodeTarget(rmode));
+  WriteRecordedPositions();
   movq(kScratchRegister, code_object, rmode);
 #ifdef DEBUG
   // Patch target is kPointer size bytes *before* target label.
@@ -533,7 +531,7 @@
 #endif
   call(kScratchRegister);
 #ifdef DEBUG
-  ASSERT_EQ(kTargetAddrToReturnAddrDist,
+  ASSERT_EQ(kPatchReturnSequenceLength,
             SizeOfCodeGeneratedSince(&target) + kPointerSize);
 #endif
 }
@@ -799,7 +797,7 @@
         Bootstrapper::FixupFlagsIsPCRelative::encode(false) |
         Bootstrapper::FixupFlagsUseCodeObject::encode(false);
     Unresolved entry =
-        { pc_offset() - kTargetAddrToReturnAddrDist, flags, name };
+        { pc_offset() - kPatchReturnSequenceLength, flags, name };
     unresolved_.Add(entry);
   }
 }
@@ -859,12 +857,11 @@
       movq(rdx, code_register);
     }
 
-    movq(kScratchRegister, adaptor, RelocInfo::CODE_TARGET);
     if (flag == CALL_FUNCTION) {
-      call(kScratchRegister);
+      Call(adaptor, RelocInfo::CODE_TARGET);
       jmp(done);
     } else {
-      jmp(kScratchRegister);
+      Jump(adaptor, RelocInfo::CODE_TARGET);
     }
     bind(&invoke);
   }
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 209aa2d..1e38d6d 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -25,3 +25,1277 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#include "v8.h"
+#include "serialize.h"
+#include "unicode.h"
+#include "log.h"
+#include "ast.h"
+#include "regexp-stack.h"
+#include "macro-assembler.h"
+#include "regexp-macro-assembler.h"
+#include "x64/macro-assembler-x64.h"
+#include "x64/regexp-macro-assembler-x64.h"
+
+namespace v8 {
+namespace internal {
+
+/*
+ * This assembler uses the following register assignment convention
+ * - rdx : currently loaded character(s) as ASCII or UC16. Must be loaded using
+ *         LoadCurrentCharacter before using any of the dispatch methods.
+ * - rdi : current position in input, as negative offset from end of string.
+ *         Please notice that this is the byte offset, not the character
+ *         offset! Is always a 32-bit signed (negative) offset, but must be
+ *         maintained sign-extended to 64 bits, since it is used as index.
+ * - rsi : end of input (points to byte after last character in input),
+ *         so that rsi+rdi points to the current character.
+ * - rbp : frame pointer. Used to access arguments, local variables and
+ *         RegExp registers.
+ * - rsp : points to tip of C stack.
+ * - rcx : points to tip of backtrack stack. The backtrack stack contains
+ *         only 32-bit values. Most are offsets from some base (e.g., character
+ *         positions from end of string or code location from Code* pointer).
+ * - r8  : code object pointer. Used to convert between absolute and
+ *         code-object-relative addresses.
+ *
+ * The registers rax, rbx, rcx, r9 and r11 are free to use for computations.
+ * If changed to use r12+, they should be saved as callee-save registers.
+ *
+ * Each call to a C++ method should retain these registers.
+ *
+ * The stack will have the following content, in some order, indexable from the
+ * frame pointer (see, e.g., kStackHighEnd):
+ *    - stack_area_base       (High end of the memory area to use as
+ *                             backtracking stack)
+ *    - at_start              (if 1, start at start of string, if 0, don't)
+ *    - int* capture_array    (int[num_saved_registers_], for output).
+ *    - end of input          (Address of end of string)
+ *    - start of input        (Address of first character in string)
+ *    - String** input_string (location of a handle containing the string)
+ *    - return address
+ *    - backup of callee save registers (rbx, possibly rsi and rdi).
+ *    - Offset of location before start of input (effectively character
+ *      position -1). Used to initialize capture registers to a non-position.
+ *    - register 0  rbp[-n]   (Only positions must be stored in the first
+ *    - register 1  rbp[-n-8]  num_saved_registers_ registers)
+ *    - ...
+ *
+ * The first num_saved_registers_ registers are initialized to point to
+ * "character -1" in the string (i.e., char_size() bytes before the first
+ * character of the string). The remaining registers starts out uninitialized.
+ *
+ * The first seven values must be provided by the calling code by
+ * calling the code's entry address cast to a function pointer with the
+ * following signature:
+ * int (*match)(String* input_string,
+ *              Address start,
+ *              Address end,
+ *              int* capture_output_array,
+ *              bool at_start,
+ *              byte* stack_area_base)
+ */
+
+#define __ ACCESS_MASM(masm_)
+
+RegExpMacroAssemblerX64::RegExpMacroAssemblerX64(
+    Mode mode,
+    int registers_to_save)
+    : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
+      code_relative_fixup_positions_(4),
+      mode_(mode),
+      num_registers_(registers_to_save),
+      num_saved_registers_(registers_to_save),
+      entry_label_(),
+      start_label_(),
+      success_label_(),
+      backtrack_label_(),
+      exit_label_() {
+  __ jmp(&entry_label_);   // We'll write the entry code when we know more.
+  __ bind(&start_label_);  // And then continue from here.
+}
+
+
+RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() {
+  delete masm_;
+  // Unuse labels in case we throw away the assembler without calling GetCode.
+  entry_label_.Unuse();
+  start_label_.Unuse();
+  success_label_.Unuse();
+  backtrack_label_.Unuse();
+  exit_label_.Unuse();
+  check_preempt_label_.Unuse();
+  stack_overflow_label_.Unuse();
+}
+
+
+int RegExpMacroAssemblerX64::stack_limit_slack()  {
+  return RegExpStack::kStackLimitSlack;
+}
+
+
+void RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) {
+  if (by != 0) {
+    Label inside_string;
+    __ addq(rdi, Immediate(by * char_size()));
+  }
+}
+
+
+void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) {
+  ASSERT(reg >= 0);
+  ASSERT(reg < num_registers_);
+  if (by != 0) {
+    __ addq(register_location(reg), Immediate(by));
+  }
+}
+
+
+void RegExpMacroAssemblerX64::Backtrack() {
+  CheckPreemption();
+  // Pop Code* offset from backtrack stack, add Code* and jump to location.
+  Pop(rbx);
+  __ addq(rbx, code_object_pointer());
+  __ jmp(rbx);
+}
+
+
+void RegExpMacroAssemblerX64::Bind(Label* label) {
+  __ bind(label);
+}
+
+
+void RegExpMacroAssemblerX64::CheckCharacter(uint32_t c, Label* on_equal) {
+  __ cmpl(current_character(), Immediate(c));
+  BranchOrBacktrack(equal, on_equal);
+}
+
+
+void RegExpMacroAssemblerX64::CheckCharacterGT(uc16 limit, Label* on_greater) {
+  __ cmpl(current_character(), Immediate(limit));
+  BranchOrBacktrack(greater, on_greater);
+}
+
+
+void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) {
+  Label not_at_start;
+  // Did we start the match at the start of the string at all?
+  __ cmpb(Operand(rbp, kAtStart), Immediate(0));
+  BranchOrBacktrack(equal, &not_at_start);
+  // If we did, are we still at the start of the input?
+  __ lea(rax, Operand(rsi, rdi, times_1, 0));
+  __ cmpq(rax, Operand(rbp, kInputStart));
+  BranchOrBacktrack(equal, on_at_start);
+  __ bind(&not_at_start);
+}
+
+
+void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) {
+  // Did we start the match at the start of the string at all?
+  __ cmpb(Operand(rbp, kAtStart), Immediate(0));
+  BranchOrBacktrack(equal, on_not_at_start);
+  // If we did, are we still at the start of the input?
+  __ lea(rax, Operand(rsi, rdi, times_1, 0));
+  __ cmpq(rax, Operand(rbp, kInputStart));
+  BranchOrBacktrack(not_equal, on_not_at_start);
+}
+
+
+void RegExpMacroAssemblerX64::CheckCharacterLT(uc16 limit, Label* on_less) {
+  __ cmpl(current_character(), Immediate(limit));
+  BranchOrBacktrack(less, on_less);
+}
+
+
+void RegExpMacroAssemblerX64::CheckCharacters(Vector<const uc16> str,
+                                              int cp_offset,
+                                              Label* on_failure,
+                                              bool check_end_of_string) {
+  int byte_length = str.length() * char_size();
+  int byte_offset = cp_offset * char_size();
+  if (check_end_of_string) {
+    // Check that there are at least str.length() characters left in the input.
+    __ cmpl(rdi, Immediate(-(byte_offset + byte_length)));
+    BranchOrBacktrack(greater, on_failure);
+  }
+
+  if (on_failure == NULL) {
+    // Instead of inlining a backtrack, (re)use the global backtrack target.
+    on_failure = &backtrack_label_;
+  }
+
+  // TODO(lrn): Test multiple characters at a time by loading 4 or 8 bytes
+  // at a time.
+  for (int i = 0; i < str.length(); i++) {
+    if (mode_ == ASCII) {
+      __ cmpb(Operand(rsi, rdi, times_1, byte_offset + i),
+              Immediate(static_cast<int8_t>(str[i])));
+    } else {
+      ASSERT(mode_ == UC16);
+      __ cmpw(Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)),
+              Immediate(str[i]));
+    }
+    BranchOrBacktrack(not_equal, on_failure);
+  }
+}
+
+
+void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
+  Label fallthrough;
+  __ cmpl(rdi, Operand(backtrack_stackpointer(), 0));
+  __ j(not_equal, &fallthrough);
+  Drop();
+  BranchOrBacktrack(no_condition, on_equal);
+  __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
+    int start_reg,
+    Label* on_no_match) {
+  Label fallthrough;
+  __ movq(rdx, register_location(start_reg));  // Offset of start of capture
+  __ movq(rbx, register_location(start_reg + 1));  // Offset of end of capture
+  __ subq(rbx, rdx);  // Length of capture.
+
+  // -----------------------
+  // rdx  = Start offset of capture.
+  // rbx = Length of capture
+
+  // If length is negative, this code will fail (it's a symptom of a partial or
+  // illegal capture where start of capture after end of capture).
+  // This must not happen (no back-reference can reference a capture that wasn't
+  // closed before in the reg-exp, and we must not generate code that can cause
+  // this condition).
+
+  // If length is zero, either the capture is empty or it is nonparticipating.
+  // In either case succeed immediately.
+  __ j(equal, &fallthrough);
+
+  if (mode_ == ASCII) {
+    Label loop_increment;
+    if (on_no_match == NULL) {
+      on_no_match = &backtrack_label_;
+    }
+
+    __ lea(r9, Operand(rsi, rdx, times_1, 0));
+    __ lea(r11, Operand(rsi, rdi, times_1, 0));
+    __ addq(rbx, r9);  // End of capture
+    // ---------------------
+    // r11 - current input character address
+    // r9 - current capture character address
+    // rbx - end of capture
+
+    Label loop;
+    __ bind(&loop);
+    __ movzxbl(rdx, Operand(r9, 0));
+    __ movzxbl(rax, Operand(r11, 0));
+    // al - input character
+    // dl - capture character
+    __ cmpb(rax, rdx);
+    __ j(equal, &loop_increment);
+
+    // Mismatch, try case-insensitive match (converting letters to lower-case).
+    // I.e., if or-ing with 0x20 makes values equal and in range 'a'-'z', it's
+    // a match.
+    __ or_(rax, Immediate(0x20));  // Convert match character to lower-case.
+    __ or_(rdx, Immediate(0x20));  // Convert capture character to lower-case.
+    __ cmpb(rax, rdx);
+    __ j(not_equal, on_no_match);  // Definitely not equal.
+    __ subb(rax, Immediate('a'));
+    __ cmpb(rax, Immediate('z' - 'a'));
+    __ j(above, on_no_match);  // Weren't letters anyway.
+
+    __ bind(&loop_increment);
+    // Increment pointers into match and capture strings.
+    __ addq(r11, Immediate(1));
+    __ addq(r9, Immediate(1));
+    // Compare to end of capture, and loop if not done.
+    __ cmpq(r9, rbx);
+    __ j(below, &loop);
+
+    // Compute new value of character position after the matched part.
+    __ movq(rdi, r11);
+    __ subq(rdi, rsi);
+  } else {
+    ASSERT(mode_ == UC16);
+    // Save important/volatile registers before calling C function.
+#ifndef __MSVC__
+    // Callee save on Win64
+    __ push(rsi);
+    __ push(rdi);
+#endif
+    __ push(backtrack_stackpointer());
+
+    int num_arguments = 3;
+    FrameAlign(num_arguments);
+
+    // Put arguments into parameter registers. Parameters are
+    //   Address byte_offset1 - Address captured substring's start.
+    //   Address byte_offset2 - Address of current character position.
+    //   size_t byte_length - length of capture in bytes(!)
+#ifdef __MSVC__
+    // Compute and set byte_offset1 (start of capture).
+    __ lea(rcx, Operand(rsi, rdx, times_1, 0));
+    // Set byte_offset2.
+    __ lea(rdx, Operand(rsi, rdi, times_1, 0));
+    // Set byte_length.
+    __ movq(r8, rbx);
+#else  // AMD64 calling convention
+    // Compute byte_offset2 (current position = rsi+rdi).
+    __ lea(rax, Operand(rsi, rdi, times_1, 0));
+    // Compute and set byte_offset1 (start of capture).
+    __ lea(rdi, Operand(rsi, rdx, times_1, 0));
+    // Set byte_offset2.
+    __ movq(rsi, rax);
+    // Set byte_length.
+    __ movq(rdx, rbx);
+#endif
+    Address function_address = FUNCTION_ADDR(&CaseInsensitiveCompareUC16);
+    CallCFunction(function_address, num_arguments);
+
+    // Restore original values before reacting on result value.
+    __ Move(code_object_pointer(), masm_->CodeObject());
+    __ pop(backtrack_stackpointer());
+#ifndef __MSVC__
+    __ pop(rdi);
+    __ pop(rsi);
+#endif
+
+    // Check if function returned non-zero for success or zero for failure.
+    __ testq(rax, rax);
+    BranchOrBacktrack(zero, on_no_match);
+    // On success, increment position by length of capture.
+    // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs).
+    __ addq(rdi, rbx);
+  }
+  __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerX64::CheckNotBackReference(
+    int start_reg,
+    Label* on_no_match) {
+  Label fallthrough;
+
+  // Find length of back-referenced capture.
+  __ movq(rdx, register_location(start_reg));
+  __ movq(rax, register_location(start_reg + 1));
+  __ subq(rax, rdx);  // Length to check.
+
+  // Fail on partial or illegal capture (start of capture after end of capture).
+  // This must not happen (no back-reference can reference a capture that wasn't
+  // closed before in the reg-exp).
+  __ Check(greater_equal, "Invalid capture referenced");
+
+  // Succeed on empty capture (including non-participating capture)
+  __ j(equal, &fallthrough);
+
+  // -----------------------
+  // rdx - Start of capture
+  // rax - length of capture
+
+  // Check that there are sufficient characters left in the input.
+  __ movl(rbx, rdi);
+  __ addl(rbx, rax);
+  BranchOrBacktrack(greater, on_no_match);
+
+  // Compute pointers to match string and capture string
+  __ lea(rbx, Operand(rsi, rdi, times_1, 0));  // Start of match.
+  __ addq(rdx, rsi);  // Start of capture.
+  __ lea(r9, Operand(rdx, rax, times_1, 0));  // End of capture
+
+  // -----------------------
+  // rbx - current capture character address.
+  // rbx - current input character address .
+  // r9 - end of input to match (capture length after rbx).
+
+  Label loop;
+  __ bind(&loop);
+  if (mode_ == ASCII) {
+    __ movzxbl(rax, Operand(rdx, 0));
+    __ cmpb(rax, Operand(rbx, 0));
+  } else {
+    ASSERT(mode_ == UC16);
+    __ movzxwl(rax, Operand(rdx, 0));
+    __ cmpw(rax, Operand(rbx, 0));
+  }
+  BranchOrBacktrack(not_equal, on_no_match);
+  // Increment pointers into capture and match string.
+  __ addq(rbx, Immediate(char_size()));
+  __ addq(rdx, Immediate(char_size()));
+  // Check if we have reached end of match area.
+  __ cmpq(rdx, r9);
+  __ j(below, &loop);
+
+  // Success.
+  // Set current character position to position after match.
+  __ movq(rdi, rbx);
+  __ subq(rdi, rsi);
+
+  __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerX64::CheckNotRegistersEqual(int reg1,
+                                                     int reg2,
+                                                     Label* on_not_equal) {
+  __ movq(rax, register_location(reg1));
+  __ cmpq(rax, register_location(reg2));
+  BranchOrBacktrack(not_equal, on_not_equal);
+}
+
+
+void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c,
+                                                Label* on_not_equal) {
+  __ cmpl(current_character(), Immediate(c));
+  BranchOrBacktrack(not_equal, on_not_equal);
+}
+
+
+void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c,
+                                                     uint32_t mask,
+                                                     Label* on_equal) {
+  __ movl(rax, current_character());
+  __ and_(rax, Immediate(mask));
+  __ cmpl(rax, Immediate(c));
+  BranchOrBacktrack(equal, on_equal);
+}
+
+
+void RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(uint32_t c,
+                                                        uint32_t mask,
+                                                        Label* on_not_equal) {
+  __ movl(rax, current_character());
+  __ and_(rax, Immediate(mask));
+  __ cmpl(rax, Immediate(c));
+  BranchOrBacktrack(not_equal, on_not_equal);
+}
+
+
+void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd(
+    uc16 c,
+    uc16 minus,
+    uc16 mask,
+    Label* on_not_equal) {
+  ASSERT(minus < String::kMaxUC16CharCode);
+  __ lea(rax, Operand(current_character(), -minus));
+  __ and_(rax, Immediate(mask));
+  __ cmpl(rax, Immediate(c));
+  BranchOrBacktrack(not_equal, on_not_equal);
+}
+
+
+bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type,
+                                                         int cp_offset,
+                                                         bool check_offset,
+                                                         Label* on_no_match) {
+  // Range checks (c in min..max) are generally implemented by an unsigned
+  // (c - min) <= (max - min) check
+  switch (type) {
+  case 's':
+    // Match space-characters
+    if (mode_ == ASCII) {
+      // ASCII space characters are '\t'..'\r' and ' '.
+      if (check_offset) {
+        LoadCurrentCharacter(cp_offset, on_no_match);
+      } else {
+        LoadCurrentCharacterUnchecked(cp_offset, 1);
+      }
+      Label success;
+      __ cmpl(current_character(), Immediate(' '));
+      __ j(equal, &success);
+      // Check range 0x09..0x0d
+      __ subl(current_character(), Immediate('\t'));
+      __ cmpl(current_character(), Immediate('\r' - '\t'));
+      BranchOrBacktrack(above, on_no_match);
+      __ bind(&success);
+      return true;
+    }
+    return false;
+  case 'S':
+    // Match non-space characters.
+    if (check_offset) {
+      LoadCurrentCharacter(cp_offset, on_no_match, 1);
+    } else {
+      LoadCurrentCharacterUnchecked(cp_offset, 1);
+    }
+    if (mode_ == ASCII) {
+      // ASCII space characters are '\t'..'\r' and ' '.
+      __ cmpl(current_character(), Immediate(' '));
+      BranchOrBacktrack(equal, on_no_match);
+      __ subl(current_character(), Immediate('\t'));
+      __ cmpl(current_character(), Immediate('\r' - '\t'));
+      BranchOrBacktrack(below_equal, on_no_match);
+      return true;
+    }
+    return false;
+  case 'd':
+    // Match ASCII digits ('0'..'9')
+    if (check_offset) {
+      LoadCurrentCharacter(cp_offset, on_no_match, 1);
+    } else {
+      LoadCurrentCharacterUnchecked(cp_offset, 1);
+    }
+    __ subl(current_character(), Immediate('0'));
+    __ cmpl(current_character(), Immediate('9' - '0'));
+    BranchOrBacktrack(above, on_no_match);
+    return true;
+  case 'D':
+    // Match non ASCII-digits
+    if (check_offset) {
+      LoadCurrentCharacter(cp_offset, on_no_match, 1);
+    } else {
+      LoadCurrentCharacterUnchecked(cp_offset, 1);
+    }
+    __ subl(current_character(), Immediate('0'));
+    __ cmpl(current_character(), Immediate('9' - '0'));
+    BranchOrBacktrack(below_equal, on_no_match);
+    return true;
+  case '.': {
+    // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
+    if (check_offset) {
+      LoadCurrentCharacter(cp_offset, on_no_match, 1);
+    } else {
+      LoadCurrentCharacterUnchecked(cp_offset, 1);
+    }
+    __ xor_(current_character(), Immediate(0x01));
+    // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
+    __ subl(current_character(), Immediate(0x0b));
+    __ cmpl(current_character(), Immediate(0x0c - 0x0b));
+    BranchOrBacktrack(below_equal, on_no_match);
+    if (mode_ == UC16) {
+      // Compare original value to 0x2028 and 0x2029, using the already
+      // computed (current_char ^ 0x01 - 0x0b). I.e., check for
+      // 0x201d (0x2028 - 0x0b) or 0x201e.
+      __ subl(current_character(), Immediate(0x2028 - 0x0b));
+      __ cmpl(current_character(), Immediate(1));
+      BranchOrBacktrack(below_equal, on_no_match);
+    }
+    return true;
+  }
+  case '*':
+    // Match any character.
+    if (check_offset) {
+      CheckPosition(cp_offset, on_no_match);
+    }
+    return true;
+  // No custom implementation (yet): w, W, s(UC16), S(UC16).
+  default:
+    return false;
+  }
+}
+
+
+void RegExpMacroAssemblerX64::Fail() {
+  ASSERT(FAILURE == 0);  // Return value for failure is zero.
+  __ xor_(rax, rax);  // zero rax.
+  __ jmp(&exit_label_);
+}
+
+
+Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
+  // Finalize code - write the entry point code now we know how many
+  // registers we need.
+
+  // Entry code:
+  __ bind(&entry_label_);
+  // Start new stack frame.
+  __ push(rbp);
+  __ movq(rbp, rsp);
+  // Save parameters and callee-save registers. Order here should correspond
+  //  to order of kBackup_ebx etc.
+#ifdef __MSVC__
+  // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots.
+  // Store register parameters in pre-allocated stack slots,
+  __ movq(Operand(rbp, kInputString), rcx);
+  __ movq(Operand(rbp, kStartIndex), rdx);
+  __ movq(Operand(rbp, kInputStart), r8);
+  __ movq(Operand(rbp, kInputEnd), r9);
+  // Callee-save on Win64.
+  __ push(rsi);
+  __ push(rdi);
+  __ push(rbx);
+#else
+  // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack).
+  // Push register parameters on stack for reference.
+  ASSERT_EQ(kInputString, -1 * kPointerSize);
+  ASSERT_EQ(kStartIndex, -2 * kPointerSize);
+  ASSERT_EQ(kInputStart, -3 * kPointerSize);
+  ASSERT_EQ(kInputEnd, -4 * kPointerSize);
+  ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
+  ASSERT_EQ(kAtStart, -6 * kPointerSize);
+  __ push(rdi);
+  __ push(rsi);
+  __ push(rdx);
+  __ push(rcx);
+  __ push(r8);
+  __ push(r9);
+
+  __ push(rbx);  // Callee-save
+#endif
+  __ push(Immediate(0));  // Make room for "input start - 1" constant.
+
+  // Check if we have space on the stack for registers.
+  Label stack_limit_hit;
+  Label stack_ok;
+
+  ExternalReference stack_guard_limit =
+      ExternalReference::address_of_stack_guard_limit();
+  __ movq(rcx, rsp);
+  __ movq(kScratchRegister, stack_guard_limit);
+  __ subq(rcx, Operand(kScratchRegister, 0));
+  // Handle it if the stack pointer is already below the stack limit.
+  __ j(below_equal, &stack_limit_hit);
+  // Check if there is room for the variable number of registers above
+  // the stack limit.
+  __ cmpq(rcx, Immediate(num_registers_ * kPointerSize));
+  __ j(above_equal, &stack_ok);
+  // Exit with OutOfMemory exception. There is not enough space on the stack
+  // for our working registers.
+  __ movq(rax, Immediate(EXCEPTION));
+  __ jmp(&exit_label_);
+
+  __ bind(&stack_limit_hit);
+  __ Move(code_object_pointer(), masm_->CodeObject());
+  CallCheckStackGuardState();  // Preserves no registers beside rbp and rsp.
+  __ testq(rax, rax);
+  // If returned value is non-zero, we exit with the returned value as result.
+  __ j(not_zero, &exit_label_);
+
+  __ bind(&stack_ok);
+
+  // Allocate space on stack for registers.
+  __ subq(rsp, Immediate(num_registers_ * kPointerSize));
+  // Load string length.
+  __ movq(rsi, Operand(rbp, kInputEnd));
+  // Load input position.
+  __ movq(rdi, Operand(rbp, kInputStart));
+  // Set up rdi to be negative offset from string end.
+  __ subq(rdi, rsi);
+  // Set rax to address of char before start of input
+  // (effectively string position -1).
+  __ lea(rax, Operand(rdi, -char_size()));
+  // Store this value in a local variable, for use when clearing
+  // position registers.
+  __ movq(Operand(rbp, kInputStartMinusOne), rax);
+  if (num_saved_registers_ > 0) {
+    // Fill saved registers with initial value = start offset - 1
+    // Fill in stack push order, to avoid accessing across an unwritten
+    // page (a problem on Windows).
+    __ movq(rcx, Immediate(kRegisterZero));
+    Label init_loop;
+    __ bind(&init_loop);
+    __ movq(Operand(rbp, rcx, times_1, 0), rax);
+    __ subq(rcx, Immediate(kPointerSize));
+    __ cmpq(rcx,
+            Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
+    __ j(greater, &init_loop);
+  }
+  // Ensure that we have written to each stack page, in order. Skipping a page
+  // on Windows can cause segmentation faults. Assuming page size is 4k.
+  const int kPageSize = 4096;
+  const int kRegistersPerPage = kPageSize / kPointerSize;
+  for (int i = num_saved_registers_ + kRegistersPerPage - 1;
+      i < num_registers_;
+      i += kRegistersPerPage) {
+    __ movq(register_location(i), rax);  // One write every page.
+  }
+
+  // Initialize backtrack stack pointer.
+  __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
+  // Initialize code object pointer.
+  __ Move(code_object_pointer(), masm_->CodeObject());
+  // Load previous char as initial value of current-character.
+  Label at_start;
+  __ cmpq(Operand(rbp, kAtStart), Immediate(0));
+  __ j(not_equal, &at_start);
+  LoadCurrentCharacterUnchecked(-1, 1);  // Load previous char.
+  __ jmp(&start_label_);
+  __ bind(&at_start);
+  __ movq(current_character(), Immediate('\n'));
+  __ jmp(&start_label_);
+
+
+  // Exit code:
+  if (success_label_.is_linked()) {
+    // Save captures when successful.
+    __ bind(&success_label_);
+    if (num_saved_registers_ > 0) {
+      // copy captures to output
+      __ movq(rbx, Operand(rbp, kRegisterOutput));
+      __ movq(rcx, Operand(rbp, kInputEnd));
+      __ subq(rcx, Operand(rbp, kInputStart));
+      for (int i = 0; i < num_saved_registers_; i++) {
+        __ movq(rax, register_location(i));
+        __ addq(rax, rcx);  // Convert to index from start, not end.
+        if (mode_ == UC16) {
+          __ sar(rax, Immediate(1));  // Convert byte index to character index.
+        }
+        __ movl(Operand(rbx, i * kIntSize), rax);
+      }
+    }
+    __ movq(rax, Immediate(SUCCESS));
+  }
+
+  // Exit and return rax
+  __ bind(&exit_label_);
+
+#ifdef __MSVC__
+  // Restore callee save registers.
+  __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister));
+  __ pop(rbx);
+  __ pop(rdi);
+  __ pop(rsi);
+  // Stack now at rbp.
+#else
+  // Restore callee save register.
+  __ movq(rbx, Operand(rbp, kBackup_rbx));
+  // Skip rsp to rbp.
+  __ movq(rsp, rbp);
+#endif
+  // Exit function frame, restore previous one.
+  __ pop(rbp);
+  __ ret(0);
+
+  // Backtrack code (branch target for conditional backtracks).
+  if (backtrack_label_.is_linked()) {
+    __ bind(&backtrack_label_);
+    Backtrack();
+  }
+
+  Label exit_with_exception;
+
+  // Preempt-code
+  if (check_preempt_label_.is_linked()) {
+    SafeCallTarget(&check_preempt_label_);
+
+    __ push(backtrack_stackpointer());
+    __ push(rdi);
+
+    CallCheckStackGuardState();
+    __ testq(rax, rax);
+    // If returning non-zero, we should end execution with the given
+    // result as return value.
+    __ j(not_zero, &exit_label_);
+
+    // Restore registers.
+    __ Move(code_object_pointer(), masm_->CodeObject());
+    __ pop(rdi);
+    __ pop(backtrack_stackpointer());
+    // String might have moved: Reload esi from frame.
+    __ movq(rsi, Operand(rbp, kInputEnd));
+    SafeReturn();
+  }
+
+  // Backtrack stack overflow code.
+  if (stack_overflow_label_.is_linked()) {
+    SafeCallTarget(&stack_overflow_label_);
+    // Reached if the backtrack-stack limit has been hit.
+
+    Label grow_failed;
+    // Save registers before calling C function
+#ifndef __MSVC__
+    // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI.
+    __ push(rsi);
+    __ push(rdi);
+#endif
+
+    // Call GrowStack(backtrack_stackpointer())
+    int num_arguments = 2;
+    FrameAlign(num_arguments);
+#ifdef __MSVC__
+    // Microsoft passes parameters in rcx, rdx.
+    // First argument, backtrack stackpointer, is already in rcx.
+    __ lea(rdx, Operand(rbp, kStackHighEnd));  // Second argument
+#else
+    // AMD64 ABI passes paremeters in rdi, rsi.
+    __ movq(rdi, backtrack_stackpointer());   // First argument.
+    __ lea(rsi, Operand(rbp, kStackHighEnd));  // Second argument.
+#endif
+    CallCFunction(FUNCTION_ADDR(&GrowStack), num_arguments);
+    // If return NULL, we have failed to grow the stack, and
+    // must exit with a stack-overflow exception.
+    __ testq(rax, rax);
+    __ j(equal, &exit_with_exception);
+    // Otherwise use return value as new stack pointer.
+    __ movq(backtrack_stackpointer(), rax);
+    // Restore saved registers and continue.
+    __ Move(code_object_pointer(), masm_->CodeObject());
+#ifndef __MSVC__
+    __ pop(rdi);
+    __ pop(rsi);
+#endif
+    SafeReturn();
+  }
+
+  if (exit_with_exception.is_linked()) {
+    // If any of the code above needed to exit with an exception.
+    __ bind(&exit_with_exception);
+    // Exit with Result EXCEPTION(-1) to signal thrown exception.
+    __ movq(rax, Immediate(EXCEPTION));
+    __ jmp(&exit_label_);
+  }
+
+  FixupCodeRelativePositions();
+
+  CodeDesc code_desc;
+  masm_->GetCode(&code_desc);
+  Handle<Code> code = Factory::NewCode(code_desc,
+                                       NULL,
+                                       Code::ComputeFlags(Code::REGEXP),
+                                       masm_->CodeObject());
+  LOG(RegExpCodeCreateEvent(*code, *source));
+  return Handle<Object>::cast(code);
+}
+
+
+void RegExpMacroAssemblerX64::GoTo(Label* to) {
+  BranchOrBacktrack(no_condition, to);
+}
+
+
+void RegExpMacroAssemblerX64::IfRegisterGE(int reg,
+                                           int comparand,
+                                           Label* if_ge) {
+  __ cmpq(register_location(reg), Immediate(comparand));
+  BranchOrBacktrack(greater_equal, if_ge);
+}
+
+
+void RegExpMacroAssemblerX64::IfRegisterLT(int reg,
+                                           int comparand,
+                                           Label* if_lt) {
+  __ cmpq(register_location(reg), Immediate(comparand));
+  BranchOrBacktrack(less, if_lt);
+}
+
+
+void RegExpMacroAssemblerX64::IfRegisterEqPos(int reg,
+                                              Label* if_eq) {
+  __ cmpq(rdi, register_location(reg));
+  BranchOrBacktrack(equal, if_eq);
+}
+
+
+RegExpMacroAssembler::IrregexpImplementation
+    RegExpMacroAssemblerX64::Implementation() {
+  return kX64Implementation;
+}
+
+
+void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset,
+                                                   Label* on_end_of_input,
+                                                   bool check_bounds,
+                                                   int characters) {
+  ASSERT(cp_offset >= -1);      // ^ and \b can look behind one character.
+  ASSERT(cp_offset < (1<<30));  // Be sane! (And ensure negation works)
+  CheckPosition(cp_offset + characters - 1, on_end_of_input);
+  LoadCurrentCharacterUnchecked(cp_offset, characters);
+}
+
+
+void RegExpMacroAssemblerX64::PopCurrentPosition() {
+  Pop(rdi);
+}
+
+
+void RegExpMacroAssemblerX64::PopRegister(int register_index) {
+  Pop(rax);
+  __ movq(register_location(register_index), rax);
+}
+
+
+void RegExpMacroAssemblerX64::PushBacktrack(Label* label) {
+  Push(label);
+  CheckStackLimit();
+}
+
+
+void RegExpMacroAssemblerX64::PushCurrentPosition() {
+  Push(rdi);
+}
+
+
+void RegExpMacroAssemblerX64::PushRegister(int register_index,
+                                           StackCheckFlag check_stack_limit) {
+  __ movq(rax, register_location(register_index));
+  Push(rax);
+  if (check_stack_limit) CheckStackLimit();
+}
+
+
+void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) {
+  __ movq(rdi, register_location(reg));
+}
+
+
+void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) {
+  __ movq(backtrack_stackpointer(), register_location(reg));
+  __ addq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
+}
+
+
+void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) {
+  ASSERT(register_index >= num_saved_registers_);  // Reserved for positions!
+  __ movq(register_location(register_index), Immediate(to));
+}
+
+
+void RegExpMacroAssemblerX64::Succeed() {
+  __ jmp(&success_label_);
+}
+
+
+void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg,
+                                                             int cp_offset) {
+  if (cp_offset == 0) {
+    __ movq(register_location(reg), rdi);
+  } else {
+    __ lea(rax, Operand(rdi, cp_offset * char_size()));
+    __ movq(register_location(reg), rax);
+  }
+}
+
+
+void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) {
+  ASSERT(reg_from <= reg_to);
+  __ movq(rax, Operand(rbp, kInputStartMinusOne));
+  for (int reg = reg_from; reg <= reg_to; reg++) {
+    __ movq(register_location(reg), rax);
+  }
+}
+
+
+void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) {
+  __ movq(rax, backtrack_stackpointer());
+  __ subq(rax, Operand(rbp, kStackHighEnd));
+  __ movq(register_location(reg), rax);
+}
+
+
+// Private methods:
+
+void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
+  // This function call preserves no register values. Caller should
+  // store anything volatile in a C call or overwritten by this function.
+  int num_arguments = 3;
+  FrameAlign(num_arguments);
+#ifdef __MSVC__
+  // Second argument: Code* of self. (Do this before overwriting r8).
+  __ movq(rdx, code_object_pointer());
+  // Third argument: RegExp code frame pointer.
+  __ movq(r8, rbp);
+  // First argument: Next address on the stack (will be address of
+  // return address).
+  __ lea(rcx, Operand(rsp, -kPointerSize));
+#else
+  // Third argument: RegExp code frame pointer.
+  __ movq(rdx, rbp);
+  // Second argument: Code* of self.
+  __ movq(rsi, code_object_pointer());
+  // First argument: Next address on the stack (will be address of
+  // return address).
+  __ lea(rdi, Operand(rsp, -kPointerSize));
+#endif
+  CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments);
+}
+
+
+// Helper function for reading a value out of a stack frame.
+template <typename T>
+static T& frame_entry(Address re_frame, int frame_offset) {
+  return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset));
+}
+
+
+int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address,
+                                                  Code* re_code,
+                                                  Address re_frame) {
+  if (StackGuard::IsStackOverflow()) {
+    Top::StackOverflow();
+    return EXCEPTION;
+  }
+
+  // If not real stack overflow the stack guard was used to interrupt
+  // execution for another purpose.
+
+  // Prepare for possible GC.
+  HandleScope handles;
+  Handle<Code> code_handle(re_code);
+
+  Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
+  // Current string.
+  bool is_ascii = subject->IsAsciiRepresentation();
+
+  ASSERT(re_code->instruction_start() <= *return_address);
+  ASSERT(*return_address <=
+      re_code->instruction_start() + re_code->instruction_size());
+
+  Object* result = Execution::HandleStackGuardInterrupt();
+
+  if (*code_handle != re_code) {  // Return address no longer valid
+    intptr_t delta = *code_handle - re_code;
+    // Overwrite the return address on the stack.
+    *return_address += delta;
+  }
+
+  if (result->IsException()) {
+    return EXCEPTION;
+  }
+
+  // String might have changed.
+  if (subject->IsAsciiRepresentation() != is_ascii) {
+    // If we changed between an ASCII and an UC16 string, the specialized
+    // code cannot be used, and we need to restart regexp matching from
+    // scratch (including, potentially, compiling a new version of the code).
+    return RETRY;
+  }
+
+  // Otherwise, the content of the string might have moved. It must still
+  // be a sequential or external string with the same content.
+  // Update the start and end pointers in the stack frame to the current
+  // location (whether it has actually moved or not).
+  ASSERT(StringShape(*subject).IsSequential() ||
+      StringShape(*subject).IsExternal());
+
+  // The original start address of the characters to match.
+  const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart);
+
+  // Find the current start address of the same character at the current string
+  // position.
+  int start_index = frame_entry<int>(re_frame, kStartIndex);
+  const byte* new_address = StringCharacterPosition(*subject, start_index);
+
+  if (start_address != new_address) {
+    // If there is a difference, update the object pointer and start and end
+    // addresses in the RegExp stack frame to match the new value.
+    const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd);
+    int byte_length = end_address - start_address;
+    frame_entry<const String*>(re_frame, kInputString) = *subject;
+    frame_entry<const byte*>(re_frame, kInputStart) = new_address;
+    frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
+  }
+
+  return 0;
+}
+
+
+Address RegExpMacroAssemblerX64::GrowStack(Address stack_pointer,
+                                           Address* stack_base) {
+  size_t size = RegExpStack::stack_capacity();
+  Address old_stack_base = RegExpStack::stack_base();
+  ASSERT(old_stack_base == *stack_base);
+  ASSERT(stack_pointer <= old_stack_base);
+  ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size);
+  Address new_stack_base = RegExpStack::EnsureCapacity(size * 2);
+  if (new_stack_base == NULL) {
+    return NULL;
+  }
+  *stack_base = new_stack_base;
+  intptr_t stack_content_size = old_stack_base - stack_pointer;
+  return new_stack_base - stack_content_size;
+}
+
+
+Operand RegExpMacroAssemblerX64::register_location(int register_index) {
+  ASSERT(register_index < (1<<30));
+  if (num_registers_ <= register_index) {
+    num_registers_ = register_index + 1;
+  }
+  return Operand(rbp, kRegisterZero - register_index * kPointerSize);
+}
+
+
+void RegExpMacroAssemblerX64::CheckPosition(int cp_offset,
+                                            Label* on_outside_input) {
+  __ cmpl(rdi, Immediate(-cp_offset * char_size()));
+  BranchOrBacktrack(greater_equal, on_outside_input);
+}
+
+
+void RegExpMacroAssemblerX64::BranchOrBacktrack(Condition condition,
+                                                Label* to) {
+  if (condition < 0) {  // No condition
+    if (to == NULL) {
+      Backtrack();
+      return;
+    }
+    __ jmp(to);
+    return;
+  }
+  if (to == NULL) {
+    __ j(condition, &backtrack_label_);
+    return;
+  }
+  __ j(condition, to);
+}
+
+
+void RegExpMacroAssemblerX64::SafeCall(Label* to) {
+  __ call(to);
+}
+
+
+void RegExpMacroAssemblerX64::SafeCallTarget(Label* label) {
+  __ bind(label);
+  __ subq(Operand(rsp, 0), code_object_pointer());
+}
+
+
+void RegExpMacroAssemblerX64::SafeReturn() {
+  __ addq(Operand(rsp, 0), code_object_pointer());
+  __ ret(0);
+}
+
+
+void RegExpMacroAssemblerX64::Push(Register source) {
+  ASSERT(!source.is(backtrack_stackpointer()));
+  // Notice: This updates flags, unlike normal Push.
+  __ subq(backtrack_stackpointer(), Immediate(kIntSize));
+  __ movl(Operand(backtrack_stackpointer(), 0), source);
+}
+
+
+void RegExpMacroAssemblerX64::Push(Immediate value) {
+  // Notice: This updates flags, unlike normal Push.
+  __ subq(backtrack_stackpointer(), Immediate(kIntSize));
+  __ movl(Operand(backtrack_stackpointer(), 0), value);
+}
+
+
+void RegExpMacroAssemblerX64::FixupCodeRelativePositions() {
+  for (int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) {
+    int position = code_relative_fixup_positions_[i];
+    // The position succeeds a relative label offset from position.
+    // Patch the relative offset to be relative to the Code object pointer
+    // instead.
+    int patch_position = position - kIntSize;
+    int offset = masm_->long_at(patch_position);
+    masm_->long_at_put(patch_position,
+                       offset
+                       + position
+                       + Code::kHeaderSize
+                       - kHeapObjectTag);
+  }
+  code_relative_fixup_positions_.Clear();
+}
+
+
+void RegExpMacroAssemblerX64::Push(Label* backtrack_target) {
+  __ subq(backtrack_stackpointer(), Immediate(kIntSize));
+  __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target);
+  MarkPositionForCodeRelativeFixup();
+}
+
+
+void RegExpMacroAssemblerX64::Pop(Register target) {
+  ASSERT(!target.is(backtrack_stackpointer()));
+  __ movsxlq(target, Operand(backtrack_stackpointer(), 0));
+  // Notice: This updates flags, unlike normal Pop.
+  __ addq(backtrack_stackpointer(), Immediate(kIntSize));
+}
+
+
+void RegExpMacroAssemblerX64::Drop() {
+  __ addq(backtrack_stackpointer(), Immediate(kIntSize));
+}
+
+
+void RegExpMacroAssemblerX64::CheckPreemption() {
+  // Check for preemption.
+  Label no_preempt;
+  ExternalReference stack_guard_limit =
+      ExternalReference::address_of_stack_guard_limit();
+  __ load_rax(stack_guard_limit);
+  __ cmpq(rsp, rax);
+  __ j(above, &no_preempt);
+
+  SafeCall(&check_preempt_label_);
+
+  __ bind(&no_preempt);
+}
+
+
+void RegExpMacroAssemblerX64::CheckStackLimit() {
+  if (FLAG_check_stack) {
+    Label no_stack_overflow;
+    ExternalReference stack_limit =
+        ExternalReference::address_of_regexp_stack_limit();
+    __ load_rax(stack_limit);
+    __ cmpq(backtrack_stackpointer(), rax);
+    __ j(above, &no_stack_overflow);
+
+    SafeCall(&stack_overflow_label_);
+
+    __ bind(&no_stack_overflow);
+  }
+}
+
+
+void RegExpMacroAssemblerX64::FrameAlign(int num_arguments) {
+  // TODO(lrn): Since we no longer use the system stack arbitrarily (but we do
+  // use it, e.g., for SafeCall), we know the number of elements on the stack
+  // since the last frame alignment. We might be able to do this simpler then.
+  int frameAlignment = OS::ActivationFrameAlignment();
+  ASSERT(frameAlignment != 0);
+  // Make stack end at alignment and make room for num_arguments pointers
+  // (on Win64 only) and the original value of rsp.
+  __ movq(kScratchRegister, rsp);
+  ASSERT(IsPowerOf2(frameAlignment));
+#ifdef __MSVC__
+  // Allocate space for parameters and old rsp.
+  __ subq(rsp, Immediate((num_arguments + 1) * kPointerSize));
+  __ and_(rsp, -frameAlignment);
+  __ movq(Operand(rsp, num_arguments * kPointerSize), kScratchRegister);
+#else
+  // Allocate space for old rsp.
+  __ subq(rsp, Immediate(kPointerSize));
+  __ and_(rsp, Immediate(-frameAlignment));
+  __ movq(Operand(rsp, 0), kScratchRegister);
+#endif
+}
+
+
+void RegExpMacroAssemblerX64::CallCFunction(Address function_address,
+                                            int num_arguments) {
+  // Don't compile regexps with serialization enabled. The addresses of the C++
+  // function being called isn't relocatable.
+  ASSERT(!Serializer::enabled());
+  __ movq(rax, reinterpret_cast<intptr_t>(function_address), RelocInfo::NONE);
+  __ call(rax);
+  ASSERT(OS::ActivationFrameAlignment() != 0);
+#ifdef __MSVC__
+  __ movq(rsp, Operand(rsp, num_arguments * kPointerSize));
+#else
+  __ pop(rsp);
+#endif
+}
+
+
+void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset,
+                                                            int characters) {
+  if (mode_ == ASCII) {
+    if (characters == 4) {
+      __ movl(current_character(), Operand(rsi, rdi, times_1, cp_offset));
+    } else if (characters == 2) {
+      __ movzxwl(current_character(), Operand(rsi, rdi, times_1, cp_offset));
+    } else {
+      ASSERT(characters == 1);
+      __ movzxbl(current_character(), Operand(rsi, rdi, times_1, cp_offset));
+    }
+  } else {
+    ASSERT(mode_ == UC16);
+    if (characters == 2) {
+      __ movl(current_character(),
+              Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16)));
+    } else {
+      ASSERT(characters == 1);
+      __ movzxwl(current_character(),
+                 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16)));
+    }
+  }
+}
+
+
+#undef __
+}}  // namespace v8::internal
diff --git a/src/x64/regexp-macro-assembler-x64.h b/src/x64/regexp-macro-assembler-x64.h
index 209aa2d..a270bc1 100644
--- a/src/x64/regexp-macro-assembler-x64.h
+++ b/src/x64/regexp-macro-assembler-x64.h
@@ -25,3 +25,271 @@
 // (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_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
+#define V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
+
+namespace v8 {
+namespace internal {
+
+class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
+ public:
+  RegExpMacroAssemblerX64(Mode mode, int registers_to_save);
+  virtual ~RegExpMacroAssemblerX64();
+  virtual int stack_limit_slack();
+  virtual void AdvanceCurrentPosition(int by);
+  virtual void AdvanceRegister(int reg, int by);
+  virtual void Backtrack();
+  virtual void Bind(Label* label);
+  virtual void CheckAtStart(Label* on_at_start);
+  virtual void CheckCharacter(uint32_t c, Label* on_equal);
+  virtual void CheckCharacterAfterAnd(uint32_t c,
+                                      uint32_t mask,
+                                      Label* on_equal);
+  virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
+  virtual void CheckCharacterLT(uc16 limit, Label* on_less);
+  virtual void CheckCharacters(Vector<const uc16> str,
+                               int cp_offset,
+                               Label* on_failure,
+                               bool check_end_of_string);
+  // A "greedy loop" is a loop that is both greedy and with a simple
+  // body. It has a particularly simple implementation.
+  virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
+  virtual void CheckNotAtStart(Label* on_not_at_start);
+  virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
+  virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
+                                               Label* on_no_match);
+  virtual void CheckNotRegistersEqual(int reg1, int reg2, Label* on_not_equal);
+  virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal);
+  virtual void CheckNotCharacterAfterAnd(uint32_t c,
+                                         uint32_t mask,
+                                         Label* on_not_equal);
+  virtual void CheckNotCharacterAfterMinusAnd(uc16 c,
+                                              uc16 minus,
+                                              uc16 mask,
+                                              Label* on_not_equal);
+  // Checks whether the given offset from the current position is before
+  // the end of the string.
+  virtual void CheckPosition(int cp_offset, Label* on_outside_input);
+  virtual bool CheckSpecialCharacterClass(uc16 type,
+                                          int cp_offset,
+                                          bool check_offset,
+                                          Label* on_no_match);
+  virtual void Fail();
+  virtual Handle<Object> GetCode(Handle<String> source);
+  virtual void GoTo(Label* label);
+  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
+  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
+  virtual void IfRegisterEqPos(int reg, Label* if_eq);
+  virtual IrregexpImplementation Implementation();
+  virtual void LoadCurrentCharacter(int cp_offset,
+                                    Label* on_end_of_input,
+                                    bool check_bounds = true,
+                                    int characters = 1);
+  virtual void PopCurrentPosition();
+  virtual void PopRegister(int register_index);
+  virtual void PushBacktrack(Label* label);
+  virtual void PushCurrentPosition();
+  virtual void PushRegister(int register_index,
+                            StackCheckFlag check_stack_limit);
+  virtual void ReadCurrentPositionFromRegister(int reg);
+  virtual void ReadStackPointerFromRegister(int reg);
+  virtual void SetRegister(int register_index, int to);
+  virtual void Succeed();
+  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
+  virtual void ClearRegisters(int reg_from, int reg_to);
+  virtual void WriteStackPointerToRegister(int reg);
+
+  static Result Match(Handle<Code> regexp,
+                      Handle<String> subject,
+                      int* offsets_vector,
+                      int offsets_vector_length,
+                      int previous_index);
+
+  static Result Execute(Code* code,
+                        String* input,
+                        int start_offset,
+                        const byte* input_start,
+                        const byte* input_end,
+                        int* output,
+                        bool at_start);
+
+ private:
+  // Offsets from rbp of function parameters and stored registers.
+  static const int kFramePointer = 0;
+  // Above the frame pointer - function parameters and return address.
+  static const int kReturn_eip = kFramePointer + kPointerSize;
+  static const int kFrameAlign = kReturn_eip + kPointerSize;
+
+#ifdef __MSVC__
+  // Parameters (first four passed as registers, but with room on stack).
+  // In Microsoft 64-bit Calling Convention, there is room on the callers
+  // stack (before the return address) to spill parameter registers. We
+  // use this space to store the register passed parameters.
+  static const int kInputString = kFrameAlign;
+  static const int kStartIndex = kInputString + kPointerSize;
+  static const int kInputStart = kStartIndex + kPointerSize;
+  static const int kInputEnd = kInputStart + kPointerSize;
+  static const int kRegisterOutput = kInputEnd + kPointerSize;
+  static const int kAtStart = kRegisterOutput + kPointerSize;
+  static const int kStackHighEnd = kAtStart + kPointerSize;
+#else
+  // In AMD64 ABI Calling Convention, the first six integer parameters
+  // are passed as registers, and caller must allocate space on the stack
+  // if it wants them stored. We push the parameters after the frame pointer.
+  static const int kInputString = kFramePointer - kPointerSize;
+  static const int kStartIndex = kInputString - kPointerSize;
+  static const int kInputStart = kStartIndex - kPointerSize;
+  static const int kInputEnd = kInputStart - kPointerSize;
+  static const int kRegisterOutput = kInputEnd - kPointerSize;
+  static const int kAtStart = kRegisterOutput - kPointerSize;
+  static const int kStackHighEnd = kFrameAlign;
+#endif
+
+#ifdef __MSVC__
+  // Microsoft calling convention has three callee-saved registers
+  // (that we are using). We push these after the frame pointer.
+  static const int kBackup_rsi = kFramePointer - kPointerSize;
+  static const int kBackup_rdi = kBackup_rsi - kPointerSize;
+  static const int kBackup_rbx = kBackup_rdi - kPointerSize;
+  static const int kLastCalleeSaveRegister = kBackup_rbx;
+#else
+  // AMD64 Calling Convention has only one callee-save register that
+  // we use. We push this after the frame pointer (and after the
+  // parameters).
+  static const int kBackup_rbx = kAtStart - kPointerSize;
+  static const int kLastCalleeSaveRegister = kBackup_rbx;
+#endif
+
+  // When adding local variables remember to push space for them in
+  // the frame in GetCode.
+  static const int kInputStartMinusOne =
+      kLastCalleeSaveRegister - kPointerSize;
+
+  // First register address. Following registers are below it on the stack.
+  static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
+
+  // Initial size of code buffer.
+  static const size_t kRegExpCodeSize = 1024;
+
+  // Load a number of characters at the given offset from the
+  // current position, into the current-character register.
+  void LoadCurrentCharacterUnchecked(int cp_offset, int character_count);
+
+  // Check whether preemption has been requested.
+  void CheckPreemption();
+
+  // Check whether we are exceeding the stack limit on the backtrack stack.
+  void CheckStackLimit();
+
+  // Called from RegExp if the stack-guard is triggered.
+  // If the code object is relocated, the return address is fixed before
+  // returning.
+  static int CheckStackGuardState(Address* return_address,
+                                  Code* re_code,
+                                  Address re_frame);
+
+  // Generate a call to CheckStackGuardState.
+  void CallCheckStackGuardState();
+
+  // Called from RegExp if the backtrack stack limit is hit.
+  // Tries to expand the stack. Returns the new stack-pointer if
+  // successful, and updates the stack_top address, or returns 0 if unable
+  // to grow the stack.
+  // This function must not trigger a garbage collection.
+  static Address GrowStack(Address stack_pointer, Address* stack_top);
+
+  // The rbp-relative location of a regexp register.
+  Operand register_location(int register_index);
+
+  // The register containing the current character after LoadCurrentCharacter.
+  inline Register current_character() { return rdx; }
+
+  // The register containing the backtrack stack top. Provides a meaningful
+  // name to the register.
+  inline Register backtrack_stackpointer() { return rcx; }
+
+  // The registers containing a self pointer to this code's Code object.
+  inline Register code_object_pointer() { return r8; }
+
+  // Byte size of chars in the string to match (decided by the Mode argument)
+  inline int char_size() { return static_cast<int>(mode_); }
+
+  // Equivalent to a conditional branch to the label, unless the label
+  // is NULL, in which case it is a conditional Backtrack.
+  void BranchOrBacktrack(Condition condition, Label* to);
+
+  void MarkPositionForCodeRelativeFixup() {
+    code_relative_fixup_positions_.Add(masm_->pc_offset());
+  }
+
+  void FixupCodeRelativePositions();
+
+  // Call and return internally in the generated code in a way that
+  // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
+  inline void SafeCall(Label* to);
+  inline void SafeCallTarget(Label* label);
+  inline void SafeReturn();
+
+  // Pushes the value of a register on the backtrack stack. Decrements the
+  // stack pointer (rcx) by a word size and stores the register's value there.
+  inline void Push(Register source);
+
+  // Pushes a value on the backtrack stack. Decrements the stack pointer (rcx)
+  // by a word size and stores the value there.
+  inline void Push(Immediate value);
+
+  // Pushes the Code object relative offset of a label on the backtrack stack
+  // (i.e., a backtrack target). Decrements the stack pointer (rcx)
+  // by a word size and stores the value there.
+  inline void Push(Label* label);
+
+  // Pops a value from the backtrack stack. Reads the word at the stack pointer
+  // (rcx) and increments it by a word size.
+  inline void Pop(Register target);
+
+  // Drops the top value from the backtrack stack without reading it.
+  // Increments the stack pointer (rcx) by a word size.
+  inline void Drop();
+
+  // Before calling a C-function from generated code, align arguments on stack.
+  // After aligning the frame, arguments must be stored in esp[0], esp[4],
+  // etc., not pushed. The argument count assumes all arguments are word sized.
+  // Some compilers/platforms require the stack to be aligned when calling
+  // C++ code.
+  // Needs a scratch register to do some arithmetic. This register will be
+  // trashed.
+  inline void FrameAlign(int num_arguments);
+
+  // Calls a C function and cleans up the space for arguments allocated
+  // by FrameAlign. The called function is not allowed to trigger a garbage
+  // collection, since that might move the code and invalidate the return
+  // address (unless this is somehow accounted for by the called function).
+  inline void CallCFunction(Address function_address, int num_arguments);
+
+  MacroAssembler* masm_;
+
+  ZoneList<int> code_relative_fixup_positions_;
+
+  // Which mode to generate code for (ASCII or UC16).
+  Mode mode_;
+
+  // One greater than maximal register index actually used.
+  int num_registers_;
+
+  // Number of registers to output at the end (the saved registers
+  // are always 0..num_saved_registers_-1)
+  int num_saved_registers_;
+
+  // Labels used internally.
+  Label entry_label_;
+  Label start_label_;
+  Label success_label_;
+  Label backtrack_label_;
+  Label exit_label_;
+  Label check_preempt_label_;
+  Label stack_overflow_label_;
+};
+
+}}  // namespace v8::internal
+
+#endif  // V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 9abe408..68aabb5 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -60,61 +60,3 @@
 # the JavaScript stacks are separate.
 test-api/ExceptionOrder: FAIL
 test-api/TryCatchInTryFinally: FAIL
-
-
-[ $arch == x64 ]
-test-decls/Present: CRASH || FAIL
-test-decls/Unknown: CRASH || FAIL
-test-decls/Appearing: CRASH || FAIL
-test-decls/Absent: CRASH || FAIL
-test-debug/DebugStub: CRASH || FAIL
-test-decls/AbsentInPrototype: CRASH || FAIL
-test-decls/Reappearing: CRASH || FAIL
-test-debug/DebugInfo: CRASH || FAIL
-test-decls/ExistsInPrototype: CRASH || FAIL
-test-debug/BreakPointICStore: CRASH || FAIL
-test-debug/BreakPointICLoad: CRASH || FAIL
-test-debug/BreakPointICCall: CRASH || FAIL
-test-debug/BreakPointReturn: CRASH || FAIL
-test-debug/GCDuringBreakPointProcessing: CRASH || FAIL
-test-debug/BreakPointSurviveGC: CRASH || FAIL
-test-debug/BreakPointThroughJavaScript: CRASH || FAIL
-test-debug/ScriptBreakPointByNameThroughJavaScript: CRASH || FAIL
-test-debug/ScriptBreakPointByIdThroughJavaScript: CRASH || FAIL
-test-debug/EnableDisableScriptBreakPoint: CRASH || FAIL
-test-debug/ConditionalScriptBreakPoint: CRASH || FAIL
-test-debug/ScriptBreakPointIgnoreCount: CRASH || FAIL
-test-debug/ScriptBreakPointReload: CRASH || FAIL
-test-debug/ScriptBreakPointMultiple: CRASH || FAIL
-test-debug/RemoveBreakPointInBreak: CRASH || FAIL
-test-debug/DebugEvaluate: CRASH || FAIL
-test-debug/ScriptBreakPointLine: CRASH || FAIL
-test-debug/ScriptBreakPointLineOffset: CRASH || FAIL
-test-debug/DebugStepLinear: CRASH || FAIL
-test-debug/DebugStepKeyedLoadLoop: CRASH || FAIL
-test-debug/DebugStepKeyedStoreLoop: CRASH || FAIL
-test-debug/DebugStepLinearMixedICs: CRASH || FAIL
-test-debug/DebugStepFor: CRASH || FAIL
-test-debug/DebugStepIf: CRASH || FAIL
-test-debug/DebugStepSwitch: CRASH || FAIL
-test-debug/StepInOutSimple: CRASH || FAIL
-test-debug/StepInOutBranch: CRASH || FAIL
-test-debug/StepInOutTree: CRASH || FAIL
-test-debug/DebugStepNatives: CRASH || FAIL
-test-debug/DebugStepFunctionApply: CRASH || FAIL
-test-debug/DebugStepFunctionCall: CRASH || FAIL
-test-debug/StepWithException: CRASH || FAIL
-test-debug/DebugBreak: CRASH || FAIL
-test-debug/DisableBreak: CRASH || FAIL
-test-debug/MessageQueues: CRASH || FAIL
-test-debug/CallFunctionInDebugger: SKIP
-test-debug/RecursiveBreakpoints: CRASH || FAIL
-test-debug/DebuggerUnload: CRASH || FAIL
-test-debug/DebuggerHostDispatch: CRASH || FAIL
-test-debug/DebugBreakInMessageHandler: CRASH || FAIL
-test-debug/NoDebugBreakInAfterCompileMessageHandler: CRASH || FAIL
-test-api/Threading: CRASH || FAIL
-test-api/Threading2: PASS || TIMEOUT
-test-api/TryCatchSourceInfo: CRASH || FAIL
-test-api/RegExpInterruption: PASS || TIMEOUT
-test-api/RegExpStringModification: PASS || TIMEOUT
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 35ac031..e1caba3 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -7738,3 +7738,31 @@
 
   free(pixel_data);
 }
+
+THREADED_TEST(ScriptContextDependence) {
+  v8::HandleScope scope;
+  LocalContext c1;
+  const char *source = "foo";
+  v8::Handle<v8::Script> dep = v8::Script::Compile(v8::String::New(source));
+  v8::Handle<v8::Script> indep = v8::Script::New(v8::String::New(source));
+  c1->Global()->Set(v8::String::New("foo"), v8::Integer::New(100));
+  CHECK_EQ(dep->Run()->Int32Value(), 100);
+  CHECK_EQ(indep->Run()->Int32Value(), 100);
+  LocalContext c2;
+  c2->Global()->Set(v8::String::New("foo"), v8::Integer::New(101));
+  CHECK_EQ(dep->Run()->Int32Value(), 100);
+  CHECK_EQ(indep->Run()->Int32Value(), 101);
+}
+
+THREADED_TEST(StackTrace) {
+  v8::HandleScope scope;
+  LocalContext context;
+  v8::TryCatch try_catch;
+  const char *source = "function foo() { FAIL.FAIL; }; foo();";
+  v8::Handle<v8::String> src = v8::String::New(source);
+  v8::Handle<v8::String> origin = v8::String::New("stack-trace-test");
+  v8::Script::New(src, origin)->Run();
+  CHECK(try_catch.HasCaught());
+  v8::String::Utf8Value stack(try_catch.StackTrace());
+  CHECK(strstr(*stack, "at foo (stack-trace-test") != NULL);
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 9e2c38d..f5e4f3a 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -487,9 +487,7 @@
     CHECK_EQ(debug_break,
         Code::GetCodeFromTargetAddress(it1.it()->rinfo()->target_address()));
   } else {
-    // TODO(1240753): Make the test architecture independent or split
-    // parts of the debugger into architecture dependent files.
-    CHECK_EQ(0xE8, *(it1.rinfo()->pc()));
+    CHECK(Debug::IsDebugBreakAtReturn(it1.it()->rinfo()));
   }
 
   // Clear the break point and check that the debug break function is no longer
@@ -501,9 +499,7 @@
   it2.FindBreakLocationFromPosition(position);
   CHECK_EQ(mode, it2.it()->rinfo()->rmode());
   if (mode == v8::internal::RelocInfo::JS_RETURN) {
-    // TODO(1240753): Make the test architecture independent or split
-    // parts of the debugger into architecture dependent files.
-    CHECK_NE(0xE8, *(it2.rinfo()->pc()));
+    CHECK(!Debug::IsDebugBreakAtReturn(it2.it()->rinfo()));
   }
 }
 
@@ -5357,3 +5353,20 @@
   v8::Debug::SetMessageHandler2(NULL);
   CheckDebuggerUnloaded();
 }
+
+
+TEST(GetMirror) {
+  v8::HandleScope scope;
+  DebugLocalContext env;
+  v8::Handle<v8::Value> obj = v8::Debug::GetMirror(v8::String::New("hodja"));
+  v8::Handle<v8::Function> run_test = v8::Handle<v8::Function>::Cast(
+      v8::Script::New(
+          v8::String::New(
+              "function runTest(mirror) {"
+              "  return mirror.isString() && (mirror.length() == 5);"
+              "}"
+              ""
+              "runTest;"))->Run());
+  v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj);
+  CHECK(result->IsTrue());
+}
diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc
index 6c48f64..f083027 100644
--- a/test/cctest/test-decls.cc
+++ b/test/cctest/test-decls.cc
@@ -111,7 +111,7 @@
   if (is_initialized_) return;
   HandleScope scope;
   Local<FunctionTemplate> function = FunctionTemplate::New();
-  Local<Value> data = Integer::New(reinterpret_cast<intptr_t>(this));
+  Local<Value> data = External::New(this);
   GetHolder(function)->SetNamedPropertyHandler(&HandleGet,
                                                &HandleSet,
                                                &HandleHas,
@@ -179,8 +179,7 @@
 
 
 DeclarationContext* DeclarationContext::GetInstance(const AccessorInfo& info) {
-  Local<Value> data = info.Data();
-  return reinterpret_cast<DeclarationContext*>(Int32::Cast(*data)->Value());
+  return static_cast<DeclarationContext*>(External::Unwrap(info.Data()));
 }
 
 
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 6b5907c..37dbdd7 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -44,35 +44,26 @@
 
 static void CheckOddball(Object* obj, const char* string) {
   CHECK(obj->IsOddball());
-#ifndef V8_HOST_ARCH_64_BIT
-// TODO(X64): Reenable when native builtins work.
   bool exc;
   Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc);
   CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string)));
-#endif  // V8_HOST_ARCH_64_BIT
 }
 
 
 static void CheckSmi(int value, const char* string) {
-#ifndef V8_HOST_ARCH_64_BIT
-// TODO(X64): Reenable when native builtins work.
   bool exc;
   Object* print_string =
       *Execution::ToString(Handle<Object>(Smi::FromInt(value)), &exc);
   CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string)));
-#endif  // V8_HOST_ARCH_64_BIT
 }
 
 
 static void CheckNumber(double value, const char* string) {
   Object* obj = Heap::NumberFromDouble(value);
   CHECK(obj->IsNumber());
-#ifndef V8_HOST_ARCH_64_BIT
-// TODO(X64): Reenable when native builtins work.
   bool exc;
   Object* print_string = *Execution::ToString(Handle<Object>(obj), &exc);
   CHECK(String::cast(print_string)->IsEqualTo(CStrVector(string)));
-#endif  // V8_HOST_ARCH_64_BIT
 }
 
 
@@ -492,8 +483,11 @@
 static void CheckSymbols(const char** strings) {
   for (const char* string = *strings; *strings != 0; string = *strings++) {
     Object* a = Heap::LookupAsciiSymbol(string);
+    // LookupAsciiSymbol may return a failure if a GC is needed.
+    if (a->IsFailure()) continue;
     CHECK(a->IsSymbol());
     Object* b = Heap::LookupAsciiSymbol(string);
+    if (b->IsFailure()) continue;
     CHECK_EQ(b, a);
     CHECK(String::cast(b)->IsEqualTo(CStrVector(string)));
   }
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 8d8326c..89c7868 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -38,18 +38,21 @@
 #include "jsregexp.h"
 #include "regexp-macro-assembler.h"
 #include "regexp-macro-assembler-irregexp.h"
+#ifdef V8_NATIVE_REGEXP
 #ifdef V8_TARGET_ARCH_ARM
 #include "arm/regexp-macro-assembler-arm.h"
 #endif
 #ifdef V8_TARGET_ARCH_X64
-// No X64-implementation yet.
+#include "x64/macro-assembler-x64.h"
+#include "x64/regexp-macro-assembler-x64.h"
 #endif
 #ifdef V8_TARGET_ARCH_IA32
 #include "ia32/macro-assembler-ia32.h"
 #include "ia32/regexp-macro-assembler-ia32.h"
 #endif
+#else
 #include "interpreter-irregexp.h"
-
+#endif
 
 using namespace v8::internal;
 
@@ -599,75 +602,20 @@
 
 // Tests of interpreter.
 
-TEST(MacroAssembler) {
-  V8::Initialize(NULL);
-  byte codes[1024];
-  RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024));
-  // ^f(o)o.
-  Label fail, fail2, start;
-  uc16 foo_chars[3];
-  foo_chars[0] = 'f';
-  foo_chars[1] = 'o';
-  foo_chars[2] = 'o';
-  Vector<const uc16> foo(foo_chars, 3);
-  m.SetRegister(4, 42);
-  m.PushRegister(4, RegExpMacroAssembler::kNoStackLimitCheck);
-  m.AdvanceRegister(4, 42);
-  m.GoTo(&start);
-  m.Fail();
-  m.Bind(&start);
-  m.PushBacktrack(&fail2);
-  m.CheckCharacters(foo, 0, &fail, true);
-  m.WriteCurrentPositionToRegister(0, 0);
-  m.PushCurrentPosition();
-  m.AdvanceCurrentPosition(3);
-  m.WriteCurrentPositionToRegister(1, 0);
-  m.PopCurrentPosition();
-  m.AdvanceCurrentPosition(1);
-  m.WriteCurrentPositionToRegister(2, 0);
-  m.AdvanceCurrentPosition(1);
-  m.WriteCurrentPositionToRegister(3, 0);
-  m.Succeed();
 
-  m.Bind(&fail);
-  m.Backtrack();
-  m.Succeed();
-
-  m.Bind(&fail2);
-  m.PopRegister(0);
-  m.Fail();
-
-  v8::HandleScope scope;
-
-  Handle<String> source = Factory::NewStringFromAscii(CStrVector("^f(o)o"));
-  Handle<ByteArray> array = Handle<ByteArray>::cast(m.GetCode(source));
-  int captures[5];
-
-  const uc16 str1[] = {'f', 'o', 'o', 'b', 'a', 'r'};
-  Handle<String> f1_16 =
-      Factory::NewStringFromTwoByte(Vector<const uc16>(str1, 6));
-
-  CHECK(IrregexpInterpreter::Match(array, f1_16, captures, 0));
-  CHECK_EQ(0, captures[0]);
-  CHECK_EQ(3, captures[1]);
-  CHECK_EQ(1, captures[2]);
-  CHECK_EQ(2, captures[3]);
-  CHECK_EQ(84, captures[4]);
-
-  const uc16 str2[] = {'b', 'a', 'r', 'f', 'o', 'o'};
-  Handle<String> f2_16 =
-      Factory::NewStringFromTwoByte(Vector<const uc16>(str2, 6));
-
-  CHECK(!IrregexpInterpreter::Match(array, f2_16, captures, 0));
-  CHECK_EQ(42, captures[0]);
-}
-
-#ifdef V8_TARGET_ARCH_IA32  // IA32 Native Regexp only tests.
 #ifdef V8_NATIVE_REGEXP
 
+#ifdef V8_TARGET_ARCH_IA32
+typedef RegExpMacroAssemblerIA32 ArchRegExpMacroAssembler;
+#endif
+#ifdef V8_TARGET_ARCH_X64
+typedef RegExpMacroAssemblerX64 ArchRegExpMacroAssembler;
+#endif
+
 class ContextInitializer {
  public:
-  ContextInitializer() : env_(), scope_(), stack_guard_() {
+  ContextInitializer()
+      : env_(), scope_(), zone_(DELETE_ON_EXIT), stack_guard_() {
     env_ = v8::Context::New();
     env_->Enter();
   }
@@ -678,18 +626,19 @@
  private:
   v8::Persistent<v8::Context> env_;
   v8::HandleScope scope_;
+  v8::internal::ZoneScope zone_;
   v8::internal::StackGuard stack_guard_;
 };
 
 
-static RegExpMacroAssemblerIA32::Result ExecuteIA32(Code* code,
-                                                    String* input,
-                                                    int start_offset,
-                                                    const byte* input_start,
-                                                    const byte* input_end,
-                                                    int* captures,
-                                                    bool at_start) {
-  return RegExpMacroAssemblerIA32::Execute(
+static ArchRegExpMacroAssembler::Result Execute(Code* code,
+                                                String* input,
+                                                int start_offset,
+                                                const byte* input_start,
+                                                const byte* input_end,
+                                                int* captures,
+                                                bool at_start) {
+  return NativeRegExpMacroAssembler::Execute(
       code,
       input,
       start_offset,
@@ -700,11 +649,11 @@
 }
 
 
-TEST(MacroAssemblerIA32Success) {
+TEST(MacroAssemblerNativeSuccess) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4);
 
   m.Succeed();
 
@@ -718,16 +667,16 @@
   const byte* start_adr =
       reinterpret_cast<const byte*>(seq_input->GetCharsAddress());
 
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + seq_input->length(),
-                  captures,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + seq_input->length(),
+              captures,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(-1, captures[0]);
   CHECK_EQ(-1, captures[1]);
   CHECK_EQ(-1, captures[2]);
@@ -735,11 +684,11 @@
 }
 
 
-TEST(MacroAssemblerIA32Simple) {
+TEST(MacroAssemblerNativeSimple) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4);
 
   uc16 foo_chars[3] = {'f', 'o', 'o'};
   Vector<const uc16> foo(foo_chars, 3);
@@ -762,16 +711,16 @@
   Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
   Address start_adr = seq_input->GetCharsAddress();
 
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  captures,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              captures,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(0, captures[0]);
   CHECK_EQ(3, captures[1]);
   CHECK_EQ(-1, captures[2]);
@@ -781,23 +730,23 @@
   seq_input = Handle<SeqAsciiString>::cast(input);
   start_adr = seq_input->GetCharsAddress();
 
-  result = ExecuteIA32(*code,
-                       *input,
-                       0,
-                       start_adr,
-                       start_adr + input->length(),
-                       captures,
-                       true);
+  result = Execute(*code,
+                   *input,
+                   0,
+                   start_adr,
+                   start_adr + input->length(),
+                   captures,
+                   true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::FAILURE, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result);
 }
 
 
-TEST(MacroAssemblerIA32SimpleUC16) {
+TEST(MacroAssemblerNativeSimpleUC16) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::UC16, 4);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 4);
 
   uc16 foo_chars[3] = {'f', 'o', 'o'};
   Vector<const uc16> foo(foo_chars, 3);
@@ -822,16 +771,16 @@
   Handle<SeqTwoByteString> seq_input = Handle<SeqTwoByteString>::cast(input);
   Address start_adr = seq_input->GetCharsAddress();
 
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  captures,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              captures,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(0, captures[0]);
   CHECK_EQ(3, captures[1]);
   CHECK_EQ(-1, captures[2]);
@@ -842,23 +791,23 @@
   seq_input = Handle<SeqTwoByteString>::cast(input);
   start_adr = seq_input->GetCharsAddress();
 
-  result = ExecuteIA32(*code,
-                       *input,
-                       0,
-                       start_adr,
-                       start_adr + input->length() * 2,
-                       captures,
-                       true);
+  result = Execute(*code,
+                   *input,
+                   0,
+                   start_adr,
+                   start_adr + input->length() * 2,
+                   captures,
+                   true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::FAILURE, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result);
 }
 
 
-TEST(MacroAssemblerIA32Backtrack) {
+TEST(MacroAssemblerNativeBacktrack) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0);
 
   Label fail;
   Label backtrack;
@@ -879,24 +828,24 @@
   Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
   Address start_adr = seq_input->GetCharsAddress();
 
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  NULL,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              NULL,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::FAILURE, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result);
 }
 
 
-TEST(MacroAssemblerIA32BackReferenceASCII) {
+TEST(MacroAssemblerNativeBackReferenceASCII) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 3);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 3);
 
   m.WriteCurrentPositionToRegister(0, 0);
   m.AdvanceCurrentPosition(2);
@@ -922,27 +871,27 @@
   Address start_adr = seq_input->GetCharsAddress();
 
   int output[3];
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  output,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              output,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(0, output[0]);
   CHECK_EQ(2, output[1]);
   CHECK_EQ(6, output[2]);
 }
 
 
-TEST(MacroAssemblerIA32BackReferenceUC16) {
+TEST(MacroAssemblerNativeBackReferenceUC16) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::UC16, 3);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::UC16, 3);
 
   m.WriteCurrentPositionToRegister(0, 0);
   m.AdvanceCurrentPosition(2);
@@ -970,8 +919,8 @@
   Address start_adr = seq_input->GetCharsAddress();
 
   int output[3];
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
                   *input,
                   0,
                   start_adr,
@@ -979,7 +928,7 @@
                   output,
                   true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(0, output[0]);
   CHECK_EQ(2, output[1]);
   CHECK_EQ(6, output[2]);
@@ -987,11 +936,11 @@
 
 
 
-TEST(MacroAssemblerIA32AtStart) {
+TEST(MacroAssemblernativeAtStart) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0);
 
   Label not_at_start, newline, fail;
   m.CheckNotAtStart(&not_at_start);
@@ -1022,34 +971,34 @@
   Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
   Address start_adr = seq_input->GetCharsAddress();
 
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  NULL,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              NULL,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
 
-  result = ExecuteIA32(*code,
-                       *input,
-                       3,
-                       start_adr + 3,
-                       start_adr + input->length(),
-                       NULL,
-                       false);
+  result = Execute(*code,
+                   *input,
+                   3,
+                   start_adr + 3,
+                   start_adr + input->length(),
+                   NULL,
+                   false);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
 }
 
 
-TEST(MacroAssemblerIA32BackRefNoCase) {
+TEST(MacroAssemblerNativeBackRefNoCase) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 4);
 
   Label fail, succ;
 
@@ -1084,16 +1033,16 @@
   Address start_adr = seq_input->GetCharsAddress();
 
   int output[4];
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  output,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              output,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(0, output[0]);
   CHECK_EQ(12, output[1]);
   CHECK_EQ(0, output[2]);
@@ -1102,11 +1051,11 @@
 
 
 
-TEST(MacroAssemblerIA32Registers) {
+TEST(MacroAssemblerNativeRegisters) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 5);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 5);
 
   uc16 foo_chars[3] = {'f', 'o', 'o'};
   Vector<const uc16> foo(foo_chars, 3);
@@ -1184,8 +1133,8 @@
   Address start_adr = seq_input->GetCharsAddress();
 
   int output[5];
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
                   *input,
                   0,
                   start_adr,
@@ -1193,7 +1142,7 @@
                   output,
                   true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(0, output[0]);
   CHECK_EQ(3, output[1]);
   CHECK_EQ(6, output[2]);
@@ -1202,11 +1151,11 @@
 }
 
 
-TEST(MacroAssemblerIA32StackOverflow) {
+TEST(MacroAssemblerStackOverflow) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 0);
 
   Label loop;
   m.Bind(&loop);
@@ -1224,26 +1173,26 @@
   Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
   Address start_adr = seq_input->GetCharsAddress();
 
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  NULL,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              NULL,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::EXCEPTION, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::EXCEPTION, result);
   CHECK(Top::has_pending_exception());
   Top::clear_pending_exception();
 }
 
 
-TEST(MacroAssemblerIA32LotsOfRegisters) {
+TEST(MacroAssemblerNativeLotsOfRegisters) {
   v8::V8::Initialize();
   ContextInitializer initializer;
 
-  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 2);
+  ArchRegExpMacroAssembler m(NativeRegExpMacroAssembler::ASCII, 2);
 
   // At least 2048, to ensure the allocated space for registers
   // span one full page.
@@ -1270,24 +1219,88 @@
   Address start_adr = seq_input->GetCharsAddress();
 
   int captures[2];
-  RegExpMacroAssemblerIA32::Result result =
-      ExecuteIA32(*code,
-                  *input,
-                  0,
-                  start_adr,
-                  start_adr + input->length(),
-                  captures,
-                  true);
+  NativeRegExpMacroAssembler::Result result =
+      Execute(*code,
+              *input,
+              0,
+              start_adr,
+              start_adr + input->length(),
+              captures,
+              true);
 
-  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
   CHECK_EQ(0, captures[0]);
   CHECK_EQ(42, captures[1]);
 
   Top::clear_pending_exception();
 }
 
-#endif  // V8_REGEXP_NATIVE
-#endif  // V8_TARGET_ARCH_IA32
+#else  // ! V8_REGEX_NATIVE
+
+TEST(MacroAssembler) {
+  V8::Initialize(NULL);
+  byte codes[1024];
+  RegExpMacroAssemblerIrregexp m(Vector<byte>(codes, 1024));
+  // ^f(o)o.
+  Label fail, fail2, start;
+  uc16 foo_chars[3];
+  foo_chars[0] = 'f';
+  foo_chars[1] = 'o';
+  foo_chars[2] = 'o';
+  Vector<const uc16> foo(foo_chars, 3);
+  m.SetRegister(4, 42);
+  m.PushRegister(4, RegExpMacroAssembler::kNoStackLimitCheck);
+  m.AdvanceRegister(4, 42);
+  m.GoTo(&start);
+  m.Fail();
+  m.Bind(&start);
+  m.PushBacktrack(&fail2);
+  m.CheckCharacters(foo, 0, &fail, true);
+  m.WriteCurrentPositionToRegister(0, 0);
+  m.PushCurrentPosition();
+  m.AdvanceCurrentPosition(3);
+  m.WriteCurrentPositionToRegister(1, 0);
+  m.PopCurrentPosition();
+  m.AdvanceCurrentPosition(1);
+  m.WriteCurrentPositionToRegister(2, 0);
+  m.AdvanceCurrentPosition(1);
+  m.WriteCurrentPositionToRegister(3, 0);
+  m.Succeed();
+
+  m.Bind(&fail);
+  m.Backtrack();
+  m.Succeed();
+
+  m.Bind(&fail2);
+  m.PopRegister(0);
+  m.Fail();
+
+  v8::HandleScope scope;
+
+  Handle<String> source = Factory::NewStringFromAscii(CStrVector("^f(o)o"));
+  Handle<ByteArray> array = Handle<ByteArray>::cast(m.GetCode(source));
+  int captures[5];
+
+  const uc16 str1[] = {'f', 'o', 'o', 'b', 'a', 'r'};
+  Handle<String> f1_16 =
+      Factory::NewStringFromTwoByte(Vector<const uc16>(str1, 6));
+
+  CHECK(IrregexpInterpreter::Match(array, f1_16, captures, 0));
+  CHECK_EQ(0, captures[0]);
+  CHECK_EQ(3, captures[1]);
+  CHECK_EQ(1, captures[2]);
+  CHECK_EQ(2, captures[3]);
+  CHECK_EQ(84, captures[4]);
+
+  const uc16 str2[] = {'b', 'a', 'r', 'f', 'o', 'o'};
+  Handle<String> f2_16 =
+      Factory::NewStringFromTwoByte(Vector<const uc16>(str2, 6));
+
+  CHECK(!IrregexpInterpreter::Match(array, f2_16, captures, 0));
+  CHECK_EQ(42, captures[0]);
+}
+
+#endif  // ! V8_REGEXP_NATIVE
 
 
 TEST(AddInverseToTable) {
diff --git a/test/message/message.status b/test/message/message.status
index 9afaa0f..fc2896b 100644
--- a/test/message/message.status
+++ b/test/message/message.status
@@ -29,16 +29,3 @@
 
 # All tests in the bug directory are expected to fail.
 bugs: FAIL
-
-[ $arch == x64 ]
-
-simple-throw: FAIL
-try-catch-finally-throw-in-catch-and-finally: FAIL
-try-catch-finally-throw-in-catch: FAIL
-try-catch-finally-throw-in-finally: FAIL
-try-finally-throw-in-finally: FAIL
-try-finally-throw-in-try-and-finally: FAIL
-try-finally-throw-in-try: FAIL
-overwritten-builtins: FAIL
-regress/regress-73: FAIL
-regress/regress-75: FAIL
diff --git a/test/mjsunit/div-mod.js b/test/mjsunit/div-mod.js
index 39fab27..a8a19b3 100644
--- a/test/mjsunit/div-mod.js
+++ b/test/mjsunit/div-mod.js
@@ -48,7 +48,7 @@
   divmod(div_func, mod_func, 0, divisor);
   divmod(div_func, mod_func, 1 / 0, divisor);
   // Floating point number test.
-  for (exp = -1024; exp <= 1024; exp += 4) {
+  for (exp = -1024; exp <= 1024; exp += 8) {
     divmod(div_func, mod_func, Math.pow(2, exp), divisor);
     divmod(div_func, mod_func, 0.9999999 * Math.pow(2, exp), divisor);
     divmod(div_func, mod_func, 1.0000001 * Math.pow(2, exp), divisor);
@@ -76,13 +76,7 @@
   8,
   9,
   10,
-  // These ones in the middle don't add much apart from slowness to the test.
   0x1000000,
-  0x2000000,
-  0x4000000,
-  0x8000000,
-  0x10000000,
-  0x20000000,
   0x40000000,
   12,
   60,
@@ -92,4 +86,3 @@
 for (var i = 0; i < divisors.length; i++) {
   run_tests_for(divisors[i]);
 }
-
diff --git a/test/mjsunit/mjsunit.js b/test/mjsunit/mjsunit.js
index 2c52a31..1fb3f02 100644
--- a/test/mjsunit/mjsunit.js
+++ b/test/mjsunit/mjsunit.js
@@ -179,9 +179,13 @@
 
 function assertDoesNotThrow(code) {
   try {
-    eval(code);
+    if (typeof code == 'function') {
+      code();
+    } else {
+      eval(code);
+    }
   } catch (e) {
-    assertTrue(false, "threw an exception");
+    assertTrue(false, "threw an exception: " + (e.message || e));
   }
 }
 
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 6853cdc..4bf67e8 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -73,33 +73,3 @@
 
 # Times out often in release mode on ARM.
 array-splice: PASS || TIMEOUT
-
-[ $arch == x64 ]
-
-debug-backtrace: CRASH || FAIL
-debug-backtrace-text: CRASH || FAIL
-debug-multiple-breakpoints: CRASH || FAIL
-debug-breakpoints: CRASH || FAIL
-debug-changebreakpoint: CRASH || FAIL
-debug-clearbreakpoint: CRASH || FAIL
-debug-conditional-breakpoints: CRASH || FAIL
-debug-constructor: CRASH || FAIL
-debug-continue: CRASH || FAIL
-debug-enable-disable-breakpoints: CRASH || FAIL
-debug-evaluate-recursive: CRASH || FAIL
-debug-event-listener: CRASH || FAIL
-debug-evaluate: CRASH || FAIL
-debug-ignore-breakpoints: CRASH || FAIL
-debug-setbreakpoint: CRASH || FAIL
-debug-step-stub-callfunction: CRASH || FAIL
-debug-step: CRASH || FAIL
-debug-stepin-builtin: CRASH || FAIL
-debug-stepin-constructor: CRASH || FAIL
-debug-stepin-function-call: CRASH || FAIL
-debug-stepin-accessor: CRASH || FAIL
-fuzz-natives: PASS || TIMEOUT
-debug-handle: CRASH || FAIL
-debug-clearbreakpointgroup: CRASH || FAIL
-regress/regress-269: CRASH || FAIL
-regress/regress-998565: CRASH || FAIL
-tools/tickprocessor: PASS || CRASH || FAIL
diff --git a/test/mjsunit/simple-constructor.js b/test/mjsunit/simple-constructor.js
new file mode 100755
index 0000000..b26d651
--- /dev/null
+++ b/test/mjsunit/simple-constructor.js
@@ -0,0 +1,78 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function props(x) {
+  var array = [];
+  for (var p in x) array.push(p);
+  return array.sort();
+}
+
+function f1() {
+  this.x = 1;
+}
+
+function f2(x) {
+  this.x = x;
+}
+
+function f3(x) {
+  this.x = x;
+  this.y = 1;
+  this.z = f1;
+}
+
+function f4(x) {
+  this.x = x;
+  this.y = 1;
+  if (x == 1) return;
+  this.z = f1;
+}
+
+o1_1 = new f1();
+o1_2 = new f1();
+assertArrayEquals(["x"], props(o1_1));
+assertArrayEquals(["x"], props(o1_2));
+
+o2_1 = new f2(0);
+o2_2 = new f2(0);
+assertArrayEquals(["x"], props(o2_1));
+assertArrayEquals(["x"], props(o2_2));
+
+o3_1 = new f3(0);
+o3_2 = new f3(0);
+assertArrayEquals(["x", "y", "z"], props(o3_1));
+assertArrayEquals(["x", "y", "z"], props(o3_2));
+
+o4_0_1 = new f4(0);
+o4_0_2 = new f4(0);
+assertArrayEquals(["x", "y", "z"], props(o4_0_1));
+assertArrayEquals(["x", "y", "z"], props(o4_0_2));
+
+o4_1_1 = new f4(1);
+o4_1_2 = new f4(1);
+assertArrayEquals(["x", "y"], props(o4_1_1));
+assertArrayEquals(["x", "y"], props(o4_1_2));
diff --git a/test/mjsunit/stack-traces.js b/test/mjsunit/stack-traces.js
index 3bb5755..d7ece2c 100644
--- a/test/mjsunit/stack-traces.js
+++ b/test/mjsunit/stack-traces.js
@@ -103,22 +103,24 @@
 
 // Utility function for testing that the expected strings occur
 // in the stack trace produced when running the given function.
-function testTrace(fun, expected, unexpected) {
+function testTrace(name, fun, expected, unexpected) {
   var threw = false;
   try {
     fun();
   } catch (e) {
     for (var i = 0; i < expected.length; i++) {
-      assertTrue(e.stack.indexOf(expected[i]) != -1);
+      assertTrue(e.stack.indexOf(expected[i]) != -1,
+                 name + " doesn't contain expected[" + i + "]");
     }
     if (unexpected) {
       for (var i = 0; i < unexpected.length; i++) {
-        assertEquals(e.stack.indexOf(unexpected[i]), -1);
+        assertEquals(e.stack.indexOf(unexpected[i]), -1,
+                     name + " contains unexpected[" + i + "]");
       }
     }
     threw = true;
   }
-  assertTrue(threw);
+  assertTrue(threw, name + " didn't throw");
 }
 
 // Test that the error constructor is not shown in the trace
@@ -127,10 +129,11 @@
   try {
     FAIL;
   } catch (e) {
-    assertEquals(-1, e.stack.indexOf('at new ReferenceError'));
+    assertEquals(-1, e.stack.indexOf('at new ReferenceError'),
+                 "CallerCensorship contained new ReferenceError");
     threw = true;
   }
-  assertTrue(threw);
+  assertTrue(threw, "CallerCensorship didn't throw");
 }
 
 // Test that the explicit constructor call is shown in the trace
@@ -143,10 +146,11 @@
       }
     });
   } catch (e) {
-    assertTrue(e.stack.indexOf('at new ReferenceError') != -1);
+    assertTrue(e.stack.indexOf('at new ReferenceError') != -1,
+               "UnintendedCallerCensorship didn't contain new ReferenceError");
     threw = true;
   }
-  assertTrue(threw);
+  assertTrue(threw, "UnintendedCallerCensorship didn't throw");
 }
 
 // If an error occurs while the stack trace is being formatted it should
@@ -161,9 +165,10 @@
     n.foo();
   } catch (e) {
     threw = true;
-    assertTrue(e.stack.indexOf('<error: ReferenceError') != -1);
+    assertTrue(e.stack.indexOf('<error: ReferenceError') != -1,
+               "ErrorsDuringFormatting didn't contain error: ReferenceError");
   }
-  assertTrue(threw);
+  assertTrue(threw, "ErrorsDuringFormatting didn't throw");
   threw = false;
   // Now we can't even format the message saying that we couldn't format
   // the stack frame.  Put that in your pipe and smoke it!
@@ -172,26 +177,28 @@
     n.foo();
   } catch (e) {
     threw = true;
-    assertTrue(e.stack.indexOf('<error>') != -1);
+    assertTrue(e.stack.indexOf('<error>') != -1,
+               "ErrorsDuringFormatting didn't contain <error>");
   }
-  assertTrue(threw);
+  assertTrue(threw, "ErrorsDuringFormatting didnt' throw (2)");
 }
 
-testTrace(testArrayNative, ["Array.map (native)"]);
-testTrace(testNested, ["at one", "at two", "at three"]);
-testTrace(testMethodNameInference, ["at Foo.bar"]);
-testTrace(testImplicitConversion, ["at Nirk.valueOf"]);
-testTrace(testEval, ["at Doo (eval at testEval"]);
-testTrace(testNestedEval, ["eval at Inner (eval at Outer"]);
-testTrace(testValue, ["at Number.causeError"]);
-testTrace(testConstructor, ["new Plonk"]);
-testTrace(testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
-testTrace(testAnonymousMethod, ["Array.<anonymous>"]);
-testTrace(testDefaultCustomError, ["hep-hey", "new CustomError"],
-    ["collectStackTrace"]);
-testTrace(testStrippedCustomError, ["hep-hey"], ["new CustomError",
-    "collectStackTrace"]);
 
+testTrace("testArrayNative", testArrayNative, ["Array.map (native)"]);
+testTrace("testNested", testNested, ["at one", "at two", "at three"]);
+testTrace("testMethodNameInference", testMethodNameInference, ["at Foo.bar"]);
+testTrace("testImplicitConversion", testImplicitConversion, ["at Nirk.valueOf"]);
+testTrace("testEval", testEval, ["at Doo (eval at testEval"]);
+testTrace("testNestedEval", testNestedEval, ["eval at Inner (eval at Outer"]);
+testTrace("testValue", testValue, ["at Number.causeError"]);
+testTrace("testConstructor", testConstructor, ["new Plonk"]);
+testTrace("testRenamedMethod", testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
+testTrace("testAnonymousMethod", testAnonymousMethod, ["Array.<anonymous>"]);
+testTrace("testDefaultCustomError", testDefaultCustomError,
+    ["hep-hey", "new CustomError"],
+    ["collectStackTrace"]);
+testTrace("testStrippedCustomError", testStrippedCustomError, ["hep-hey"],
+    ["new CustomError", "collectStackTrace"]);
 testCallerCensorship();
 testUnintendedCallerCensorship();
 testErrorsDuringFormatting();
diff --git a/test/mjsunit/tools/logreader.js b/test/mjsunit/tools/logreader.js
index dfd7f9f..8ed5ffd 100644
--- a/test/mjsunit/tools/logreader.js
+++ b/test/mjsunit/tools/logreader.js
@@ -80,3 +80,19 @@
   assertEquals('bbbbaaaa', reader.expandBackRef_('bbbb#2:4'));
   assertEquals('"#1:1"', reader.expandBackRef_('"#1:1"'));
 })();
+
+
+// See http://code.google.com/p/v8/issues/detail?id=420
+(function testReadingTruncatedLog() {
+  // Having an incorrect event in the middle of a log should throw an exception.
+  var reader1 = new devtools.profiler.LogReader({});
+  assertThrows(function() {
+    reader1.processLogChunk('alias,a,b\nxxxx\nalias,c,d\n');
+  });
+
+  // But having it as the last record should not.
+  var reader2 = new devtools.profiler.LogReader({});
+  assertDoesNotThrow(function() {
+    reader2.processLogChunk('alias,a,b\nalias,c,d\nxxxx');
+  });
+})();
diff --git a/test/mjsunit/tools/tickprocessor.js b/test/mjsunit/tools/tickprocessor.js
index 00c3fb1..83bdac8 100644
--- a/test/mjsunit/tools/tickprocessor.js
+++ b/test/mjsunit/tools/tickprocessor.js
@@ -227,6 +227,78 @@
 })();
 
 
+// http://code.google.com/p/v8/issues/detail?id=427
+(function testWindowsProcessExeAndDllMapFile() {
+  function exeSymbols(exeName) {
+    return [
+      ' 0000:00000000       ___ImageBase               00400000     <linker-defined>',
+      ' 0001:00000780       ?RunMain@@YAHHQAPAD@Z      00401780 f   shell.obj',
+      ' 0001:00000ac0       _main                      00401ac0 f   shell.obj',
+      ''
+    ].join('\r\n');
+  }
+
+  function dllSymbols(dllName) {
+    return [
+      ' 0000:00000000       ___ImageBase               01c30000     <linker-defined>',
+      ' 0001:00000780       _DllMain@12                01c31780 f   libcmt:dllmain.obj',
+      ' 0001:00000ac0       ___DllMainCRTStartup       01c31ac0 f   libcmt:dllcrt0.obj',
+      ''
+    ].join('\r\n');
+  }
+
+  var oldRead = read;
+
+  read = exeSymbols;
+  var exe_exe_syms = [];
+  (new WindowsCppEntriesProvider()).parseVmSymbols(
+      'chrome.exe', 0x00400000, 0x00472000,
+      function (name, start, end) {
+        exe_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
+      });
+  assertEquals(
+      [['RunMain', 0x00401780, 0x00401ac0],
+       ['_main', 0x00401ac0, 0x00472000]],
+      exe_exe_syms, '.exe with .exe symbols');
+
+  read = dllSymbols;
+  var exe_dll_syms = [];
+  (new WindowsCppEntriesProvider()).parseVmSymbols(
+      'chrome.exe', 0x00400000, 0x00472000,
+      function (name, start, end) {
+        exe_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
+      });
+  assertEquals(
+      [],
+      exe_dll_syms, '.exe with .dll symbols');
+
+  read = dllSymbols;
+  var dll_dll_syms = [];
+  (new WindowsCppEntriesProvider()).parseVmSymbols(
+      'chrome.dll', 0x01c30000, 0x02b80000,
+      function (name, start, end) {
+        dll_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
+      });
+  assertEquals(
+      [['_DllMain@12', 0x01c31780, 0x01c31ac0],
+       ['___DllMainCRTStartup', 0x01c31ac0, 0x02b80000]],
+      dll_dll_syms, '.dll with .dll symbols');
+
+  read = exeSymbols;
+  var dll_exe_syms = [];
+  (new WindowsCppEntriesProvider()).parseVmSymbols(
+      'chrome.dll', 0x01c30000, 0x02b80000,
+      function (name, start, end) {
+        dll_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
+      });
+  assertEquals(
+      [],
+      dll_exe_syms, '.dll with .exe symbols');
+
+  read = oldRead;
+})();
+
+
 function CppEntriesProviderMock() {
 };
 
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index c4628a0..a1551dc 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -278,6 +278,11 @@
 js1_2/regexp/endLine: FAIL_OK
 
 
+# To be compatible with safari typeof a regexp yields 'function';
+# in firefox it yields 'object'.
+js1_2/function/regexparg-1: FAIL_OK
+
+
 # Date trouble?
 js1_5/Date/regress-301738-02: FAIL_OK
 
@@ -803,10 +808,3 @@
 ecma/Expressions/11.10-3: SKIP
 ecma/Expressions/11.7.1: SKIP
 ecma_3/RegExp/regress-209067: SKIP
-
-[ $ARCH == x64 ]
-
-# Tests that fail on the 64-bit port.  This section should be empty
-# when the 64-bit port is fully debugged.
-
-js1_2/regexp/regress-9141: FAIL
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index 365d87c..b0c3331 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -32,6 +32,7 @@
     'gcc_version%': 'unknown',
     'target_arch%': 'ia32',
     'v8_use_snapshot%': 'true',
+    'v8_regexp%': 'native',
   },
   'includes': [
     '../../../build/common.gypi',
@@ -55,6 +56,7 @@
       ['target_arch=="x64"', {
         'defines': [
           'V8_TARGET_ARCH_X64',
+          'V8_NATIVE_REGEXP',
         ],
       }],
     ],
@@ -428,14 +430,18 @@
             '../../src/ia32/jump-target-ia32.cc',
             '../../src/ia32/macro-assembler-ia32.cc',
             '../../src/ia32/macro-assembler-ia32.h',
-            '../../src/ia32/regexp-macro-assembler-ia32.cc',
-            '../../src/ia32/regexp-macro-assembler-ia32.h',
             '../../src/ia32/register-allocator-ia32.cc',
             '../../src/ia32/stub-cache-ia32.cc',
             '../../src/ia32/virtual-frame-ia32.cc',
             '../../src/ia32/virtual-frame-ia32.h',
           ],
         }],
+        ['target_arch=="ia32" and v8_regexp=="native"', {
+          'sources': [
+            '../../src/ia32/regexp-macro-assembler-ia32.cc',
+            '../../src/ia32/regexp-macro-assembler-ia32.h',
+          ],
+        }],
         ['target_arch=="x64"', {
           'include_dirs+': [
             '../../src/x64',
@@ -457,14 +463,18 @@
             '../../src/x64/jump-target-x64.cc',
             '../../src/x64/macro-assembler-x64.cc',
             '../../src/x64/macro-assembler-x64.h',
-            #'../../src/x64/regexp-macro-assembler-x64.cc',
-            #'../../src/x64/regexp-macro-assembler-x64.h',
             '../../src/x64/register-allocator-x64.cc',
             '../../src/x64/stub-cache-x64.cc',
             '../../src/x64/virtual-frame-x64.cc',
             '../../src/x64/virtual-frame-x64.h',
           ],
         }],
+        ['target_arch=="x64" and v8_regexp=="native"', {
+          'sources': [
+            '../../src/x64/regexp-macro-assembler-x64.cc',
+            '../../src/x64/regexp-macro-assembler-x64.h',
+          ],
+        }],
         ['OS=="linux"', {
             'link_settings': {
               'libraries': [
diff --git a/tools/logreader.js b/tools/logreader.js
index 78085a4..88ab907 100644
--- a/tools/logreader.js
+++ b/tools/logreader.js
@@ -294,8 +294,11 @@
       this.dispatchLogRow_(fields);
     }
   } catch (e) {
-    this.printError('line ' + (i + 1) + ': ' + (e.message || e));
-    throw e;
+    // An error on the last line is acceptable since log file can be truncated.
+    if (i < n - 1) {
+      this.printError('line ' + (i + 1) + ': ' + (e.message || e));
+      throw e;
+    }
   }
 };
 
diff --git a/tools/mac-nm b/tools/mac-nm
index 9c18177..07efb07 100755
--- a/tools/mac-nm
+++ b/tools/mac-nm
@@ -12,7 +12,7 @@
 # needs to be parsed, which requires a lot of knowledge to be coded in.
 
 if [ "`which c++filt`" == "" ]; then
-  nm $@
+  nm "$@"
 else
-  nm $@ | c++filt -p -i
+  nm "$@" | c++filt -p -i
 fi
diff --git a/tools/tickprocessor.js b/tools/tickprocessor.js
index 34c6195..72b3059 100644
--- a/tools/tickprocessor.js
+++ b/tools/tickprocessor.js
@@ -499,19 +499,32 @@
 inherits(WindowsCppEntriesProvider, CppEntriesProvider);
 
 
-WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.exe$/;
+WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.([^.]+)$/;
 
 
 WindowsCppEntriesProvider.FUNC_RE =
-    /^ 0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/;
+    /^\s+0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/;
+
+
+WindowsCppEntriesProvider.IMAGE_BASE_RE =
+    /^\s+0000:00000000\s+___ImageBase\s+([0-9a-fA-F]{8}).*$/;
+
+
+// This is almost a constant on Windows.
+WindowsCppEntriesProvider.EXE_IMAGE_BASE = 0x00400000;
 
 
 WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) {
   var fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE);
-  // Only try to load symbols for the .exe file.
   if (!fileNameFields) return;
   var mapFileName = fileNameFields[1] + '.map';
-  this.symbols = readFile(mapFileName);
+  this.moduleType_ = fileNameFields[2].toLowerCase();
+  try {
+    this.symbols = read(mapFileName);
+  } catch (e) {
+    // If .map file cannot be found let's not panic.
+    this.symbols = '';
+  }
 };
 
 
@@ -523,6 +536,18 @@
 
   var line = this.symbols.substring(this.parsePos, lineEndPos);
   this.parsePos = lineEndPos + 2;
+
+  // Image base entry is above all other symbols, so we can just
+  // terminate parsing.
+  var imageBaseFields = line.match(WindowsCppEntriesProvider.IMAGE_BASE_RE);
+  if (imageBaseFields) {
+    var imageBase = parseInt(imageBaseFields[1], 16);
+    if ((this.moduleType_ == 'exe') !=
+        (imageBase == WindowsCppEntriesProvider.EXE_IMAGE_BASE)) {
+      return false;
+    }
+  }
+
   var fields = line.match(WindowsCppEntriesProvider.FUNC_RE);
   return fields ?
       { name: this.unmangleName(fields[1]), start: parseInt(fields[2], 16) } :
diff --git a/tools/visual_studio/common.vsprops b/tools/visual_studio/common.vsprops
index f131a4a..d23e4fc 100644
--- a/tools/visual_studio/common.vsprops
+++ b/tools/visual_studio/common.vsprops
@@ -10,7 +10,7 @@
 	<Tool
 		Name="VCCLCompilerTool"
 		AdditionalIncludeDirectories="$(ProjectDir)\..\..\src;$(IntDir)\DerivedSources"
-		PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;_HAS_EXCEPTIONS=0;ENABLE_LOGGING_AND_PROFILING"
+		PreprocessorDefinitions="WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_HAS_EXCEPTIONS=0;ENABLE_LOGGING_AND_PROFILING"
 		MinimalRebuild="false"
 		ExceptionHandling="0"
 		RuntimeTypeInfo="false"
diff --git a/tools/visual_studio/d8_x64.vcproj b/tools/visual_studio/d8_x64.vcproj
new file mode 100644
index 0000000..dd2b83d
--- /dev/null
+++ b/tools/visual_studio/d8_x64.vcproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="d8"
+	ProjectGUID="{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}"
+	RootNamespace="d8"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\..\src\d8.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\src\d8.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\src\d8-debug.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\src\d8-debug.h"
+			>
+		</File>
+		<File
+			RelativePath="..\..\src\d8-windows.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\src\d8.js"
+			>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Processing js files..."
+						CommandLine=".\d8js2c.cmd ..\..\src &quot;$(IntDir)\DerivedSources&quot;"
+												Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Processing js files..."
+						CommandLine=".\d8js2c.cmd ..\..\src &quot;$(IntDir)\DerivedSources&quot;"
+						Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+					/>
+				</FileConfiguration>
+		</File>
+		<Filter
+			Name="generated files"
+			>
+			<File
+				RelativePath="$(IntDir)\DerivedSources\natives.cc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/ia32.vsprops b/tools/visual_studio/ia32.vsprops
index aff0871..f48e808 100644
--- a/tools/visual_studio/ia32.vsprops
+++ b/tools/visual_studio/ia32.vsprops
@@ -6,6 +6,6 @@
 	>
 	<Tool
 		Name="VCCLCompilerTool"
-		PreprocessorDefinitions="V8_TARGET_ARCH_IA32;V8_NATIVE_REGEXP"
+		PreprocessorDefinitions="_USE_32BIT_TIME_T;V8_TARGET_ARCH_IA32;V8_NATIVE_REGEXP"
 	/>
 </VisualStudioPropertySheet>
diff --git a/tools/visual_studio/v8_base_x64.vcproj b/tools/visual_studio/v8_base_x64.vcproj
new file mode 100644
index 0000000..1e27824
--- /dev/null
+++ b/tools/visual_studio/v8_base_x64.vcproj
@@ -0,0 +1,963 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8_base"
+	ProjectGUID="{EC8B7909-62AF-470D-A75D-E1D89C837142}"
+	RootNamespace="v8_base"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="dtoa"
+			>
+			<File
+				RelativePath="..\..\src\dtoa-config.c"
+				>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableSpecificWarnings="4018;4244"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						DisableSpecificWarnings="4018;4244"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="src"
+			>
+			<File
+				RelativePath="..\..\src\accessors.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\accessors.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\allocation.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\allocation.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\api.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\api.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\arguments.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\assembler-x64-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\assembler-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\assembler-x64.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-macro-assembler-irregexp-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-stack.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\assembler.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\assembler.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ast.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ast.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\bootstrapper.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\bootstrapper.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\builtins-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\builtins.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\builtins.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\bytecodes-irregexp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\cfg-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\cfg.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\cfg.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\char-predicates-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\char-predicates.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\checks.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\checks.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\code-stubs.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\code-stubs.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\code.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\codegen-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\codegen-x64.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\codegen-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\codegen.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\codegen.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\compilation-cache.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\compilation-cache.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\compiler.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\compiler.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\contexts.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\contexts.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\conversions-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\conversions.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\conversions.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\counters.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\counters.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\cpu-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\cpu.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\dateparser.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\dateparser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\debug-agent.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\debug-agent.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\debug-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\debug.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\debug.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\disassembler.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\disassembler.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\execution.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\execution.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\factory.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\factory.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\flags.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\flags.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\frame-element.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\frame-element.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\frames-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\frames-x64.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\frames-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\frames.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\frames.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\func-name-inferrer.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\func-name-inferrer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\global-handles.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\global-handles.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\globals.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\handles-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\handles.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\handles.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\hashmap.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\hashmap.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\heap-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\heap.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\heap.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\ic-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ic-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ic.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\ic.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\interceptors.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\interpreter-irregexp.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\interpreter-irregexp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\jump-target.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\jump-target-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\jump-target.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\jump-target-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\jsregexp.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\jsregexp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\list-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\list.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\log.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\log-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\log.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\log-utils.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\log-utils.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\macro-assembler-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\macro-assembler-x64.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\macro-assembler.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\mark-compact.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\mark-compact.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\memory.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\messages.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\messages.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\natives.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\objects-debug.cc"
+				>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\src\objects-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\objects.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\objects.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\oprofile-agent.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\oprofile-agent.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\parser.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\parser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\platform-win32.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\platform.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\prettyprinter.cc"
+				>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\src\prettyprinter.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\property.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\property.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\regexp-macro-assembler-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\regexp-macro-assembler-x64.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-macro-assembler-irregexp.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-macro-assembler-irregexp.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-macro-assembler.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-macro-assembler.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-macro-assembler-tracer.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-macro-assembler-tracer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-stack.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\register-allocator.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\register-allocator.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\register-allocator-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\rewriter.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\rewriter.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\runtime.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\runtime.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\scanner.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\scanner.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\scopeinfo.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\scopeinfo.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\scopes.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\scopes.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\serialize.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\serialize.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\shell.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\snapshot-common.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\snapshot.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\spaces-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\spaces.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\spaces.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\string-stream.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\string-stream.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\stub-cache-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\stub-cache.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\stub-cache.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\token.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\token.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\top.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\top.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\unicode-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\unicode.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\usage-analyzer.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\usage-analyzer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\utils.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\utils.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\v8-counters.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\v8-counters.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\v8.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\v8.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\v8threads.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\v8threads.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\variables.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\variables.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\version.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\version.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\virtual-frame.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\virtual-frame-x64.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\virtual-frame.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\x64\virtual-frame-x64.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\zone-inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\zone.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\zone.h"
+				>
+			</File>
+			<Filter
+				Name="third party"
+				>
+				<File
+					RelativePath="..\..\src\x64\disasm-x64.cc"
+					>
+				</File>
+				<File
+					RelativePath="..\..\src\disasm.h"
+					>
+				</File>
+			</Filter>
+			<Filter
+				Name="generated files"
+				>
+				<File
+					RelativePath="..\..\src\unicode.cc"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="include"
+			>
+			<File
+				RelativePath="..\..\include\debug.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\include\v8.h"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_cctest_x64.vcproj b/tools/visual_studio/v8_cctest_x64.vcproj
new file mode 100644
index 0000000..fc7ac4b
--- /dev/null
+++ b/tools/visual_studio/v8_cctest_x64.vcproj
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8_cctest"
+	ProjectGUID="{97ECC711-7430-4FC4-90FD-004DA880E72A}"
+	RootNamespace="v8_cctest"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\..\test\cctest\cctest.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-alloc.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-api.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-assembler-x64.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-ast.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-compiler.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-conversions.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-debug.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-decls.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-disasm-x64.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-flags.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-func-name-inference.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-hashmap.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-heap.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-lock.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-log.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-log-utils.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-log-stack-tracer.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-mark-compact.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-platform-win32.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-serialize.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-sockets.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-spaces.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-strings.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-utils.cc"
+			>
+		</File>
+		<File
+			RelativePath="..\..\test\cctest\test-version.cc"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_mksnapshot_x64.vcproj b/tools/visual_studio/v8_mksnapshot_x64.vcproj
new file mode 100644
index 0000000..1c460e4
--- /dev/null
+++ b/tools/visual_studio/v8_mksnapshot_x64.vcproj
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8_mksnapshot"
+	ProjectGUID="{865575D0-37E2-405E-8CBA-5F6C485B5A26}"
+	RootNamespace="v8_mksnapshot"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\..\src\mksnapshot.cc"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_process_sample_x64.vcproj b/tools/visual_studio/v8_process_sample_x64.vcproj
new file mode 100644
index 0000000..81adbe0
--- /dev/null
+++ b/tools/visual_studio/v8_process_sample_x64.vcproj
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8_process_sample"
+	ProjectGUID="{EF019874-D38A-40E3-B17C-DB5923F0A79C}"
+	RootNamespace="v8_process_sample"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\..\samples\process.cc"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_shell_sample_x64.vcproj b/tools/visual_studio/v8_shell_sample_x64.vcproj
new file mode 100644
index 0000000..ab276f4
--- /dev/null
+++ b/tools/visual_studio/v8_shell_sample_x64.vcproj
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8_shell_sample"
+	ProjectGUID="{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}"
+	RootNamespace="v8_shell_sample"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="1"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib Ws2_32.lib"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<File
+			RelativePath="..\..\samples\shell.cc"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_snapshot_cc_x64.vcproj b/tools/visual_studio/v8_snapshot_cc_x64.vcproj
new file mode 100644
index 0000000..9c6f9d2
--- /dev/null
+++ b/tools/visual_studio/v8_snapshot_cc_x64.vcproj
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8_snapshot_cc"
+	ProjectGUID="{0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F}"
+	RootNamespace="v8_snapshot_cc"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="10"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="10"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="generated files"
+			SourceControlFiles="false"
+			>
+      <File
+        RelativePath="$(OutDir)\v8_mksnapshot.exe"
+        >
+        <FileConfiguration
+          Name="Debug|x64"
+          >
+          <Tool
+            Name="VCCustomBuildTool"
+            Description="Building snapshot..."
+            CommandLine="&quot;$(OutDir)\v8_mksnapshot.exe&quot; &quot;$(IntDir)\DerivedSources\snapshot.cc&quot;&#x0D;&#x0A;"
+            AdditionalDependencies="$(OutDir)\v8_mksnapshot.exe"
+            Outputs="$(IntDir)\DerivedSources\snapshot.cc"
+          />
+        </FileConfiguration>
+        <FileConfiguration
+          Name="Release|x64"
+          >
+          <Tool
+            Name="VCCustomBuildTool"
+            Description="Building snapshot..."
+            CommandLine="&quot;$(OutDir)\v8_mksnapshot.exe&quot; &quot;$(IntDir)\DerivedSources\snapshot.cc&quot;&#x0D;&#x0A;"
+            AdditionalDependencies="$(OutDir)\v8_mksnapshot.exe"
+            Outputs="$(IntDir)\DerivedSources\snapshot.cc"
+          />
+        </FileConfiguration>
+      </File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_snapshot_x64.vcproj b/tools/visual_studio/v8_snapshot_x64.vcproj
new file mode 100644
index 0000000..0f6c70f
--- /dev/null
+++ b/tools/visual_studio/v8_snapshot_x64.vcproj
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8_snapshot"
+	ProjectGUID="{C0334F9A-1168-4101-9DD8-C30FB252D435}"
+	RootNamespace="v8_snapshot"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				LinkLibraryDependencies="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				LinkLibraryDependencies="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="generated files"
+			SourceControlFiles="false"
+			>
+			<File
+				RelativePath="$(IntDir)\..\v8\DerivedSources\natives-empty.cc"
+				>
+			</File>
+			<File
+				RelativePath="$(IntDir)\..\v8_snapshot_cc\DerivedSources\snapshot.cc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/v8_x64.sln b/tools/visual_studio/v8_x64.sln
new file mode 100644
index 0000000..1fa2f16
--- /dev/null
+++ b/tools/visual_studio/v8_x64.sln
@@ -0,0 +1,101 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_base", "v8_base_x64.vcproj", "{EC8B7909-62AF-470D-A75D-E1D89C837142}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8", "v8_x64.vcproj", "{21E22961-22BF-4493-BD3A-868F93DA5179}"
+	ProjectSection(ProjectDependencies) = postProject
+		{EC8B7909-62AF-470D-A75D-E1D89C837142} = {EC8B7909-62AF-470D-A75D-E1D89C837142}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_mksnapshot", "v8_mksnapshot_x64.vcproj", "{865575D0-37E2-405E-8CBA-5F6C485B5A26}"
+	ProjectSection(ProjectDependencies) = postProject
+		{21E22961-22BF-4493-BD3A-868F93DA5179} = {21E22961-22BF-4493-BD3A-868F93DA5179}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_snapshot", "v8_snapshot_x64.vcproj", "{C0334F9A-1168-4101-9DD8-C30FB252D435}"
+	ProjectSection(ProjectDependencies) = postProject
+		{0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F} = {0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F}
+		{EC8B7909-62AF-470D-A75D-E1D89C837142} = {EC8B7909-62AF-470D-A75D-E1D89C837142}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_shell_sample", "v8_shell_sample_x64.vcproj", "{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}"
+	ProjectSection(ProjectDependencies) = postProject
+		{C0334F9A-1168-4101-9DD8-C30FB252D435} = {C0334F9A-1168-4101-9DD8-C30FB252D435}
+	EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E131F77D-B713-48F3-B86D-097ECDCC4C3A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_process_sample", "v8_process_sample_x64.vcproj", "{EF019874-D38A-40E3-B17C-DB5923F0A79C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{C0334F9A-1168-4101-9DD8-C30FB252D435} = {C0334F9A-1168-4101-9DD8-C30FB252D435}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_cctest", "v8_cctest_x64.vcproj", "{97ECC711-7430-4FC4-90FD-004DA880E72A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{C0334F9A-1168-4101-9DD8-C30FB252D435} = {C0334F9A-1168-4101-9DD8-C30FB252D435}
+	EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AD933CE2-1303-448E-89C8-60B1FDD18EC3}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d8", "d8_x64.vcproj", "{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{C0334F9A-1168-4101-9DD8-C30FB252D435} = {C0334F9A-1168-4101-9DD8-C30FB252D435}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "v8_snapshot_cc", "v8_snapshot_cc_x64.vcproj", "{0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F}"
+	ProjectSection(ProjectDependencies) = postProject
+		{865575D0-37E2-405E-8CBA-5F6C485B5A26} = {865575D0-37E2-405E-8CBA-5F6C485B5A26}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F}.Debug|x64.ActiveCfg = Debug|x64
+		{0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F}.Debug|x64.Build.0 = Debug|x64
+		{0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F}.Release|x64.ActiveCfg = Release|x64
+		{0DDBDA8B-A49F-4CC7-A1D5-5BB8297C8A3F}.Release|x64.Build.0 = Release|x64
+		{21E22961-22BF-4493-BD3A-868F93DA5179}.Debug|x64.ActiveCfg = Debug|x64
+		{21E22961-22BF-4493-BD3A-868F93DA5179}.Debug|x64.Build.0 = Debug|x64
+		{21E22961-22BF-4493-BD3A-868F93DA5179}.Release|x64.ActiveCfg = Release|x64
+		{21E22961-22BF-4493-BD3A-868F93DA5179}.Release|x64.Build.0 = Release|x64
+		{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}.Debug|x64.ActiveCfg = Debug|x64
+		{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}.Debug|x64.Build.0 = Debug|x64
+		{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}.Release|x64.ActiveCfg = Release|x64
+		{2DE20FFA-6F5E-48D9-84D8-09B044A5B119}.Release|x64.Build.0 = Release|x64
+		{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}.Debug|x64.ActiveCfg = Debug|x64
+		{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}.Debug|x64.Build.0 = Debug|x64
+		{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}.Release|x64.ActiveCfg = Release|x64
+		{7E4C7D2D-A4B9-40B9-8192-22654E626F6C}.Release|x64.Build.0 = Release|x64
+		{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Debug|x64.ActiveCfg = Debug|x64
+		{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Debug|x64.Build.0 = Debug|x64
+		{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Release|x64.ActiveCfg = Release|x64
+		{865575D0-37E2-405E-8CBA-5F6C485B5A26}.Release|x64.Build.0 = Release|x64
+		{97ECC711-7430-4FC4-90FD-004DA880E72A}.Debug|x64.ActiveCfg = Debug|x64
+		{97ECC711-7430-4FC4-90FD-004DA880E72A}.Debug|x64.Build.0 = Debug|x64
+		{97ECC711-7430-4FC4-90FD-004DA880E72A}.Release|x64.ActiveCfg = Release|x64
+		{97ECC711-7430-4FC4-90FD-004DA880E72A}.Release|x64.Build.0 = Release|x64
+		{C0334F9A-1168-4101-9DD8-C30FB252D435}.Debug|x64.ActiveCfg = Debug|x64
+		{C0334F9A-1168-4101-9DD8-C30FB252D435}.Debug|x64.Build.0 = Debug|x64
+		{C0334F9A-1168-4101-9DD8-C30FB252D435}.Release|x64.ActiveCfg = Release|x64
+		{C0334F9A-1168-4101-9DD8-C30FB252D435}.Release|x64.Build.0 = Release|x64
+		{EC8B7909-62AF-470D-A75D-E1D89C837142}.Debug|x64.ActiveCfg = Debug|x64
+		{EC8B7909-62AF-470D-A75D-E1D89C837142}.Debug|x64.Build.0 = Debug|x64
+		{EC8B7909-62AF-470D-A75D-E1D89C837142}.Release|x64.ActiveCfg = Release|x64
+		{EC8B7909-62AF-470D-A75D-E1D89C837142}.Release|x64.Build.0 = Release|x64
+		{EF019874-D38A-40E3-B17C-DB5923F0A79C}.Debug|x64.ActiveCfg = Debug|x64
+		{EF019874-D38A-40E3-B17C-DB5923F0A79C}.Debug|x64.Build.0 = Debug|x64
+		{EF019874-D38A-40E3-B17C-DB5923F0A79C}.Release|x64.ActiveCfg = Release|x64
+		{EF019874-D38A-40E3-B17C-DB5923F0A79C}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{2DE20FFA-6F5E-48D9-84D8-09B044A5B119} = {E131F77D-B713-48F3-B86D-097ECDCC4C3A}
+		{97ECC711-7430-4FC4-90FD-004DA880E72A} = {AD933CE2-1303-448E-89C8-60B1FDD18EC3}
+		{EF019874-D38A-40E3-B17C-DB5923F0A79C} = {E131F77D-B713-48F3-B86D-097ECDCC4C3A}
+	EndGlobalSection
+EndGlobal
diff --git a/tools/visual_studio/v8_x64.vcproj b/tools/visual_studio/v8_x64.vcproj
new file mode 100644
index 0000000..cbf88c9
--- /dev/null
+++ b/tools/visual_studio/v8_x64.vcproj
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="v8"
+	ProjectGUID="{21E22961-22BF-4493-BD3A-868F93DA5179}"
+	RootNamespace="v8"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="x64"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\debug.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				LinkLibraryDependencies="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			ConfigurationType="4"
+			InheritedPropertySheets=".\common.vsprops;.\x64.vsprops;.\release.vsprops"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				LinkLibraryDependencies="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="js"
+			>
+			<File
+				RelativePath="..\..\src\apinatives.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\array.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\date-delay.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\debug-delay.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\macros.py"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\math.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\messages.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\mirror-delay.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\regexp-delay.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\json-delay.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\runtime.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\string.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\uri.js"
+				>
+			</File>
+			<File
+				RelativePath="..\..\src\v8natives.js"
+				>
+				<FileConfiguration
+					Name="Debug|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Processing js files..."
+						CommandLine=".\js2c.cmd ..\..\src &quot;$(IntDir)\DerivedSources&quot;"
+						AdditionalDependencies="..\..\src\macros.py;..\..\src\runtime.js;..\..\src\v8natives.js;..\..\src\array.js;..\..\src\string.js;..\..\src\uri.js;..\..\src\math.js;..\..\src\messages.js;..\..\src\apinatives.js;..\..\src\debug-delay.js;..\..\src\mirror-delay.js;..\..\src\date-delay.js;..\..\src\regexp-delay.js;..\..\src\json-delay.js"
+						Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCustomBuildTool"
+						Description="Processing js files..."
+						CommandLine=".\js2c.cmd ..\..\src &quot;$(IntDir)\DerivedSources&quot;"
+						AdditionalDependencies="..\..\src\macros.py;..\..\src\runtime.js;..\..\src\v8natives.js;..\..\src\array.js;..\..\src\string.js;..\..\src\uri.js;..\..\src\math.js;..\..\src\messages.js;..\..\src\apinatives.js;..\..\src\debug-delay.js;..\..\src\mirror-delay.js;..\..\src\date-delay.js;..\..\src\regexp-delay.js;..\..\src\json-delay.js"
+						Outputs="$(IntDir)\DerivedSources\natives.cc;$(IntDir)\DerivedSources\natives-empty.cc"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="generated files"
+			>
+			<File
+				RelativePath="$(IntDir)\DerivedSources\natives.cc"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath="..\..\src\snapshot-empty.cc"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/tools/visual_studio/x64.vsprops b/tools/visual_studio/x64.vsprops
new file mode 100644
index 0000000..af0e47c
--- /dev/null
+++ b/tools/visual_studio/x64.vsprops
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="x64"
+	>
+	<Tool
+		Name="VCCLCompilerTool"
+		PreprocessorDefinitions="V8_TARGET_ARCH_X64;V8_NATIVE_REGEXP"
+	/>
+</VisualStudioPropertySheet>