summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorRyan <ry@tinyclouds.org>2009-08-19 16:37:15 +0200
committerRyan <ry@tinyclouds.org>2009-08-19 16:37:15 +0200
commit0cec74d03dc6a1735e731fe06056a1731e14c0df (patch)
tree9606bcb9afeba305a7b2a1ac4c518ded63a25d89 /deps
parentb590a45849307f5544b7a95854f45064527105ad (diff)
downloadnode-new-0cec74d03dc6a1735e731fe06056a1731e14c0df.tar.gz
Upgrade v8 to 1.3.5
Diffstat (limited to 'deps')
-rw-r--r--deps/v8/ChangeLog27
-rw-r--r--deps/v8/SConstruct11
-rw-r--r--deps/v8/include/v8-debug.h7
-rw-r--r--deps/v8/include/v8.h42
-rwxr-xr-xdeps/v8/src/SConscript44
-rw-r--r--deps/v8/src/api.cc88
-rw-r--r--deps/v8/src/arm/assembler-arm.h5
-rw-r--r--deps/v8/src/arm/builtins-arm.cc2
-rw-r--r--deps/v8/src/arm/codegen-arm.cc9
-rw-r--r--deps/v8/src/arm/codegen-arm.h9
-rw-r--r--deps/v8/src/arm/macro-assembler-arm.cc2
-rw-r--r--deps/v8/src/assembler.h3
-rw-r--r--deps/v8/src/ast.h20
-rw-r--r--deps/v8/src/builtins.cc6
-rw-r--r--deps/v8/src/codegen.cc33
-rw-r--r--deps/v8/src/compilation-cache.cc1
-rw-r--r--deps/v8/src/compiler.cc9
-rw-r--r--deps/v8/src/debug.cc10
-rw-r--r--deps/v8/src/debug.h4
-rw-r--r--deps/v8/src/execution.cc7
-rw-r--r--deps/v8/src/execution.h5
-rw-r--r--deps/v8/src/factory.cc6
-rw-r--r--deps/v8/src/factory.h3
-rw-r--r--deps/v8/src/handles-inl.h2
-rw-r--r--deps/v8/src/handles.h19
-rw-r--r--deps/v8/src/heap.cc61
-rw-r--r--deps/v8/src/heap.h4
-rw-r--r--deps/v8/src/ia32/assembler-ia32.h5
-rw-r--r--deps/v8/src/ia32/builtins-ia32.cc9
-rw-r--r--deps/v8/src/ia32/codegen-ia32.cc16
-rw-r--r--deps/v8/src/ia32/codegen-ia32.h19
-rw-r--r--deps/v8/src/ia32/debug-ia32.cc4
-rw-r--r--deps/v8/src/ia32/ic-ia32.cc4
-rw-r--r--deps/v8/src/ia32/macro-assembler-ia32.cc4
-rw-r--r--deps/v8/src/ia32/regexp-macro-assembler-ia32.cc254
-rw-r--r--deps/v8/src/ia32/regexp-macro-assembler-ia32.h64
-rw-r--r--deps/v8/src/ic-inl.h2
-rw-r--r--deps/v8/src/ic.cc2
-rw-r--r--deps/v8/src/ic.h2
-rw-r--r--deps/v8/src/jsregexp.cc79
-rw-r--r--deps/v8/src/math.js2
-rw-r--r--deps/v8/src/objects-debug.cc13
-rw-r--r--deps/v8/src/objects-inl.h34
-rw-r--r--deps/v8/src/objects.cc44
-rw-r--r--deps/v8/src/objects.h52
-rw-r--r--deps/v8/src/parser.cc283
-rw-r--r--deps/v8/src/parser.h3
-rw-r--r--deps/v8/src/platform-win32.cc4
-rw-r--r--deps/v8/src/regexp-macro-assembler-irregexp.cc31
-rw-r--r--deps/v8/src/regexp-macro-assembler-irregexp.h12
-rw-r--r--deps/v8/src/regexp-macro-assembler-tracer.cc58
-rw-r--r--deps/v8/src/regexp-macro-assembler-tracer.h14
-rw-r--r--deps/v8/src/regexp-macro-assembler.cc190
-rw-r--r--deps/v8/src/regexp-macro-assembler.h102
-rw-r--r--deps/v8/src/regexp-stack.h4
-rw-r--r--deps/v8/src/runtime.cc28
-rw-r--r--deps/v8/src/runtime.h2
-rw-r--r--deps/v8/src/scanner.cc97
-rw-r--r--deps/v8/src/scanner.h57
-rw-r--r--deps/v8/src/scopes.cc23
-rw-r--r--deps/v8/src/scopes.h7
-rw-r--r--deps/v8/src/spaces.cc73
-rw-r--r--deps/v8/src/spaces.h20
-rw-r--r--deps/v8/src/v8-counters.h2
-rw-r--r--deps/v8/src/v8natives.js7
-rw-r--r--deps/v8/src/version.cc2
-rw-r--r--deps/v8/src/x64/assembler-x64-inl.h24
-rw-r--r--deps/v8/src/x64/assembler-x64.cc136
-rw-r--r--deps/v8/src/x64/assembler-x64.h96
-rw-r--r--deps/v8/src/x64/builtins-x64.cc22
-rw-r--r--deps/v8/src/x64/cfg-x64.cc4
-rw-r--r--deps/v8/src/x64/codegen-x64.cc44
-rw-r--r--deps/v8/src/x64/codegen-x64.h21
-rw-r--r--deps/v8/src/x64/debug-x64.cc150
-rw-r--r--deps/v8/src/x64/ic-x64.cc4
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.cc17
-rw-r--r--deps/v8/src/x64/regexp-macro-assembler-x64.cc1274
-rw-r--r--deps/v8/src/x64/regexp-macro-assembler-x64.h268
-rw-r--r--deps/v8/test/cctest/cctest.status58
-rw-r--r--deps/v8/test/cctest/test-api.cc28
-rw-r--r--deps/v8/test/cctest/test-debug.cc25
-rw-r--r--deps/v8/test/cctest/test-decls.cc5
-rw-r--r--deps/v8/test/cctest/test-heap.cc12
-rw-r--r--deps/v8/test/cctest/test-regexp.cc443
-rw-r--r--deps/v8/test/message/message.status13
-rw-r--r--deps/v8/test/mjsunit/div-mod.js9
-rw-r--r--deps/v8/test/mjsunit/mjsunit.js8
-rw-r--r--deps/v8/test/mjsunit/mjsunit.status30
-rwxr-xr-xdeps/v8/test/mjsunit/simple-constructor.js78
-rw-r--r--deps/v8/test/mjsunit/stack-traces.js63
-rw-r--r--deps/v8/test/mjsunit/tools/logreader.js16
-rw-r--r--deps/v8/test/mjsunit/tools/tickprocessor.js72
-rw-r--r--deps/v8/test/mozilla/mozilla.status12
-rw-r--r--deps/v8/tools/gyp/v8.gyp18
-rw-r--r--deps/v8/tools/logreader.js7
-rwxr-xr-xdeps/v8/tools/mac-nm4
-rw-r--r--deps/v8/tools/tickprocessor.js33
-rw-r--r--deps/v8/tools/visual_studio/common.vsprops2
-rw-r--r--deps/v8/tools/visual_studio/d8_x64.vcproj199
-rw-r--r--deps/v8/tools/visual_studio/ia32.vsprops2
-rw-r--r--deps/v8/tools/visual_studio/v8_base_x64.vcproj963
-rw-r--r--deps/v8/tools/visual_studio/v8_cctest_x64.vcproj251
-rw-r--r--deps/v8/tools/visual_studio/v8_mksnapshot_x64.vcproj151
-rw-r--r--deps/v8/tools/visual_studio/v8_process_sample_x64.vcproj151
-rw-r--r--deps/v8/tools/visual_studio/v8_shell_sample_x64.vcproj151
-rw-r--r--deps/v8/tools/visual_studio/v8_snapshot_cc_x64.vcproj92
-rw-r--r--deps/v8/tools/visual_studio/v8_snapshot_x64.vcproj142
-rw-r--r--deps/v8/tools/visual_studio/v8_x64.sln101
-rw-r--r--deps/v8/tools/visual_studio/v8_x64.vcproj223
-rw-r--r--deps/v8/tools/visual_studio/x64.vsprops11
110 files changed, 6193 insertions, 1307 deletions
diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog
index 4bfd8d5ca9..c59661d366 100644
--- a/deps/v8/ChangeLog
+++ b/deps/v8/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/deps/v8/SConstruct b/deps/v8/SConstruct
index c981ef9139..efd34dbade 100644
--- a/deps/v8/SConstruct
+++ b/deps/v8/SConstruct
@@ -101,6 +101,9 @@ LIBRARY_FLAGS = {
'regexp:native': {
'arch:ia32' : {
'CPPDEFINES': ['V8_NATIVE_REGEXP']
+ },
+ 'arch:x64' : {
+ 'CPPDEFINES': ['V8_NATIVE_REGEXP']
}
}
},
@@ -166,7 +169,7 @@ LIBRARY_FLAGS = {
},
'arch:x64': {
'CPPDEFINES': ['V8_TARGET_ARCH_X64'],
- 'CCFLAGS': ['-fno-strict-aliasing', '-m64'],
+ 'CCFLAGS': ['-m64'],
'LINKFLAGS': ['-m64'],
},
'prof:oprofile': {
@@ -716,7 +719,11 @@ class BuildContext(object):
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/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h
index 345d331a12..3c5c923b3d 100644
--- a/deps/v8/include/v8-debug.h
+++ b/deps/v8/include/v8-debug.h
@@ -228,9 +228,14 @@ class EXPORT Debug {
* }
* \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/deps/v8/include/v8.h b/deps/v8/include/v8.h
index d8de00ceca..a0cc4ea8b0 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -513,10 +513,36 @@ class V8EXPORT ScriptOrigin {
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 @@ class V8EXPORT Script {
/**
* 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 @@ class V8EXPORT TryCatch {
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/deps/v8/src/SConscript b/deps/v8/src/SConscript
index a9669a1229..6a38c1a79e 100755
--- a/deps/v8/src/SConscript
+++ b/deps/v8/src/SConscript
@@ -63,24 +63,32 @@ SOURCES = {
'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/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 0dc4fd7c7e..88cf2bcde0 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -1046,7 +1046,7 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
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 @@ ScriptData* ScriptData::New(unsigned* data, int length) {
// --- 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 @@ Local<Script> Script::Compile(v8::Handle<String> source,
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 @@ Local<Value> Script::Run() {
{
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::Exception() const {
}
+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 @@ Persistent<Context> v8::Context::New(
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 @@ void Debug::SetHostDispatchHandler(HostDispatchHandler handler,
}
-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 @@ Handle<Value> Debug::Call(v8::Handle<v8::Function> fun,
}
+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/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h
index eeab4a72cc..b3ebb8be8b 100644
--- a/deps/v8/src/arm/assembler-arm.h
+++ b/deps/v8/src/arm/assembler-arm.h
@@ -430,7 +430,10 @@ class Assembler : public Malloced {
// 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/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc
index b5332ece4c..28524c80ad 100644
--- a/deps/v8/src/arm/builtins-arm.cc
+++ b/deps/v8/src/arm/builtins-arm.cc
@@ -39,7 +39,7 @@ namespace internal {
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/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc
index d3507ec0e3..40b0ac8160 100644
--- a/deps/v8/src/arm/codegen-arm.cc
+++ b/deps/v8/src/arm/codegen-arm.cc
@@ -5890,16 +5890,11 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
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/deps/v8/src/arm/codegen-arm.h b/deps/v8/src/arm/codegen-arm.h
index 80d1d56ee2..70a7b27765 100644
--- a/deps/v8/src/arm/codegen-arm.h
+++ b/deps/v8/src/arm/codegen-arm.h
@@ -152,14 +152,9 @@ class CodeGenerator: public AstVisitor {
#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/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc
index 875c91e964..4b02e2d688 100644
--- a/deps/v8/src/arm/macro-assembler-arm.cc
+++ b/deps/v8/src/arm/macro-assembler-arm.cc
@@ -132,7 +132,7 @@ void MacroAssembler::Call(intptr_t target, RelocInfo::Mode rmode,
// 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/deps/v8/src/assembler.h b/deps/v8/src/assembler.h
index 879ee5410a..1ddc8a31e8 100644
--- a/deps/v8/src/assembler.h
+++ b/deps/v8/src/assembler.h
@@ -216,6 +216,9 @@ class RelocInfo BASE_EMBEDDED {
// 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/deps/v8/src/ast.h b/deps/v8/src/ast.h
index 3a309ac96a..ea83712137 100644
--- a/deps/v8/src/ast.h
+++ b/deps/v8/src/ast.h
@@ -111,6 +111,7 @@ AST_NODE_LIST(DEF_FORWARD_DECLARATION)
// 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 @@ class FunctionLiteral: public Expression {
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 @@ class FunctionLiteral: public Expression {
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 @@ class FunctionLiteral: public Expression {
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 @@ class FunctionLiteral: public Expression {
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/deps/v8/src/builtins.cc b/deps/v8/src/builtins.cc
index 1ea0245a72..dbd18f82a5 100644
--- a/deps/v8/src/builtins.cc
+++ b/deps/v8/src/builtins.cc
@@ -61,7 +61,7 @@ namespace internal {
// ----------------------------------------------------------------------------
-// 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 @@ BUILTIN(HandleApiCall) {
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/deps/v8/src/codegen.cc b/deps/v8/src/codegen.cc
index 7a4bb12ed0..8e516c0b04 100644
--- a/deps/v8/src/codegen.cc
+++ b/deps/v8/src/codegen.cc
@@ -243,23 +243,22 @@ bool CodeGenerator::ShouldGenerateLog(Expression* type) {
// 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 @@ Handle<JSFunction> CodeGenerator::BuildBoilerplate(FunctionLiteral* node) {
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/deps/v8/src/compilation-cache.cc b/deps/v8/src/compilation-cache.cc
index ec5b39c2fb..8dd9ec16b2 100644
--- a/deps/v8/src/compilation-cache.cc
+++ b/deps/v8/src/compilation-cache.cc
@@ -290,7 +290,6 @@ void CompilationCacheScript::Put(Handle<String> source,
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/deps/v8/src/compiler.cc b/deps/v8/src/compiler.cc
index 5607f29622..feff492404 100644
--- a/deps/v8/src/compiler.cc
+++ b/deps/v8/src/compiler.cc
@@ -219,11 +219,8 @@ static Handle<JSFunction> MakeFunction(bool is_global,
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 @@ Handle<JSFunction> Compiler::Compile(Handle<String> source,
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/deps/v8/src/debug.cc b/deps/v8/src/debug.cc
index 18536f5c7a..f2a28148b1 100644
--- a/deps/v8/src/debug.cc
+++ b/deps/v8/src/debug.cc
@@ -1452,14 +1452,15 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
// 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 @@ void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
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/deps/v8/src/debug.h b/deps/v8/src/debug.h
index 970dbbe5ce..5b0273aa22 100644
--- a/deps/v8/src/debug.h
+++ b/deps/v8/src/debug.h
@@ -238,7 +238,10 @@ class Debug {
// 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 @@ class Debug {
// 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/deps/v8/src/execution.cc b/deps/v8/src/execution.cc
index 4ab6b61731..9080f5eaaa 100644
--- a/deps/v8/src/execution.cc
+++ b/deps/v8/src/execution.cc
@@ -174,12 +174,7 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
// 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/deps/v8/src/execution.h b/deps/v8/src/execution.h
index 126b172d21..fba696e72c 100644
--- a/deps/v8/src/execution.h
+++ b/deps/v8/src/execution.h
@@ -206,8 +206,13 @@ class StackGuard BASE_EMBEDDED {
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/deps/v8/src/factory.cc b/deps/v8/src/factory.cc
index 36554df732..bb6987bb8c 100644
--- a/deps/v8/src/factory.cc
+++ b/deps/v8/src/factory.cc
@@ -87,8 +87,10 @@ Handle<String> Factory::NewStringFromUtf8(Vector<const char> string,
}
-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/deps/v8/src/factory.h b/deps/v8/src/factory.h
index 4db5d4e71b..ddf71dec7a 100644
--- a/deps/v8/src/factory.h
+++ b/deps/v8/src/factory.h
@@ -92,7 +92,8 @@ class Factory : public AllStatic {
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/deps/v8/src/handles-inl.h b/deps/v8/src/handles-inl.h
index 6013c5b51e..8478bb5cd9 100644
--- a/deps/v8/src/handles-inl.h
+++ b/deps/v8/src/handles-inl.h
@@ -39,7 +39,7 @@ namespace internal {
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/deps/v8/src/handles.h b/deps/v8/src/handles.h
index ba2694f509..8c9cbebfd9 100644
--- a/deps/v8/src/handles.h
+++ b/deps/v8/src/handles.h
@@ -82,7 +82,7 @@ class Handle {
}
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 @@ class HandleScope {
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/deps/v8/src/heap.cc b/deps/v8/src/heap.cc
index f8d22a2e36..7d6e442b87 100644
--- a/deps/v8/src/heap.cc
+++ b/deps/v8/src/heap.cc
@@ -73,6 +73,10 @@ int Heap::amount_of_external_allocated_memory_at_last_global_gc_ = 0;
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 @@ void Heap::GarbageCollectionPrologue() {
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 @@ Object* Heap::AllocateMap(InstanceType instance_type, int instance_size) {
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 @@ Object* Heap::AllocateSharedFunctionInfo(Object* name) {
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::AllocateArgumentsObject(Object* callee, int length) {
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 @@ Object* Heap::AllocateInitialMap(JSFunction* fun) {
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 @@ Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
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::CopyFixedArray(FixedArray* src) {
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/deps/v8/src/heap.h b/deps/v8/src/heap.h
index 179f9af10c..ec1e21af5b 100644
--- a/deps/v8/src/heap.h
+++ b/deps/v8/src/heap.h
@@ -852,7 +852,11 @@ class Heap : public AllStatic {
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/deps/v8/src/ia32/assembler-ia32.h b/deps/v8/src/ia32/assembler-ia32.h
index b648055f1b..6a90e070d8 100644
--- a/deps/v8/src/ia32/assembler-ia32.h
+++ b/deps/v8/src/ia32/assembler-ia32.h
@@ -437,7 +437,10 @@ class Assembler : public Malloced {
// 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/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc
index a70a9d2acf..6de9de6ee5 100644
--- a/deps/v8/src/ia32/builtins-ia32.cc
+++ b/deps/v8/src/ia32/builtins-ia32.cc
@@ -37,7 +37,7 @@ namespace internal {
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 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// 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 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ 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/deps/v8/src/ia32/codegen-ia32.cc b/deps/v8/src/ia32/codegen-ia32.cc
index 9542b1646f..b8b3db64bd 100644
--- a/deps/v8/src/ia32/codegen-ia32.cc
+++ b/deps/v8/src/ia32/codegen-ia32.cc
@@ -6752,11 +6752,10 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
// 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 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
// 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 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
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/deps/v8/src/ia32/codegen-ia32.h b/deps/v8/src/ia32/codegen-ia32.h
index 1d0cc8bdd2..afdbffe58e 100644
--- a/deps/v8/src/ia32/codegen-ia32.h
+++ b/deps/v8/src/ia32/codegen-ia32.h
@@ -299,14 +299,9 @@ class CodeGenerator: public AstVisitor {
#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 @@ class GenericBinaryOpStub: public CodeStub {
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 @@ class GenericBinaryOpStub: public CodeStub {
Token::Value op_;
OverwriteMode mode_;
GenericBinaryFlags flags_;
+ bool use_sse3_;
const char* GetName();
@@ -644,9 +641,10 @@ class GenericBinaryOpStub: public CodeStub {
}
#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 @@ class GenericBinaryOpStub: public CodeStub {
// 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/deps/v8/src/ia32/debug-ia32.cc b/deps/v8/src/ia32/debug-ia32.cc
index 9913a39ba9..4ef0862af1 100644
--- a/deps/v8/src/ia32/debug-ia32.cc
+++ b/deps/v8/src/ia32/debug-ia32.cc
@@ -195,8 +195,8 @@ void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
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/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc
index 08ffe2f141..fa9b8a20f6 100644
--- a/deps/v8/src/ia32/ic-ia32.cc
+++ b/deps/v8/src/ia32/ic-ia32.cc
@@ -840,7 +840,7 @@ void KeyedStoreIC::RestoreInlinedVersion(Address address) {
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 @@ bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
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/deps/v8/src/ia32/macro-assembler-ia32.cc b/deps/v8/src/ia32/macro-assembler-ia32.cc
index 7782aa95c6..e362cd3c5b 100644
--- a/deps/v8/src/ia32/macro-assembler-ia32.cc
+++ b/deps/v8/src/ia32/macro-assembler-ia32.cc
@@ -82,8 +82,8 @@ static void RecordWriteHelper(MacroAssembler* masm,
// 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/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc b/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
index a49c1f510e..bc8107633e 100644
--- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/deps/v8/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 @@ namespace internal {
*
* 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 @@ namespace internal {
* 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 @@ RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
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::Bind(Label* label) {
}
-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 @@ void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str,
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 @@ bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type,
}
}
-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 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ 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 @@ void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
}
-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 @@ static T& frame_entry(Address re_frame, int frame_offset) {
}
-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 @@ int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
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::LoadCurrentCharacterUnchecked(int cp_offset,
}
-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/deps/v8/src/ia32/regexp-macro-assembler-ia32.h b/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
index c3d9155700..d11439299c 100644
--- a/deps/v8/src/ia32/regexp-macro-assembler-ia32.h
+++ b/deps/v8/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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
// 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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
// 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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
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 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
Label check_preempt_label_;
Label stack_overflow_label_;
};
+#endif // V8_NATIVE_REGEXP
}} // namespace v8::internal
diff --git a/deps/v8/src/ic-inl.h b/deps/v8/src/ic-inl.h
index 08304d83e7..38d61dcbb4 100644
--- a/deps/v8/src/ic-inl.h
+++ b/deps/v8/src/ic-inl.h
@@ -38,7 +38,7 @@ namespace internal {
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/deps/v8/src/ic.cc b/deps/v8/src/ic.cc
index f4d74c9354..393ccbf6a7 100644
--- a/deps/v8/src/ic.cc
+++ b/deps/v8/src/ic.cc
@@ -122,7 +122,7 @@ Address IC::OriginalCodeAddress() {
// 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/deps/v8/src/ic.h b/deps/v8/src/ic.h
index 860b7e60d6..007b0352e9 100644
--- a/deps/v8/src/ic.h
+++ b/deps/v8/src/ic.h
@@ -390,7 +390,7 @@ class KeyedStoreIC: public IC {
// 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/deps/v8/src/jsregexp.cc b/deps/v8/src/jsregexp.cc
index bd511024bb..06208aa50a 100644
--- a/deps/v8/src/jsregexp.cc
+++ b/deps/v8/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 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
// 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 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
// 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 @@ Handle<Object> RegExpImpl::IrregexpExec(Handle<JSRegExp> jsregexp,
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 @@ RegExpEngine::CompilationResult RegExpEngine::Compile(RegExpCompileData* data,
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/deps/v8/src/math.js b/deps/v8/src/math.js
index db75cb28ae..e3d266e4be 100644
--- a/deps/v8/src/math.js
+++ b/deps/v8/src/math.js
@@ -184,6 +184,7 @@ function MathTan(x) {
function SetupMath() {
// Setup math constants.
// ECMA-262, section 15.8.1.1.
+ %OptimizeObjectForAddingMultipleProperties($Math, 8);
%SetProperty($Math,
"E",
2.7182818284590452354,
@@ -219,6 +220,7 @@ function SetupMath() {
"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/deps/v8/src/objects-debug.cc b/deps/v8/src/objects-debug.cc
index 40001f9619..e97b207bac 100644
--- a/deps/v8/src/objects-debug.cc
+++ b/deps/v8/src/objects-debug.cc
@@ -371,9 +371,9 @@ void JSObject::JSObjectVerify() {
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 @@ void Map::MapPrint() {
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 @@ void SharedFunctionInfo::SharedFunctionInfoPrint() {
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/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index a3bd3ce1ca..7b750b61ea 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -91,7 +91,13 @@ PropertyDetails PropertyDetails::AsDeleted() {
}
-#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::inobject_properties() {
}
+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_inobject_properties(int value) {
}
+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, function_data, Object,
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 @@ BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
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, start_position_and_type,
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/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index c3051b811c..e4a3a67a57 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -4780,6 +4780,48 @@ Object* SharedFunctionInfo::GetSourceCode() {
}
+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 @@ void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) {
IteratePointers(v, kNameOffset, kConstructStubOffset + kPointerSize);
IteratePointers(v, kInstanceClassNameOffset, kScriptOffset + kPointerSize);
IteratePointers(v, kDebugInfoOffset, kInferredNameOffset + kPointerSize);
+ IteratePointers(v, kThisPropertyAssignmentsOffset,
+ kThisPropertyAssignmentsOffset + kPointerSize);
}
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index 03f0f3dd6b..a4029614e8 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -2704,6 +2704,10 @@ class Map: public HeapObject {
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 @@ class Map: public HeapObject {
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 @@ class Map: public HeapObject {
// 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 @@ class SharedFunctionInfo: public HeapObject {
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 @@ class SharedFunctionInfo: public HeapObject {
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 @@ class SharedFunctionInfo: public HeapObject {
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/deps/v8/src/parser.cc b/deps/v8/src/parser.cc
index 348c12a4ac..5cc6341f9a 100644
--- a/deps/v8/src/parser.cc
+++ b/deps/v8/src/parser.cc
@@ -97,7 +97,7 @@ class Parser {
// 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 @@ class TemporaryScope BASE_EMBEDDED {
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 @@ class TemporaryScope BASE_EMBEDDED {
// 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 @@ TemporaryScope::TemporaryScope(Parser* parser)
: 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 @@ Parser::Parser(Handle<Script> script,
}
-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 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
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 @@ void PreParser::ReportMessageAt(Scanner::Location source_location,
}
+// 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 @@ class InitializationBlockFinder {
}
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 @@ class InitializationBlockFinder {
};
+// 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 @@ void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
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 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
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 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
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* Parser::ParseFunctionLiteral(Handle<String> var_name,
}
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 @@ unsigned* ScriptDataImpl::Data() {
}
-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 @@ ScriptDataImpl* PreParse(unibrow::CharacterStream* stream,
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/deps/v8/src/parser.h b/deps/v8/src/parser.h
index c029c4b25d..86e1f74fbe 100644
--- a/deps/v8/src/parser.h
+++ b/deps/v8/src/parser.h
@@ -143,7 +143,8 @@ FunctionLiteral* MakeAST(bool compile_in_global_context,
ScriptDataImpl* pre_data);
-ScriptDataImpl* PreParse(unibrow::CharacterStream* stream,
+ScriptDataImpl* PreParse(Handle<String> source,
+ unibrow::CharacterStream* stream,
v8::Extension* extension);
diff --git a/deps/v8/src/platform-win32.cc b/deps/v8/src/platform-win32.cc
index 633b2c25a8..0a2d99041b 100644
--- a/deps/v8/src/platform-win32.cc
+++ b/deps/v8/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/deps/v8/src/regexp-macro-assembler-irregexp.cc b/deps/v8/src/regexp-macro-assembler-irregexp.cc
index eea3c23eae..21b622ef05 100644
--- a/deps/v8/src/regexp-macro-assembler-irregexp.cc
+++ b/deps/v8/src/regexp-macro-assembler-irregexp.cc
@@ -375,37 +375,6 @@ void RegExpMacroAssemblerIrregexp::CheckNotRegistersEqual(int reg1,
}
-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/deps/v8/src/regexp-macro-assembler-irregexp.h b/deps/v8/src/regexp-macro-assembler-irregexp.h
index 597046c4c3..dd64e7ae83 100644
--- a/deps/v8/src/regexp-macro-assembler-irregexp.h
+++ b/deps/v8/src/regexp-macro-assembler-irregexp.h
@@ -52,7 +52,6 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
// 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 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
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 @@ class RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
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/deps/v8/src/regexp-macro-assembler-tracer.cc b/deps/v8/src/regexp-macro-assembler-tracer.cc
index 30eb485e37..0aad337378 100644
--- a/deps/v8/src/regexp-macro-assembler-tracer.cc
+++ b/deps/v8/src/regexp-macro-assembler-tracer.cc
@@ -53,12 +53,6 @@ void RegExpMacroAssemblerTracer::Bind(Label* label) {
}
-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::CheckCharacters(Vector<const uc16> str,
}
-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 @@ bool RegExpMacroAssemblerTracer::CheckSpecialCharacterClass(
}
-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/deps/v8/src/regexp-macro-assembler-tracer.h b/deps/v8/src/regexp-macro-assembler-tracer.h
index 0fd73f3d6f..28434d7cab 100644
--- a/deps/v8/src/regexp-macro-assembler-tracer.h
+++ b/deps/v8/src/regexp-macro-assembler-tracer.h
@@ -43,7 +43,6 @@ class RegExpMacroAssemblerTracer: public RegExpMacroAssembler {
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 @@ class RegExpMacroAssemblerTracer: public RegExpMacroAssembler {
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/deps/v8/src/regexp-macro-assembler.cc b/deps/v8/src/regexp-macro-assembler.cc
index 8dede304eb..7f830fe485 100644
--- a/deps/v8/src/regexp-macro-assembler.cc
+++ b/deps/v8/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 @@ RegExpMacroAssembler::~RegExpMacroAssembler() {
}
-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;
+ }
+ const uc16* data;
+ if (StringShape(subject).IsExternal()) {
+ data = ExternalTwoByteString::cast(subject)->resource()->data();
+ } else {
+ ASSERT(subject->IsSeqTwoByteString());
+ data = SeqTwoByteString::cast(subject)->GetChars();
}
- current_byte_array_free_offset_ = free_offset + byte_size;
- return ArraySlice(current_byte_array_, free_offset);
+ 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/deps/v8/src/regexp-macro-assembler.h b/deps/v8/src/regexp-macro-assembler.h
index 484986428b..e59082768a 100644
--- a/deps/v8/src/regexp-macro-assembler.h
+++ b/deps/v8/src/regexp-macro-assembler.h
@@ -46,6 +46,7 @@ class RegExpMacroAssembler {
enum IrregexpImplementation {
kIA32Implementation,
kARMImplementation,
+ kX64Implementation,
kBytecodeImplementation
};
@@ -67,12 +68,6 @@ class RegExpMacroAssembler {
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 @@ class RegExpMacroAssembler {
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 @@ class RegExpMacroAssembler {
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 };
-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_;
-};
+ 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);
+};
+#endif // V8_NATIVE_REGEXP
} } // namespace v8::internal
#endif // V8_REGEXP_MACRO_ASSEMBLER_H_
diff --git a/deps/v8/src/regexp-stack.h b/deps/v8/src/regexp-stack.h
index 6c090daa65..99cf33cd32 100644
--- a/deps/v8/src/regexp-stack.h
+++ b/deps/v8/src/regexp-stack.h
@@ -48,7 +48,7 @@ class RegExpStack {
~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 @@ class RegExpStack {
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/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index 0da4be8216..b3e8aa477d 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -1022,6 +1022,30 @@ static Object* Runtime_InitializeConstContextSlot(Arguments args) {
}
+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 @@ static Object* Runtime_Typeof(Arguments args) {
}
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 @@ static Object* Runtime_NewObject(Arguments args) {
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/deps/v8/src/runtime.h b/deps/v8/src/runtime.h
index cdf21dcabf..d47ca18e79 100644
--- a/deps/v8/src/runtime.h
+++ b/deps/v8/src/runtime.h
@@ -247,6 +247,8 @@ namespace internal {
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/deps/v8/src/scanner.cc b/deps/v8/src/scanner.cc
index 24a6d4be9c..720dc3536c 100644
--- a/deps/v8/src/scanner.cc
+++ b/deps/v8/src/scanner.cc
@@ -92,33 +92,35 @@ void UTF8Buffer::AddCharSlow(uc32 c) {
UTF16Buffer::UTF16Buffer()
- : pos_(0),
- pushback_buffer_(0),
- last_(0),
- stream_(NULL) { }
+ : pos_(0), size_(0) { }
-void UTF16Buffer::Initialize(Handle<String> data,
- unibrow::CharacterStream* input) {
- data_ = data;
- pos_ = 0;
- stream_ = input;
+Handle<String> UTF16Buffer::SubString(int start, int end) {
+ return internal::SubString(data_, start, end);
}
-Handle<String> UTF16Buffer::SubString(int start, int end) {
- return internal::SubString(data_, start, end);
+// 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 UTF16Buffer::PushBack(uc32 ch) {
+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 UTF16Buffer::Advance() {
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 @@ uc32 UTF16Buffer::Advance() {
}
-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 @@ Scanner::Scanner(bool pre) : stack_overflow_(false), is_pre_parsing_(pre) {
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 @@ void Scanner::Init(Handle<String> source, unibrow::CharacterStream* stream,
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::AddCharAdvance() {
}
-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::Scan() {
void Scanner::SeekForward(int pos) {
- source_.SeekForward(pos - 1);
+ source_->SeekForward(pos - 1);
Advance();
Scan();
}
diff --git a/deps/v8/src/scanner.h b/deps/v8/src/scanner.h
index eea23a70c2..340da86ed7 100644
--- a/deps/v8/src/scanner.h
+++ b/deps/v8/src/scanner.h
@@ -73,24 +73,53 @@ class UTF8Buffer {
class UTF16Buffer {
public:
UTF16Buffer();
+ virtual ~UTF16Buffer() {}
+
+ 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;
- 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);
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 @@ class Scanner {
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 @@ class Scanner {
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 @@ class Scanner {
// 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/deps/v8/src/scopes.cc b/deps/v8/src/scopes.cc
index 78ed035180..25873fac1d 100644
--- a/deps/v8/src/scopes.cc
+++ b/deps/v8/src/scopes.cc
@@ -108,14 +108,31 @@ Variable* VariableMap::Lookup(Handle<String> name) {
// 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/deps/v8/src/scopes.h b/deps/v8/src/scopes.h
index 5767d9f017..fc627df619 100644
--- a/deps/v8/src/scopes.h
+++ b/deps/v8/src/scopes.h
@@ -93,7 +93,6 @@ class Scope: public ZoneObject {
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 @@ class Scope: public ZoneObject {
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 @@ class Scope: public ZoneObject {
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 Scope: public ZoneObject {
class DummyScope : public Scope {
public:
- DummyScope() {
+ DummyScope() : Scope(GLOBAL_SCOPE) {
outer_scope_ = this;
}
diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc
index 9f266cb0ea..9227a87f3c 100644
--- a/deps/v8/src/spaces.cc
+++ b/deps/v8/src/spaces.cc
@@ -726,47 +726,25 @@ void PagedSpace::Shrink() {
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 @@ bool NewSpace::Setup(Address start, int size) {
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 @@ bool NewSpace::Setup(Address start, int size) {
#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 @@ void NewSpace::TearDown() {
#endif
start_ = NULL;
- capacity_ = 0;
allocation_info_.top = NULL;
allocation_info_.limit = NULL;
mc_forwarding_info_.top = NULL;
@@ -975,12 +952,11 @@ void NewSpace::Flip() {
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 @@ void SemiSpace::TearDown() {
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/deps/v8/src/spaces.h b/deps/v8/src/spaces.h
index 4760a42402..f12e0e4f47 100644
--- a/deps/v8/src/spaces.h
+++ b/deps/v8/src/spaces.h
@@ -1054,6 +1054,10 @@ class SemiSpace : public Space {
// 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 @@ class NewSpace : public Space {
// 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 @@ class NewSpace : public Space {
}
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 @@ class FixedSpace : public PagedSpace {
// 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/deps/v8/src/v8-counters.h b/deps/v8/src/v8-counters.h
index a62cd74465..43cd5e3d60 100644
--- a/deps/v8/src/v8-counters.h
+++ b/deps/v8/src/v8-counters.h
@@ -139,6 +139,8 @@ namespace internal {
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/deps/v8/src/v8natives.js b/deps/v8/src/v8natives.js
index 841c920852..be92347768 100644
--- a/deps/v8/src/v8natives.js
+++ b/deps/v8/src/v8natives.js
@@ -46,12 +46,16 @@ const $isFinite = GlobalIsFinite;
// 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 NumberToJSON(key) {
// ----------------------------------------------------------------------------
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 @@ function SetupNumber() {
"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/deps/v8/src/version.cc b/deps/v8/src/version.cc
index 7bc52a8490..26b009c78d 100644
--- a/deps/v8/src/version.cc
+++ b/deps/v8/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/deps/v8/src/x64/assembler-x64-inl.h b/deps/v8/src/x64/assembler-x64-inl.h
index 196f2eedbd..f51a3ea887 100644
--- a/deps/v8/src/x64/assembler-x64-inl.h
+++ b/deps/v8/src/x64/assembler-x64-inl.h
@@ -228,43 +228,47 @@ void RelocInfo::set_target_object(Object* target) {
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/deps/v8/src/x64/assembler-x64.cc b/deps/v8/src/x64/assembler-x64.cc
index b4fd678e17..a02557e96a 100644
--- a/deps/v8/src/x64/assembler-x64.cc
+++ b/deps/v8/src/x64/assembler-x64.cc
@@ -178,6 +178,13 @@ void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
}
+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 reg, const Operand& op) {
}
-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(byte subcode,
}
+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::cmovl(Condition cc, Register dst, const Operand& src) {
}
+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(Register target) {
}
+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 @@ void Assembler::movq(const Operand& dst, Immediate value) {
}
+/*
+ * 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 dst, Register src) {
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(Register reg, Immediate mask) {
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/deps/v8/src/x64/assembler-x64.h b/deps/v8/src/x64/assembler-x64.h
index 015fa68237..9d602b9ef1 100644
--- a/deps/v8/src/x64/assembler-x64.h
+++ b/deps/v8/src/x64/assembler-x64.h
@@ -442,8 +442,10 @@ class Assembler : public Malloced {
// 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 @@ class Assembler : public Malloced {
// Load a 32-bit immediate value, zero-extended to 64 bits.
void movl(Register dst, Immediate imm32);
+ // 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);
- void movq(Register dst, Register src);
+ // 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 64 bit register value to 64-bit memory location.
- void movq(const Operand& dst, Register 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 @@ class Assembler : public Malloced {
// 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 @@ class Assembler : public Malloced {
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 @@ class Assembler : public Malloced {
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 @@ class Assembler : public Malloced {
// 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 @@ class Assembler : public Malloced {
// 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,
+ Register dst,
Immediate src);
void immediate_arithmetic_op_8(byte subcode,
- Register dst,
+ 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 @@ class Assembler : public Malloced {
friend class CodePatcher;
friend class EnsureSpace;
+ friend class RegExpMacroAssemblerX64;
// Code buffer:
// The buffer into which code and relocation info are generated.
diff --git a/deps/v8/src/x64/builtins-x64.cc b/deps/v8/src/x64/builtins-x64.cc
index 087aaff2cb..6988d72082 100644
--- a/deps/v8/src/x64/builtins-x64.cc
+++ b/deps/v8/src/x64/builtins-x64.cc
@@ -35,7 +35,7 @@ namespace internal {
#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 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
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 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
// 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 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
__ 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 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
// 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/deps/v8/src/x64/cfg-x64.cc b/deps/v8/src/x64/cfg-x64.cc
index 8d01ed28e1..34ddbbf025 100644
--- a/deps/v8/src/x64/cfg-x64.cc
+++ b/deps/v8/src/x64/cfg-x64.cc
@@ -114,8 +114,8 @@ void ExitNode::Compile(MacroAssembler* masm) {
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/deps/v8/src/x64/codegen-x64.cc b/deps/v8/src/x64/codegen-x64.cc
index b3df929d78..7fe6ebdb8b 100644
--- a/deps/v8/src/x64/codegen-x64.cc
+++ b/deps/v8/src/x64/codegen-x64.cc
@@ -500,17 +500,19 @@ void CodeGenerator::GenerateReturnSequence(Result* return_value) {
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 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
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 @@ void Reference::GetValue(TypeofState typeof_state) {
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 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
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 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
// 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 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
// 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/deps/v8/src/x64/codegen-x64.h b/deps/v8/src/x64/codegen-x64.h
index b1c61d8688..bfdff56744 100644
--- a/deps/v8/src/x64/codegen-x64.h
+++ b/deps/v8/src/x64/codegen-x64.h
@@ -299,14 +299,9 @@ class CodeGenerator: public AstVisitor {
#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 @@ class GenericBinaryOpStub: public CodeStub {
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 @@ class GenericBinaryOpStub: public CodeStub {
Token::Value op_;
OverwriteMode mode_;
GenericBinaryFlags flags_;
+ bool use_sse3_;
const char* GetName();
@@ -645,17 +642,19 @@ class GenericBinaryOpStub: public CodeStub {
}
#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/deps/v8/src/x64/debug-x64.cc b/deps/v8/src/x64/debug-x64.cc
index 177eb90a49..f2bb62bc69 100644
--- a/deps/v8/src/x64/debug-x64.cc
+++ b/deps/v8/src/x64/debug-x64.cc
@@ -39,60 +39,176 @@ namespace internal {
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/deps/v8/src/x64/ic-x64.cc b/deps/v8/src/x64/ic-x64.cc
index 86008eb325..1c74a44d02 100644
--- a/deps/v8/src/x64/ic-x64.cc
+++ b/deps/v8/src/x64/ic-x64.cc
@@ -167,7 +167,7 @@ static bool PatchInlinedMapCheck(Address address, Object* map) {
// 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 @@ void LoadIC::GenerateStringLength(MacroAssembler* masm) {
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/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc
index 2219a5a0ee..8f8398dc9d 100644
--- a/deps/v8/src/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/x64/macro-assembler-x64.cc
@@ -262,8 +262,7 @@ void MacroAssembler::Abort(const char* msg) {
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(Address destination, RelocInfo::Mode rmode) {
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 @@ void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
#endif
jmp(kScratchRegister);
#ifdef DEBUG
- ASSERT_EQ(kTargetAddrToReturnAddrDist,
+ ASSERT_EQ(kPatchReturnSequenceLength,
SizeOfCodeGeneratedSince(&target) + kPointerSize);
#endif
}
@@ -523,8 +521,8 @@ void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
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 @@ void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
#endif
call(kScratchRegister);
#ifdef DEBUG
- ASSERT_EQ(kTargetAddrToReturnAddrDist,
+ ASSERT_EQ(kPatchReturnSequenceLength,
SizeOfCodeGeneratedSince(&target) + kPointerSize);
#endif
}
@@ -799,7 +797,7 @@ void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) {
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 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
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/deps/v8/src/x64/regexp-macro-assembler-x64.cc b/deps/v8/src/x64/regexp-macro-assembler-x64.cc
index 209aa2d307..1e38d6da97 100644
--- a/deps/v8/src/x64/regexp-macro-assembler-x64.cc
+++ b/deps/v8/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/deps/v8/src/x64/regexp-macro-assembler-x64.h b/deps/v8/src/x64/regexp-macro-assembler-x64.h
index 209aa2d307..a270bc1865 100644
--- a/deps/v8/src/x64/regexp-macro-assembler-x64.h
+++ b/deps/v8/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/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index 9abe408948..68aabb5165 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -60,61 +60,3 @@ test-log/ProfLazyMode: SKIP
# 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/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 35ac031a55..e1caba3c83 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -7738,3 +7738,31 @@ THREADED_TEST(PixelArray) {
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/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 9e2c38dbee..f5e4f3a4fc 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -487,9 +487,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
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 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
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 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) {
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/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc
index 6c48f64f72..f083027d0b 100644
--- a/deps/v8/test/cctest/test-decls.cc
+++ b/deps/v8/test/cctest/test-decls.cc
@@ -111,7 +111,7 @@ void DeclarationContext::InitializeIfNeeded() {
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 @@ v8::Handle<Boolean> DeclarationContext::HandleHas(Local<String> key,
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/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index 6b5907c2e8..37dbdd7c60 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -44,35 +44,26 @@ TEST(HeapMaps) {
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 const char* not_so_random_string_table[] = {
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/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc
index 8d8326ccad..89c7868d83 100644
--- a/deps/v8/test/cctest/test-regexp.cc
+++ b/deps/v8/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 @@ TEST(DispatchTableConstruction) {
// 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 @@ class ContextInitializer {
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 @@ static RegExpMacroAssemblerIA32::Result ExecuteIA32(Code* code,
}
-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 @@ TEST(MacroAssemblerIA32Success) {
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(MacroAssemblerIA32Success) {
}
-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 @@ TEST(MacroAssemblerIA32Simple) {
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 @@ TEST(MacroAssemblerIA32Simple) {
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 @@ TEST(MacroAssemblerIA32SimpleUC16) {
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 @@ TEST(MacroAssemblerIA32SimpleUC16) {
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 @@ TEST(MacroAssemblerIA32Backtrack) {
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 @@ TEST(MacroAssemblerIA32BackReferenceASCII) {
Address start_adr = seq_input->GetCharsAddress();
int output[3];
- RegExpMacroAssemblerIA32::Result result =
- ExecuteIA32(*code,
- *input,
- 0,
- start_adr,
- start_adr + input->length(),
- output,
- true);
-
- CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+ NativeRegExpMacroAssembler::Result result =
+ Execute(*code,
+ *input,
+ 0,
+ start_adr,
+ start_adr + input->length(),
+ output,
+ true);
+
+ 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 @@ TEST(MacroAssemblerIA32BackReferenceUC16) {
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 @@ TEST(MacroAssemblerIA32BackReferenceUC16) {
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(MacroAssemblerIA32BackReferenceUC16) {
-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 @@ TEST(MacroAssemblerIA32AtStart) {
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);
-
- CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
-
- result = ExecuteIA32(*code,
- *input,
- 3,
- start_adr + 3,
- start_adr + input->length(),
- NULL,
- false);
-
- CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+ NativeRegExpMacroAssembler::Result result =
+ Execute(*code,
+ *input,
+ 0,
+ start_adr,
+ start_adr + input->length(),
+ NULL,
+ true);
+
+ CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
+
+ result = Execute(*code,
+ *input,
+ 3,
+ start_adr + 3,
+ start_adr + input->length(),
+ NULL,
+ false);
+
+ 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 @@ TEST(MacroAssemblerIA32BackRefNoCase) {
Address start_adr = seq_input->GetCharsAddress();
int output[4];
- RegExpMacroAssemblerIA32::Result result =
- ExecuteIA32(*code,
- *input,
- 0,
- start_adr,
- start_adr + input->length(),
- output,
- true);
-
- CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+ NativeRegExpMacroAssembler::Result result =
+ Execute(*code,
+ *input,
+ 0,
+ start_adr,
+ start_adr + input->length(),
+ output,
+ true);
+
+ 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(MacroAssemblerIA32BackRefNoCase) {
-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 @@ TEST(MacroAssemblerIA32Registers) {
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 @@ TEST(MacroAssemblerIA32Registers) {
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(MacroAssemblerIA32Registers) {
}
-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 @@ TEST(MacroAssemblerIA32StackOverflow) {
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 @@ TEST(MacroAssemblerIA32LotsOfRegisters) {
Address start_adr = seq_input->GetCharsAddress();
int captures[2];
- RegExpMacroAssemblerIA32::Result result =
- ExecuteIA32(*code,
- *input,
- 0,
- start_adr,
- start_adr + input->length(),
- captures,
- true);
-
- CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+ NativeRegExpMacroAssembler::Result result =
+ Execute(*code,
+ *input,
+ 0,
+ start_adr,
+ start_adr + input->length(),
+ captures,
+ true);
+
+ 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/deps/v8/test/message/message.status b/deps/v8/test/message/message.status
index 9afaa0f148..fc2896b1c9 100644
--- a/deps/v8/test/message/message.status
+++ b/deps/v8/test/message/message.status
@@ -29,16 +29,3 @@ prefix message
# 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/deps/v8/test/mjsunit/div-mod.js b/deps/v8/test/mjsunit/div-mod.js
index 39fab27829..a8a19b30c1 100644
--- a/deps/v8/test/mjsunit/div-mod.js
+++ b/deps/v8/test/mjsunit/div-mod.js
@@ -48,7 +48,7 @@ function run_tests_for(divisor) {
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 @@ var divisors = [
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 @@ var divisors = [
for (var i = 0; i < divisors.length; i++) {
run_tests_for(divisors[i]);
}
-
diff --git a/deps/v8/test/mjsunit/mjsunit.js b/deps/v8/test/mjsunit/mjsunit.js
index 2c52a31e60..1fb3f02afb 100644
--- a/deps/v8/test/mjsunit/mjsunit.js
+++ b/deps/v8/test/mjsunit/mjsunit.js
@@ -179,9 +179,13 @@ function assertInstanceof(obj, type) {
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/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index 6853cdc65a..4bf67e80d6 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -73,33 +73,3 @@ string-compare-alignment: PASS || FAIL
# 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/deps/v8/test/mjsunit/simple-constructor.js b/deps/v8/test/mjsunit/simple-constructor.js
new file mode 100755
index 0000000000..b26d6519b0
--- /dev/null
+++ b/deps/v8/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/deps/v8/test/mjsunit/stack-traces.js b/deps/v8/test/mjsunit/stack-traces.js
index 3bb5755aed..d7ece2c6f2 100644
--- a/deps/v8/test/mjsunit/stack-traces.js
+++ b/deps/v8/test/mjsunit/stack-traces.js
@@ -103,22 +103,24 @@ function testStrippedCustomError() {
// 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 @@ function testCallerCensorship() {
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 @@ function testUnintendedCallerCensorship() {
}
});
} 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 @@ function testErrorsDuringFormatting() {
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 @@ function testErrorsDuringFormatting() {
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);
-}
-
-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"],
+ assertTrue(threw, "ErrorsDuringFormatting didnt' throw (2)");
+}
+
+
+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, ["hep-hey"], ["new CustomError",
- "collectStackTrace"]);
-
+testTrace("testStrippedCustomError", testStrippedCustomError, ["hep-hey"],
+ ["new CustomError", "collectStackTrace"]);
testCallerCensorship();
testUnintendedCallerCensorship();
testErrorsDuringFormatting();
diff --git a/deps/v8/test/mjsunit/tools/logreader.js b/deps/v8/test/mjsunit/tools/logreader.js
index dfd7f9f54e..8ed5ffd267 100644
--- a/deps/v8/test/mjsunit/tools/logreader.js
+++ b/deps/v8/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/deps/v8/test/mjsunit/tools/tickprocessor.js b/deps/v8/test/mjsunit/tools/tickprocessor.js
index 00c3fb176b..83bdac8ab8 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor.js
+++ b/deps/v8/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/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status
index c4628a00b0..a1551dcdd4 100644
--- a/deps/v8/test/mozilla/mozilla.status
+++ b/deps/v8/test/mozilla/mozilla.status
@@ -278,6 +278,11 @@ js1_2/regexp/beginLine: FAIL_OK
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.7.3: SKIP
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/deps/v8/tools/gyp/v8.gyp b/deps/v8/tools/gyp/v8.gyp
index 365d87cff4..b0c33318fe 100644
--- a/deps/v8/tools/gyp/v8.gyp
+++ b/deps/v8/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/deps/v8/tools/logreader.js b/deps/v8/tools/logreader.js
index 78085a451e..88ab907740 100644
--- a/deps/v8/tools/logreader.js
+++ b/deps/v8/tools/logreader.js
@@ -294,8 +294,11 @@ devtools.profiler.LogReader.prototype.processLog_ = function(lines) {
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/deps/v8/tools/mac-nm b/deps/v8/tools/mac-nm
index 9c18177978..07efb07bae 100755
--- a/deps/v8/tools/mac-nm
+++ b/deps/v8/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/deps/v8/tools/tickprocessor.js b/deps/v8/tools/tickprocessor.js
index 34c6195d9a..72b3059dca 100644
--- a/deps/v8/tools/tickprocessor.js
+++ b/deps/v8/tools/tickprocessor.js
@@ -499,19 +499,32 @@ function WindowsCppEntriesProvider() {
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 @@ WindowsCppEntriesProvider.prototype.parseNextLine = function() {
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/deps/v8/tools/visual_studio/common.vsprops b/deps/v8/tools/visual_studio/common.vsprops
index f131a4a0ca..d23e4fcfe8 100644
--- a/deps/v8/tools/visual_studio/common.vsprops
+++ b/deps/v8/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/deps/v8/tools/visual_studio/d8_x64.vcproj b/deps/v8/tools/visual_studio/d8_x64.vcproj
new file mode 100644
index 0000000000..dd2b83d06e
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/ia32.vsprops b/deps/v8/tools/visual_studio/ia32.vsprops
index aff08716fd..f48e808d84 100644
--- a/deps/v8/tools/visual_studio/ia32.vsprops
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_base_x64.vcproj b/deps/v8/tools/visual_studio/v8_base_x64.vcproj
new file mode 100644
index 0000000000..1e27824629
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_cctest_x64.vcproj b/deps/v8/tools/visual_studio/v8_cctest_x64.vcproj
new file mode 100644
index 0000000000..fc7ac4be8b
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_mksnapshot_x64.vcproj b/deps/v8/tools/visual_studio/v8_mksnapshot_x64.vcproj
new file mode 100644
index 0000000000..1c460e4db6
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_process_sample_x64.vcproj b/deps/v8/tools/visual_studio/v8_process_sample_x64.vcproj
new file mode 100644
index 0000000000..81adbe0fb4
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_shell_sample_x64.vcproj b/deps/v8/tools/visual_studio/v8_shell_sample_x64.vcproj
new file mode 100644
index 0000000000..ab276f4876
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_snapshot_cc_x64.vcproj b/deps/v8/tools/visual_studio/v8_snapshot_cc_x64.vcproj
new file mode 100644
index 0000000000..9c6f9d2f00
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_snapshot_x64.vcproj b/deps/v8/tools/visual_studio/v8_snapshot_x64.vcproj
new file mode 100644
index 0000000000..0f6c70faf9
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_x64.sln b/deps/v8/tools/visual_studio/v8_x64.sln
new file mode 100644
index 0000000000..1fa2f16cb7
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/v8_x64.vcproj b/deps/v8/tools/visual_studio/v8_x64.vcproj
new file mode 100644
index 0000000000..cbf88c918d
--- /dev/null
+++ b/deps/v8/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/deps/v8/tools/visual_studio/x64.vsprops b/deps/v8/tools/visual_studio/x64.vsprops
new file mode 100644
index 0000000000..af0e47c4b6
--- /dev/null
+++ b/deps/v8/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>