Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2012-01-07 01:03:06 +0400
committerRyan Dahl <ry@tinyclouds.org>2012-01-07 01:03:06 +0400
commit8e5674fb5cb31fd872b9b74fde0430603806a48a (patch)
tree3e51952c9d42078a2fef42b428f2996ce6b5d085 /deps
parent42281124d4b83b0e99baf5d56b696ef242399f51 (diff)
Upgrade V8 to 3.8.5
Diffstat (limited to 'deps')
-rw-r--r--deps/v8/ChangeLog26
-rw-r--r--deps/v8/LICENSE6
-rw-r--r--deps/v8/build/common.gypi15
-rw-r--r--deps/v8/build/standalone.gypi24
-rw-r--r--deps/v8/include/v8.h20
-rw-r--r--deps/v8/src/api.cc40
-rw-r--r--deps/v8/src/arm/builtins-arm.cc11
-rw-r--r--deps/v8/src/arm/code-stubs-arm.cc6
-rw-r--r--deps/v8/src/checks.h20
-rw-r--r--deps/v8/src/collection.js44
-rw-r--r--deps/v8/src/d8-posix.cc3
-rw-r--r--deps/v8/src/d8.gyp4
-rw-r--r--deps/v8/src/flag-definitions.h8
-rw-r--r--deps/v8/src/heap.cc16
-rw-r--r--deps/v8/src/heap.h10
-rw-r--r--deps/v8/src/ia32/builtins-ia32.cc3
-rw-r--r--deps/v8/src/ia32/code-stubs-ia32.cc22
-rw-r--r--deps/v8/src/isolate.h22
-rw-r--r--deps/v8/src/macros.py3
-rw-r--r--deps/v8/src/math.js34
-rw-r--r--deps/v8/src/mips/builtins-mips.cc69
-rw-r--r--deps/v8/src/mips/code-stubs-mips.cc16
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.cc12
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.h3
-rw-r--r--deps/v8/src/mips/lithium-gap-resolver-mips.cc18
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.h8
-rw-r--r--deps/v8/src/objects-inl.h19
-rw-r--r--deps/v8/src/objects.cc82
-rw-r--r--deps/v8/src/objects.h13
-rw-r--r--deps/v8/src/platform-openbsd.cc21
-rw-r--r--deps/v8/src/platform-posix.cc3
-rw-r--r--deps/v8/src/profile-generator.cc13
-rw-r--r--deps/v8/src/runtime.cc24
-rw-r--r--deps/v8/src/spaces.cc37
-rw-r--r--deps/v8/src/store-buffer.cc96
-rw-r--r--deps/v8/src/store-buffer.h17
-rw-r--r--deps/v8/src/v8.cc39
-rw-r--r--deps/v8/src/v8.h6
-rw-r--r--deps/v8/src/version.cc2
-rw-r--r--deps/v8/src/x64/builtins-x64.cc11
-rw-r--r--deps/v8/src/x64/code-stubs-x64.cc11
-rw-r--r--deps/v8/test/cctest/test-api.cc97
-rw-r--r--deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js10
-rw-r--r--deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js12
-rw-r--r--deps/v8/test/mjsunit/harmony/collections.js34
-rwxr-xr-xdeps/v8/tools/grokdump.py114
-rw-r--r--deps/v8/tools/gyp/v8.gyp13
47 files changed, 866 insertions, 271 deletions
diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog
index 5eb4b26780e..059b69252e6 100644
--- a/deps/v8/ChangeLog
+++ b/deps/v8/ChangeLog
@@ -1,3 +1,29 @@
+2012-01-05: Version 3.8.5
+
+ Fix broken test that assumes that no GC can clear the regexp cache (GC
+ can happen at any time due to Crankshaft).
+
+ Fix handling of bogus receivers for Harmony collections. (issue 1884)
+
+ Add netbsd support to gyp build.
+
+ Determine page size at runtime on posix platforms.
+
+ Ensure that store buffer filtering hash sets are cleared after
+ StoreBuffer::Filter.
+
+ Randomize the seed used for string hashing. This helps guard against
+ CPU-eating DOS attacks against node.js servers. Based on code from
+ Bert Belder. This version only solves the issue for those that compile
+ V8 themselves or those that do not use snapshots. A snapshot-based
+ precompiled V8 will still have predictable string hash codes.
+
+ Implement callback when script finishes running in V8 API.
+
+ Improve performance of Math.min and Math.max for the case of two
+ arguments. (issue 1325)
+
+
2012-01-02: Version 3.8.4
Performance improvements for large Smi-only arrays.
diff --git a/deps/v8/LICENSE b/deps/v8/LICENSE
index e435050e909..2e516bab628 100644
--- a/deps/v8/LICENSE
+++ b/deps/v8/LICENSE
@@ -14,7 +14,9 @@ are:
- Strongtalk assembler, the basis of the files assembler-arm-inl.h,
assembler-arm.cc, assembler-arm.h, assembler-ia32-inl.h,
- assembler-ia32.cc, assembler-ia32.h, assembler.cc and assembler.h.
+ assembler-ia32.cc, assembler-ia32.h, assembler-x64-inl.h,
+ assembler-x64.cc, assembler-x64.h, assembler-mips-inl.h,
+ assembler-mips.cc, assembler-mips.h, assembler.cc and assembler.h.
This code is copyrighted by Sun Microsystems Inc. and released
under a 3-clause BSD license.
@@ -24,7 +26,7 @@ are:
These libraries have their own licenses; we recommend you read them,
as their terms may differ from the terms below.
-Copyright 2006-2011, the V8 project authors. All rights reserved.
+Copyright 2006-2012, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi
index 9129d0170ca..7aab91356a0 100644
--- a/deps/v8/build/common.gypi
+++ b/deps/v8/build/common.gypi
@@ -1,4 +1,4 @@
-# Copyright 2011 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
@@ -215,7 +215,8 @@
},
},
}],
- ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
+ or OS=="netbsd"', {
'conditions': [
[ 'target_arch=="ia32"', {
'cflags': [ '-m32' ],
@@ -259,7 +260,10 @@
['OS=="freebsd" or OS=="openbsd"', {
'cflags': [ '-I/usr/local/include' ],
}],
- ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
+ ['OS=="netbsd"', {
+ 'cflags': [ '-I/usr/pkg/include' ],
+ }],
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
'-Wnon-virtual-dtor' ],
}],
@@ -267,7 +271,7 @@
},
'Release': {
'conditions': [
- ['OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
'cflags!': [
'-O2',
'-Os',
@@ -290,6 +294,9 @@
['OS=="freebsd" or OS=="openbsd"', {
'cflags': [ '-I/usr/local/include' ],
}],
+ ['OS=="netbsd"', {
+ 'cflags': [ '-I/usr/pkg/include' ],
+ }],
['OS=="mac"', {
'xcode_settings': {
'GCC_OPTIMIZATION_LEVEL': '3', # -O3
diff --git a/deps/v8/build/standalone.gypi b/deps/v8/build/standalone.gypi
index 4297f5c84a0..86f6d460924 100644
--- a/deps/v8/build/standalone.gypi
+++ b/deps/v8/build/standalone.gypi
@@ -1,4 +1,4 @@
-# Copyright 2011 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
@@ -37,13 +37,16 @@
'variables': {
'variables': {
'conditions': [
- [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd"', {
- # This handles the Linux platforms we generally deal with. Anything
- # else gets passed through, which probably won't work very well; such
- # hosts should pass an explicit target_arch to gyp.
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
+ # This handles the Linux platforms we generally deal with.
+ # Anything else gets passed through, which probably won't work
+ # very well; such hosts should pass an explicit target_arch
+ # to gyp.
'host_arch%':
- '<!(uname -m | sed -e "s/i.86/ia32/;s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/mips.*/mips/")',
- }, { # OS!="linux" and OS!="freebsd" and OS!="openbsd"
+ '<!(uname -m | sed -e "s/i.86/ia32/;\
+ s/x86_64/x64/;s/amd64/x64/;s/arm.*/arm/;s/mips.*/mips/")',
+ }, {
+ # OS!="linux" and OS!="freebsd" and OS!="openbsd" and OS!="netbsd"
'host_arch%': 'ia32',
}],
],
@@ -78,7 +81,8 @@
},
},
'conditions': [
- [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris" \
+ or OS=="netbsd"', {
'target_defaults': {
'cflags': [ '-Wall', '<(werror)', '-W', '-Wno-unused-parameter',
'-Wnon-virtual-dtor', '-pthread', '-fno-rtti',
@@ -96,7 +100,9 @@
}],
],
},
- }], # 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"'
+ }],
+ # 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"
+ # or OS=="netbsd"'
['OS=="win"', {
'target_defaults': {
'defines': [
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index 53bad21c113..18199435808 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -2635,6 +2635,9 @@ typedef void (*MemoryAllocationCallback)(ObjectSpace space,
AllocationAction action,
int size);
+// --- Leave Script Callback ---
+typedef void (*CallCompletedCallback)();
+
// --- Failed Access Check Callback ---
typedef void (*FailedAccessCheckCallback)(Local<Object> target,
AccessType type,
@@ -3033,12 +3036,25 @@ class V8EXPORT V8 {
AllocationAction action);
/**
- * This function removes callback which was installed by
- * AddMemoryAllocationCallback function.
+ * Removes callback that was installed by AddMemoryAllocationCallback.
*/
static void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback);
/**
+ * Adds a callback to notify the host application when a script finished
+ * running. If a script re-enters the runtime during executing, the
+ * CallCompletedCallback is only invoked when the outer-most script
+ * execution ends. Executing scripts inside the callback do not trigger
+ * further callbacks.
+ */
+ static void AddCallCompletedCallback(CallCompletedCallback callback);
+
+ /**
+ * Removes callback that was installed by AddCallCompletedCallback.
+ */
+ static void RemoveCallCompletedCallback(CallCompletedCallback callback);
+
+ /**
* Allows the host application to group objects together. If one
* object in the group is alive, all objects in the group are alive.
* After each garbage collection, object groups are removed. It is
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 7eaadbb6b19..3bd5a3180f6 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -78,7 +78,7 @@ namespace v8 {
bool has_pending_exception = false
-#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
+#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback) \
do { \
i::HandleScopeImplementer* handle_scope_implementer = \
(isolate)->handle_scope_implementer(); \
@@ -91,11 +91,22 @@ namespace v8 {
} \
bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
(isolate)->OptionalRescheduleException(call_depth_is_zero); \
+ do_callback \
return value; \
} \
+ do_callback \
} while (false)
+#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
+ EXCEPTION_BAILOUT_CHECK_GENERIC( \
+ isolate, value, i::V8::FireCallCompletedCallback(isolate);)
+
+
+#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
+ EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
+
+
#define API_ENTRY_CHECK(isolate, msg) \
do { \
if (v8::Locker::IsActive()) { \
@@ -1568,7 +1579,7 @@ Local<Value> Script::Run() {
isolate->context()->global_proxy(), isolate);
i::Handle<i::Object> result =
i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
raw_result = *result;
}
i::Handle<i::Object> result(raw_result, isolate);
@@ -3494,7 +3505,7 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv,
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned =
i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
return Utils::ToLocal(scope.CloseAndEscape(returned));
}
@@ -3515,7 +3526,7 @@ Local<v8::Value> Object::CallAsConstructor(int argc,
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned =
i::Execution::New(fun, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
return Utils::ToLocal(scope.CloseAndEscape(
i::Handle<i::JSObject>::cast(returned)));
}
@@ -3528,7 +3539,7 @@ Local<v8::Value> Object::CallAsConstructor(int argc,
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned =
i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
ASSERT(!delegate->IsUndefined());
return Utils::ToLocal(scope.CloseAndEscape(returned));
}
@@ -3555,7 +3566,7 @@ Local<v8::Object> Function::NewInstance(int argc,
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned =
i::Execution::New(function, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
return scope.Close(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
}
@@ -3576,7 +3587,7 @@ Local<v8::Value> Function::Call(v8::Handle<v8::Object> recv, int argc,
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> returned =
i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
+ EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
raw_result = *returned;
}
i::Handle<i::Object> result(raw_result);
@@ -5045,6 +5056,21 @@ void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
}
+void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
+ if (callback == NULL) return;
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::V8::AddLeaveScriptCallback()")) return;
+ i::V8::AddCallCompletedCallback(callback);
+}
+
+
+void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::V8::RemoveLeaveScriptCallback()")) return;
+ i::V8::RemoveCallCompletedCallback(callback);
+}
+
+
void V8::PauseProfiler() {
i::Isolate* isolate = i::Isolate::Current();
isolate->logger()->PauseProfiler();
diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc
index c452821ff64..69ef1872c76 100644
--- a/deps/v8/src/arm/builtins-arm.cc
+++ b/deps/v8/src/arm/builtins-arm.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -316,7 +316,8 @@ static void AllocateJSArray(MacroAssembler* masm,
static void ArrayNativeCode(MacroAssembler* masm,
Label* call_generic_code) {
Counters* counters = masm->isolate()->counters();
- Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array;
+ Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array,
+ has_non_smi_element;
// Check for array construction with zero arguments or one.
__ cmp(r0, Operand(0, RelocInfo::NONE));
@@ -415,7 +416,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ bind(&loop);
__ ldr(r2, MemOperand(r7, kPointerSize, PostIndex));
if (FLAG_smi_only_arrays) {
- __ JumpIfNotSmi(r2, call_generic_code);
+ __ JumpIfNotSmi(r2, &has_non_smi_element);
}
__ str(r2, MemOperand(r5, -kPointerSize, PreIndex));
__ bind(&entry);
@@ -431,6 +432,10 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ add(sp, sp, Operand(kPointerSize));
__ mov(r0, r3);
__ Jump(lr);
+
+ __ bind(&has_non_smi_element);
+ __ UndoAllocationInNewSpace(r3, r4);
+ __ b(call_generic_code);
}
diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc
index 209c48e2a04..e95e2cf4216 100644
--- a/deps/v8/src/arm/code-stubs-arm.cc
+++ b/deps/v8/src/arm/code-stubs-arm.cc
@@ -5730,7 +5730,11 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register hash,
Register character) {
// hash = character + (character << 10);
- __ add(hash, character, Operand(character, LSL, 10));
+ __ LoadRoot(hash, Heap::kStringHashSeedRootIndex);
+ // Untag smi seed and add the character.
+ __ add(hash, character, Operand(hash, LSR, kSmiTagSize));
+ // hash += hash << 10;
+ __ add(hash, hash, Operand(hash, LSL, 10));
// hash ^= hash >> 6;
__ eor(hash, hash, Operand(hash, LSR, 6));
}
diff --git a/deps/v8/src/checks.h b/deps/v8/src/checks.h
index 8608b0eba97..d93d4510f6e 100644
--- a/deps/v8/src/checks.h
+++ b/deps/v8/src/checks.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -265,16 +265,16 @@ extern bool FLAG_enable_slow_asserts;
// The ASSERT macro is equivalent to CHECK except that it only
// generates code in debug builds.
#ifdef DEBUG
-#define ASSERT_RESULT(expr) CHECK(expr)
-#define ASSERT(condition) CHECK(condition)
-#define ASSERT_EQ(v1, v2) CHECK_EQ(v1, v2)
-#define ASSERT_NE(v1, v2) CHECK_NE(v1, v2)
-#define ASSERT_GE(v1, v2) CHECK_GE(v1, v2)
-#define ASSERT_LT(v1, v2) CHECK_LT(v1, v2)
-#define ASSERT_LE(v1, v2) CHECK_LE(v1, v2)
-#define SLOW_ASSERT(condition) if (FLAG_enable_slow_asserts) CHECK(condition)
+#define ASSERT_RESULT(expr) CHECK(expr)
+#define ASSERT(condition) CHECK(condition)
+#define ASSERT_EQ(v1, v2) CHECK_EQ(v1, v2)
+#define ASSERT_NE(v1, v2) CHECK_NE(v1, v2)
+#define ASSERT_GE(v1, v2) CHECK_GE(v1, v2)
+#define ASSERT_LT(v1, v2) CHECK_LT(v1, v2)
+#define ASSERT_LE(v1, v2) CHECK_LE(v1, v2)
+#define SLOW_ASSERT(condition) CHECK(!FLAG_enable_slow_asserts || (condition))
#else
-#define ASSERT_RESULT(expr) (expr)
+#define ASSERT_RESULT(expr) (expr)
#define ASSERT(condition) ((void) 0)
#define ASSERT_EQ(v1, v2) ((void) 0)
#define ASSERT_NE(v1, v2) ((void) 0)
diff --git a/deps/v8/src/collection.js b/deps/v8/src/collection.js
index d11612681e9..fcf4d38d94f 100644
--- a/deps/v8/src/collection.js
+++ b/deps/v8/src/collection.js
@@ -47,6 +47,10 @@ function SetConstructor() {
function SetAdd(key) {
+ if (!IS_SET(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Set.prototype.add', this]);
+ }
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
@@ -55,6 +59,10 @@ function SetAdd(key) {
function SetHas(key) {
+ if (!IS_SET(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Set.prototype.has', this]);
+ }
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
@@ -63,6 +71,10 @@ function SetHas(key) {
function SetDelete(key) {
+ if (!IS_SET(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Set.prototype.delete', this]);
+ }
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
@@ -80,6 +92,10 @@ function MapConstructor() {
function MapGet(key) {
+ if (!IS_MAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Map.prototype.get', this]);
+ }
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
@@ -88,6 +104,10 @@ function MapGet(key) {
function MapSet(key, value) {
+ if (!IS_MAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Map.prototype.set', this]);
+ }
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
@@ -96,6 +116,10 @@ function MapSet(key, value) {
function MapHas(key) {
+ if (!IS_MAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Map.prototype.has', this]);
+ }
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
@@ -104,6 +128,10 @@ function MapHas(key) {
function MapDelete(key) {
+ if (!IS_MAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['Map.prototype.delete', this]);
+ }
if (IS_UNDEFINED(key)) {
key = undefined_sentinel;
}
@@ -126,6 +154,10 @@ function WeakMapConstructor() {
function WeakMapGet(key) {
+ if (!IS_WEAKMAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['WeakMap.prototype.get', this]);
+ }
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
@@ -134,6 +166,10 @@ function WeakMapGet(key) {
function WeakMapSet(key, value) {
+ if (!IS_WEAKMAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['WeakMap.prototype.set', this]);
+ }
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
@@ -142,6 +178,10 @@ function WeakMapSet(key, value) {
function WeakMapHas(key) {
+ if (!IS_WEAKMAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['WeakMap.prototype.has', this]);
+ }
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
@@ -150,6 +190,10 @@ function WeakMapHas(key) {
function WeakMapDelete(key) {
+ if (!IS_WEAKMAP(this)) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ['WeakMap.prototype.delete', this]);
+ }
if (!IS_SPEC_OBJECT(key)) {
throw %MakeTypeError('invalid_weakmap_key', [this, key]);
}
diff --git a/deps/v8/src/d8-posix.cc b/deps/v8/src/d8-posix.cc
index 289c3b0ae8f..8a278e4e42e 100644
--- a/deps/v8/src/d8-posix.cc
+++ b/deps/v8/src/d8-posix.cc
@@ -366,7 +366,8 @@ static Handle<Value> GetStdout(int child_fd,
// We're disabling usage of waitid in Mac OS X because it doens't work for us:
// a parent process hangs on waiting while a child process is already a zombie.
// See http://code.google.com/p/v8/issues/detail?id=401.
-#if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__)
+#if defined(WNOWAIT) && !defined(ANDROID) && !defined(__APPLE__) \
+ && !defined(__NetBSD__)
#if !defined(__FreeBSD__)
#define HAS_WAITID 1
#endif
diff --git a/deps/v8/src/d8.gyp b/deps/v8/src/d8.gyp
index bdc23a20e99..a096af35b83 100644
--- a/deps/v8/src/d8.gyp
+++ b/deps/v8/src/d8.gyp
@@ -64,8 +64,8 @@
'libraries': [ '-lreadline', ],
'sources': [ 'd8-readline.cc' ],
}],
- [ '(OS=="linux" or OS=="mac" or OS=="freebsd" \
- or OS=="openbsd" or OS=="solaris" or OS=="android")', {
+ ['(OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="netbsd" \
+ or OS=="openbsd" or OS=="solaris" or OS=="android")', {
'sources': [ 'd8-posix.cc', ]
}],
[ 'OS=="win"', {
diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h
index 1ae1b17eb5c..07060dcb038 100644
--- a/deps/v8/src/flag-definitions.h
+++ b/deps/v8/src/flag-definitions.h
@@ -349,6 +349,14 @@ DEFINE_bool(trace_exception, false,
"print stack trace when throwing exceptions")
DEFINE_bool(preallocate_message_memory, false,
"preallocate some memory to build stack traces.")
+DEFINE_bool(randomize_string_hashes,
+ true,
+ "randomize string hashes to avoid predictable hash collisions "
+ "(with snapshots this option cannot override the baked-in seed)")
+DEFINE_int(string_hash_seed,
+ 0,
+ "Fixed seed to use to string hashing (0 means random)"
+ "(with snapshots this option cannot override the baked-in seed)")
// v8.cc
DEFINE_bool(preemption, false,
diff --git a/deps/v8/src/heap.cc b/deps/v8/src/heap.cc
index 5984834eaf3..31cd889cbef 100644
--- a/deps/v8/src/heap.cc
+++ b/deps/v8/src/heap.cc
@@ -2318,6 +2318,10 @@ bool Heap::CreateInitialObjects() {
}
set_infinity_value(HeapNumber::cast(obj));
+ // The hole has not been created yet, but we want to put something
+ // predictable in the gaps in the symbol table, so lets make that Smi zero.
+ set_the_hole_value(reinterpret_cast<Oddball*>(Smi::FromInt(0)));
+
// Allocate initial symbol table.
{ MaybeObject* maybe_obj = SymbolTable::Allocate(kInitialSymbolTableSize);
if (!maybe_obj->ToObject(&obj)) return false;
@@ -5638,6 +5642,18 @@ bool Heap::Setup(bool create_heap_objects) {
lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE);
if (lo_space_ == NULL) return false;
if (!lo_space_->Setup()) return false;
+
+ // Setup the seed that is used to randomize the string hash function.
+ ASSERT(string_hash_seed() == 0);
+ if (FLAG_randomize_string_hashes) {
+ if (FLAG_string_hash_seed == 0) {
+ set_string_hash_seed(
+ Smi::FromInt(V8::RandomPrivate(isolate()) & 0x3fffffff));
+ } else {
+ set_string_hash_seed(Smi::FromInt(FLAG_string_hash_seed));
+ }
+ }
+
if (create_heap_objects) {
// Create initial maps.
if (!CreateInitialMaps()) return false;
diff --git a/deps/v8/src/heap.h b/deps/v8/src/heap.h
index d92a4fb148b..2d993bbc2b4 100644
--- a/deps/v8/src/heap.h
+++ b/deps/v8/src/heap.h
@@ -96,6 +96,7 @@ inline Heap* _inline_get_heap_();
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, string_split_cache, StringSplitCache) \
V(Object, termination_exception, TerminationException) \
+ V(Smi, string_hash_seed, StringHashSeed) \
V(Map, string_map, StringMap) \
V(Map, symbol_map, SymbolMap) \
V(Map, cons_string_map, ConsStringMap) \
@@ -954,8 +955,7 @@ class Heap {
// Please note this function does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* LookupSymbol(Vector<const char> str);
MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(Vector<const char> str);
- MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(
- Vector<const uc16> str);
+ MUST_USE_RESULT MaybeObject* LookupTwoByteSymbol(Vector<const uc16> str);
MUST_USE_RESULT MaybeObject* LookupAsciiSymbol(const char* str) {
return LookupSymbol(CStrVector(str));
}
@@ -1506,6 +1506,12 @@ class Heap {
return idle_notification_will_schedule_next_gc_;
}
+ uint32_t StringHashSeed() {
+ uint32_t seed = static_cast<uint32_t>(string_hash_seed()->value());
+ ASSERT(FLAG_randomize_string_hashes || seed == 0);
+ return seed;
+ }
+
private:
Heap();
diff --git a/deps/v8/src/ia32/builtins-ia32.cc b/deps/v8/src/ia32/builtins-ia32.cc
index 3d274f2e6b8..55f66f1df8e 100644
--- a/deps/v8/src/ia32/builtins-ia32.cc
+++ b/deps/v8/src/ia32/builtins-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -1297,6 +1297,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ bind(&has_non_smi_element);
// Throw away the array that's only been partially constructed.
__ pop(eax);
+ __ UndoAllocationInNewSpace(eax);
// Restore argc and constructor before running the generic code.
__ bind(&prepare_generic_code_call);
diff --git a/deps/v8/src/ia32/code-stubs-ia32.cc b/deps/v8/src/ia32/code-stubs-ia32.cc
index bb422959e77..9bc024f40d0 100644
--- a/deps/v8/src/ia32/code-stubs-ia32.cc
+++ b/deps/v8/src/ia32/code-stubs-ia32.cc
@@ -6033,10 +6033,24 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register hash,
Register character,
Register scratch) {
- // hash = character + (character << 10);
- __ mov(hash, character);
- __ shl(hash, 10);
- __ add(hash, character);
+ // hash = (seed + character) + ((seed + character) << 10);
+ if (Serializer::enabled()) {
+ ExternalReference roots_array_start =
+ ExternalReference::roots_array_start(masm->isolate());
+ __ mov(scratch, Immediate(Heap::kStringHashSeedRootIndex));
+ __ mov(scratch, Operand::StaticArray(scratch,
+ times_pointer_size,
+ roots_array_start));
+ __ add(scratch, character);
+ __ mov(hash, scratch);
+ __ shl(scratch, 10);
+ __ add(hash, scratch);
+ } else {
+ int32_t seed = masm->isolate()->heap()->StringHashSeed();
+ __ lea(scratch, Operand(character, seed));
+ __ shl(scratch, 10);
+ __ lea(hash, Operand(scratch, character, times_1, seed));
+ }
// hash ^= hash >> 6;
__ mov(scratch, hash);
__ shr(scratch, 6);
diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h
index 2ea9b80b69c..c044e1f5789 100644
--- a/deps/v8/src/isolate.h
+++ b/deps/v8/src/isolate.h
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -106,15 +106,21 @@ class Simulator;
// of handles to the actual constants.
typedef ZoneList<Handle<Object> > ZoneObjectList;
-#define RETURN_IF_SCHEDULED_EXCEPTION(isolate) \
- if (isolate->has_scheduled_exception()) \
- return isolate->PromoteScheduledException()
+#define RETURN_IF_SCHEDULED_EXCEPTION(isolate) \
+ do { \
+ Isolate* __isolate__ = (isolate); \
+ if (__isolate__->has_scheduled_exception()) { \
+ return __isolate__->PromoteScheduledException(); \
+ } \
+ } while (false)
#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
- if (call.is_null()) { \
- ASSERT(isolate->has_pending_exception()); \
- return value; \
- }
+ do { \
+ if ((call).is_null()) { \
+ ASSERT((isolate)->has_pending_exception()); \
+ return (value); \
+ } \
+ } while (false)
#define RETURN_IF_EMPTY_HANDLE(isolate, call) \
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
diff --git a/deps/v8/src/macros.py b/deps/v8/src/macros.py
index bf7119feaa9..34b07ab2351 100644
--- a/deps/v8/src/macros.py
+++ b/deps/v8/src/macros.py
@@ -101,6 +101,9 @@ macro IS_OBJECT(arg) = (%_IsObject(arg));
macro IS_ARRAY(arg) = (%_IsArray(arg));
macro IS_FUNCTION(arg) = (%_IsFunction(arg));
macro IS_REGEXP(arg) = (%_IsRegExp(arg));
+macro IS_SET(arg) = (%_ClassOf(arg) === 'Set');
+macro IS_MAP(arg) = (%_ClassOf(arg) === 'Map');
+macro IS_WEAKMAP(arg) = (%_ClassOf(arg) === 'WeakMap');
macro IS_DATE(arg) = (%_ClassOf(arg) === 'Date');
macro IS_NUMBER_WRAPPER(arg) = (%_ClassOf(arg) === 'Number');
macro IS_STRING_WRAPPER(arg) = (%_ClassOf(arg) === 'String');
diff --git a/deps/v8/src/math.js b/deps/v8/src/math.js
index 18492aa050c..f4426f4a000 100644
--- a/deps/v8/src/math.js
+++ b/deps/v8/src/math.js
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -119,6 +119,19 @@ function MathLog(x) {
// ECMA 262 - 15.8.2.11
function MathMax(arg1, arg2) { // length == 2
var length = %_ArgumentsLength();
+ if (length == 2) {
+ if (!IS_NUMBER(arg1)) arg1 = NonNumberToNumber(arg1);
+ if (!IS_NUMBER(arg2)) arg2 = NonNumberToNumber(arg2);
+ if (arg2 > arg1) return arg2;
+ if (arg1 > arg2) return arg1;
+ if (arg1 == arg2) {
+ // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can be
+ // a Smi or a heap number.
+ return (arg1 == 0 && !%_IsSmi(arg1) && 1 / arg1 < 0) ? arg2 : arg1;
+ }
+ // All comparisons failed, one of the arguments must be NaN.
+ return 0/0; // Compiler constant-folds this to NaN.
+ }
if (length == 0) {
return -1/0; // Compiler constant-folds this to -Infinity.
}
@@ -131,7 +144,7 @@ function MathMax(arg1, arg2) { // length == 2
if (NUMBER_IS_NAN(n)) return n;
// Make sure +0 is considered greater than -0. -0 is never a Smi, +0 can be
// a Smi or heap number.
- if (n > r || (r === 0 && n === 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
+ if (n > r || (r == 0 && n == 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
}
return r;
}
@@ -139,6 +152,19 @@ function MathMax(arg1, arg2) { // length == 2
// ECMA 262 - 15.8.2.12
function MathMin(arg1, arg2) { // length == 2
var length = %_ArgumentsLength();
+ if (length == 2) {
+ if (!IS_NUMBER(arg1)) arg1 = NonNumberToNumber(arg1);
+ if (!IS_NUMBER(arg2)) arg2 = NonNumberToNumber(arg2);
+ if (arg2 > arg1) return arg1;
+ if (arg1 > arg2) return arg2;
+ if (arg1 == arg2) {
+ // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can be
+ // a Smi or a heap number.
+ return (arg1 == 0 && !%_IsSmi(arg1) && 1 / arg1 < 0) ? arg1 : arg2;
+ }
+ // All comparisons failed, one of the arguments must be NaN.
+ return 0/0; // Compiler constant-folds this to NaN.
+ }
if (length == 0) {
return 1/0; // Compiler constant-folds this to Infinity.
}
@@ -149,9 +175,9 @@ function MathMin(arg1, arg2) { // length == 2
var n = %_Arguments(i);
if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
if (NUMBER_IS_NAN(n)) return n;
- // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can b a
+ // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can be a
// Smi or a heap number.
- if (n < r || (r === 0 && n === 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
+ if (n < r || (r == 0 && n == 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
}
return r;
}
diff --git a/deps/v8/src/mips/builtins-mips.cc b/deps/v8/src/mips/builtins-mips.cc
index 701450b8145..46a912bd596 100644
--- a/deps/v8/src/mips/builtins-mips.cc
+++ b/deps/v8/src/mips/builtins-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -74,17 +74,33 @@ void Builtins::Generate_Adaptor(MacroAssembler* masm,
}
+// Load the built-in InternalArray function from the current context.
+static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
+ Register result) {
+ // Load the global context.
+
+ __ lw(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ lw(result,
+ FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
+ // Load the InternalArray function from the global context.
+ __ lw(result,
+ MemOperand(result,
+ Context::SlotOffset(
+ Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
+}
+
+
// Load the built-in Array function from the current context.
static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
// Load the global context.
__ lw(result, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ lw(result,
- FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
+ FieldMemOperand(result, GlobalObject::kGlobalContextOffset));
// Load the Array function from the global context.
__ lw(result,
- MemOperand(result,
- Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
+ MemOperand(result,
+ Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
}
@@ -308,7 +324,8 @@ static void AllocateJSArray(MacroAssembler* masm,
static void ArrayNativeCode(MacroAssembler* masm,
Label* call_generic_code) {
Counters* counters = masm->isolate()->counters();
- Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array;
+ Label argc_one_or_more, argc_two_or_more, not_empty_array, empty_array,
+ has_non_smi_element;
// Check for array construction with zero arguments or one.
__ Branch(&argc_one_or_more, ne, a0, Operand(zero_reg));
@@ -406,7 +423,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ lw(a2, MemOperand(t3));
__ Addu(t3, t3, kPointerSize);
if (FLAG_smi_only_arrays) {
- __ JumpIfNotSmi(a2, call_generic_code);
+ __ JumpIfNotSmi(a2, &has_non_smi_element);
}
__ Addu(t1, t1, -kPointerSize);
__ sw(a2, MemOperand(t1));
@@ -422,6 +439,46 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ Addu(sp, sp, Operand(kPointerSize));
__ mov(v0, a3);
__ Ret();
+
+ __ bind(&has_non_smi_element);
+ __ UndoAllocationInNewSpace(a3, t0);
+ __ b(call_generic_code);
+}
+
+
+void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- a0 : number of arguments
+ // -- ra : return address
+ // -- sp[...]: constructor arguments
+ // -----------------------------------
+ Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
+
+ // Get the InternalArray function.
+ GenerateLoadInternalArrayFunction(masm, a1);
+
+ if (FLAG_debug_code) {
+ // Initial map for the builtin InternalArray functions should be maps.
+ __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
+ __ And(t0, a2, Operand(kSmiTagMask));
+ __ Assert(ne, "Unexpected initial map for InternalArray function",
+ t0, Operand(zero_reg));
+ __ GetObjectType(a2, a3, t0);
+ __ Assert(eq, "Unexpected initial map for InternalArray function",
+ t0, Operand(MAP_TYPE));
+ }
+
+ // Run the native code for the InternalArray function called as a normal
+ // function.
+ ArrayNativeCode(masm, &generic_array_code);
+
+ // Jump to the generic array code if the specialized code cannot handle the
+ // construction.
+ __ bind(&generic_array_code);
+
+ Handle<Code> array_code =
+ masm->isolate()->builtins()->InternalArrayCodeGeneric();
+ __ Jump(array_code, RelocInfo::CODE_TARGET);
}
diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc
index b8e97f6dfe7..3e811bd7cbd 100644
--- a/deps/v8/src/mips/code-stubs-mips.cc
+++ b/deps/v8/src/mips/code-stubs-mips.cc
@@ -5924,11 +5924,15 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
void StringHelper::GenerateHashInit(MacroAssembler* masm,
- Register hash,
- Register character) {
- // hash = character + (character << 10);
- __ sll(hash, character, 10);
+ Register hash,
+ Register character) {
+ // hash = seed + character + ((seed + character) << 10);
+ __ LoadRoot(hash, Heap::kStringHashSeedRootIndex);
+ // Untag smi seed and add the character.
+ __ SmiUntag(hash);
__ addu(hash, hash, character);
+ __ sll(at, hash, 10);
+ __ addu(hash, hash, at);
// hash ^= hash >> 6;
__ srl(at, hash, 6);
__ xor_(hash, hash, at);
@@ -5936,8 +5940,8 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
- Register hash,
- Register character) {
+ Register hash,
+ Register character) {
// hash += character;
__ addu(hash, hash, character);
// hash += hash << 10;
diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc
index 53be7d1e17a..06e886c6bb1 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.cc
+++ b/deps/v8/src/mips/lithium-codegen-mips.cc
@@ -353,6 +353,18 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
}
+Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
+ Handle<Object> literal = chunk_->LookupLiteral(op);
+ ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
+ return literal;
+}
+
+
+bool LCodeGen::IsInteger32(LConstantOperand* op) const {
+ return chunk_->LookupLiteralRepresentation(op).IsInteger32();
+}
+
+
int LCodeGen::ToInteger32(LConstantOperand* op) const {
Handle<Object> value = chunk_->LookupLiteral(op);
ASSERT(chunk_->LookupLiteralRepresentation(op).IsInteger32());
diff --git a/deps/v8/src/mips/lithium-codegen-mips.h b/deps/v8/src/mips/lithium-codegen-mips.h
index 32d4fb3f4dd..68a7c5b1aa8 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.h
+++ b/deps/v8/src/mips/lithium-codegen-mips.h
@@ -93,6 +93,9 @@ class LCodeGen BASE_EMBEDDED {
// Returns a MemOperand pointing to the high word of a DoubleStackSlot.
MemOperand ToHighMemOperand(LOperand* op) const;
+ bool IsInteger32(LConstantOperand* op) const;
+ Handle<Object> ToHandle(LConstantOperand* op) const;
+
// Try to generate code for the entire chunk, but it may fail if the
// chunk contains constructs we cannot handle. Returns true if the
// code generation attempt succeeded.
diff --git a/deps/v8/src/mips/lithium-gap-resolver-mips.cc b/deps/v8/src/mips/lithium-gap-resolver-mips.cc
index 8f7f89cf5d1..2e5c64e7a2e 100644
--- a/deps/v8/src/mips/lithium-gap-resolver-mips.cc
+++ b/deps/v8/src/mips/lithium-gap-resolver-mips.cc
@@ -252,14 +252,24 @@ void LGapResolver::EmitMove(int index) {
}
} else if (source->IsConstantOperand()) {
- Operand source_operand = cgen_->ToOperand(source);
+ LConstantOperand* constant_source = LConstantOperand::cast(source);
if (destination->IsRegister()) {
- __ li(cgen_->ToRegister(destination), source_operand);
+ Register dst = cgen_->ToRegister(destination);
+ if (cgen_->IsInteger32(constant_source)) {
+ __ li(dst, Operand(cgen_->ToInteger32(constant_source)));
+ } else {
+ __ LoadObject(dst, cgen_->ToHandle(constant_source));
+ }
} else {
ASSERT(destination->IsStackSlot());
ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone.
- MemOperand destination_operand = cgen_->ToMemOperand(destination);
- __ li(kSavedValueRegister, source_operand);
+ if (cgen_->IsInteger32(constant_source)) {
+ __ li(kSavedValueRegister,
+ Operand(cgen_->ToInteger32(constant_source)));
+ } else {
+ __ LoadObject(kSavedValueRegister,
+ cgen_->ToHandle(constant_source));
+ }
__ sw(kSavedValueRegister, cgen_->ToMemOperand(destination));
}
diff --git a/deps/v8/src/mips/macro-assembler-mips.h b/deps/v8/src/mips/macro-assembler-mips.h
index 4e14fbf9770..bd5b94f57c6 100644
--- a/deps/v8/src/mips/macro-assembler-mips.h
+++ b/deps/v8/src/mips/macro-assembler-mips.h
@@ -264,6 +264,14 @@ class MacroAssembler: public Assembler {
void LoadHeapObject(Register dst, Handle<HeapObject> object);
+ void LoadObject(Register result, Handle<Object> object) {
+ if (object->IsHeapObject()) {
+ LoadHeapObject(result, Handle<HeapObject>::cast(object));
+ } else {
+ li(result, object);
+ }
+ }
+
// ---------------------------------------------------------------------------
// GC Support
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h
index 99a0bb08d29..c5cf060829f 100644
--- a/deps/v8/src/objects-inl.h
+++ b/deps/v8/src/objects-inl.h
@@ -2062,8 +2062,9 @@ int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
// EnsureCapacity will guarantee the hash table is never full.
while (true) {
Object* element = KeyAt(entry);
- if (element == isolate->heap()->undefined_value()) break; // Empty entry.
- if (element != isolate->heap()->the_hole_value() &&
+ // Empty entry.
+ if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
+ if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
Shape::IsMatch(key, element)) return entry;
entry = NextProbe(entry, count++, capacity);
}
@@ -4320,13 +4321,15 @@ uint32_t String::Hash() {
}
-StringHasher::StringHasher(int length)
+StringHasher::StringHasher(int length, uint32_t seed)
: length_(length),
- raw_running_hash_(0),
+ raw_running_hash_(seed),
array_index_(0),
is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
is_first_char_(true),
- is_valid_(true) { }
+ is_valid_(true) {
+ ASSERT(FLAG_randomize_string_hashes || raw_running_hash_ == 0);
+}
bool StringHasher::has_trivial_hash() {
@@ -4378,7 +4381,7 @@ uint32_t StringHasher::GetHash() {
result += (result << 3);
result ^= (result >> 11);
result += (result << 15);
- if (result == 0) {
+ if ((result & String::kHashBitMask) == 0) {
result = 27;
}
return result;
@@ -4386,8 +4389,8 @@ uint32_t StringHasher::GetHash() {
template <typename schar>
-uint32_t HashSequentialString(const schar* chars, int length) {
- StringHasher hasher(length);
+uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
+ StringHasher hasher(length, seed);
if (!hasher.has_trivial_hash()) {
int i;
for (i = 0; hasher.is_array_index() && (i < length); i++) {
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index f3a543f0774..36879099e0b 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -6682,6 +6682,20 @@ bool String::SlowEquals(String* other) {
// Fast check: if hash code is computed for both strings
// a fast negative check can be performed.
if (HasHashCode() && other->HasHashCode()) {
+#ifdef DEBUG
+ if (FLAG_enable_slow_asserts) {
+ if (Hash() != other->Hash()) {
+ bool found_difference = false;
+ for (int i = 0; i < len; i++) {
+ if (Get(i) != other->Get(i)) {
+ found_difference = true;
+ break;
+ }
+ }
+ ASSERT(found_difference);
+ }
+ }
+#endif
if (Hash() != other->Hash()) return false;
}
@@ -6817,12 +6831,16 @@ uint32_t String::ComputeAndSetHash() {
// Compute the hash code.
uint32_t field = 0;
if (StringShape(this).IsSequentialAscii()) {
- field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len);
+ field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(),
+ len,
+ GetHeap()->StringHashSeed());
} else if (StringShape(this).IsSequentialTwoByte()) {
- field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), len);
+ field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(),
+ len,
+ GetHeap()->StringHashSeed());
} else {
StringInputBuffer buffer(this);
- field = ComputeHashField(&buffer, len);
+ field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed());
}
// Store the hash code in the object.
@@ -6913,8 +6931,9 @@ uint32_t StringHasher::GetHashField() {
uint32_t String::ComputeHashField(unibrow::CharacterStream* buffer,
- int length) {
- StringHasher hasher(length);
+ int length,
+ uint32_t seed) {
+ StringHasher hasher(length, seed);
// Very long strings have a trivial hash that doesn't inspect the
// string contents.
@@ -10456,8 +10475,8 @@ class RegExpKey : public HashTableKey {
// Utf8SymbolKey carries a vector of chars as key.
class Utf8SymbolKey : public HashTableKey {
public:
- explicit Utf8SymbolKey(Vector<const char> string)
- : string_(string), hash_field_(0) { }
+ explicit Utf8SymbolKey(Vector<const char> string, uint32_t seed)
+ : string_(string), hash_field_(0), seed_(seed) { }
bool IsMatch(Object* string) {
return String::cast(string)->IsEqualTo(string_);
@@ -10468,7 +10487,7 @@ class Utf8SymbolKey : public HashTableKey {
unibrow::Utf8InputBuffer<> buffer(string_.start(),
static_cast<unsigned>(string_.length()));
chars_ = buffer.Length();
- hash_field_ = String::ComputeHashField(&buffer, chars_);
+ hash_field_ = String::ComputeHashField(&buffer, chars_, seed_);
uint32_t result = hash_field_ >> String::kHashShift;
ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
return result;
@@ -10487,17 +10506,18 @@ class Utf8SymbolKey : public HashTableKey {
Vector<const char> string_;
uint32_t hash_field_;
int chars_; // Caches the number of characters when computing the hash code.
+ uint32_t seed_;
};
template <typename Char>
class SequentialSymbolKey : public HashTableKey {
public:
- explicit SequentialSymbolKey(Vector<const Char> string)
- : string_(string), hash_field_(0) { }
+ explicit SequentialSymbolKey(Vector<const Char> string, uint32_t seed)
+ : string_(string), hash_field_(0), seed_(seed) { }
uint32_t Hash() {
- StringHasher hasher(string_.length());
+ StringHasher hasher(string_.length(), seed_);
// Very long strings have a trivial hash that doesn't inspect the
// string contents.
@@ -10533,14 +10553,15 @@ class SequentialSymbolKey : public HashTableKey {
Vector<const Char> string_;
uint32_t hash_field_;
+ uint32_t seed_;
};
class AsciiSymbolKey : public SequentialSymbolKey<char> {
public:
- explicit AsciiSymbolKey(Vector<const char> str)
- : SequentialSymbolKey<char>(str) { }
+ AsciiSymbolKey(Vector<const char> str, uint32_t seed)
+ : SequentialSymbolKey<char>(str, seed) { }
bool IsMatch(Object* string) {
return String::cast(string)->IsAsciiEqualTo(string_);
@@ -10557,13 +10578,14 @@ class SubStringAsciiSymbolKey : public HashTableKey {
public:
explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string,
int from,
- int length)
- : string_(string), from_(from), length_(length) { }
+ int length,
+ uint32_t seed)
+ : string_(string), from_(from), length_(length), seed_(seed) { }
uint32_t Hash() {
ASSERT(length_ >= 0);
ASSERT(from_ + length_ <= string_->length());
- StringHasher hasher(length_);
+ StringHasher hasher(length_, string_->GetHeap()->StringHashSeed());
// Very long strings have a trivial hash that doesn't inspect the
// string contents.
@@ -10615,13 +10637,14 @@ class SubStringAsciiSymbolKey : public HashTableKey {
int from_;
int length_;
uint32_t hash_field_;
+ uint32_t seed_;
};
class TwoByteSymbolKey : public SequentialSymbolKey<uc16> {
public:
- explicit TwoByteSymbolKey(Vector<const uc16> str)
- : SequentialSymbolKey<uc16>(str) { }
+ explicit TwoByteSymbolKey(Vector<const uc16> str, uint32_t seed)
+ : SequentialSymbolKey<uc16>(str, seed) { }
bool IsMatch(Object* string) {
return String::cast(string)->IsTwoByteEqualTo(string_);
@@ -11406,10 +11429,12 @@ MaybeObject* SymbolTable::LookupString(String* string, Object** s) {
// algorithm.
class TwoCharHashTableKey : public HashTableKey {
public:
- TwoCharHashTableKey(uint32_t c1, uint32_t c2)
+ TwoCharHashTableKey(uint32_t c1, uint32_t c2, uint32_t seed)
: c1_(c1), c2_(c2) {
// Char 1.
- uint32_t hash = c1 + (c1 << 10);
+ uint32_t hash = seed;
+ hash += c1;
+ hash += hash << 10;
hash ^= hash >> 6;
// Char 2.
hash += c2;
@@ -11419,9 +11444,9 @@ class TwoCharHashTableKey : public HashTableKey {
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
- if (hash == 0) hash = 27;
+ if ((hash & String::kHashBitMask) == 0) hash = 27;
#ifdef DEBUG
- StringHasher hasher(2);
+ StringHasher hasher(2, seed);
hasher.AddCharacter(c1);
hasher.AddCharacter(c2);
// If this assert fails then we failed to reproduce the two-character
@@ -11478,7 +11503,7 @@ bool SymbolTable::LookupSymbolIfExists(String* string, String** symbol) {
bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1,
uint32_t c2,
String** symbol) {
- TwoCharHashTableKey key(c1, c2);
+ TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed());
int entry = FindEntry(&key);
if (entry == kNotFound) {
return false;
@@ -11491,15 +11516,16 @@ bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1,
}
-MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) {
- Utf8SymbolKey key(str);
+MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str,
+ Object** s) {
+ Utf8SymbolKey key(str, GetHeap()->StringHashSeed());
return LookupKey(&key, s);
}
MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str,
Object** s) {
- AsciiSymbolKey key(str);
+ AsciiSymbolKey key(str, GetHeap()->StringHashSeed());
return LookupKey(&key, s);
}
@@ -11508,14 +11534,14 @@ MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str,
int from,
int length,
Object** s) {
- SubStringAsciiSymbolKey key(str, from, length);
+ SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed());
return LookupKey(&key, s);
}
MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str,
Object** s) {
- TwoByteSymbolKey key(str);
+ TwoByteSymbolKey key(str, GetHeap()->StringHashSeed());
return LookupKey(&key, s);
}
diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h
index a0e77cb86db..541334a5dc1 100644
--- a/deps/v8/src/objects.h
+++ b/deps/v8/src/objects.h
@@ -6117,7 +6117,7 @@ enum RobustnessFlag {ROBUST_STRING_TRAVERSAL, FAST_STRING_TRAVERSAL};
class StringHasher {
public:
- explicit inline StringHasher(int length);
+ explicit inline StringHasher(int length, uint32_t seed);
// Returns true if the hash of this string can be computed without
// looking at the contents.
@@ -6168,7 +6168,9 @@ class StringHasher {
// Calculates string hash.
template <typename schar>
-inline uint32_t HashSequentialString(const schar* chars, int length);
+inline uint32_t HashSequentialString(const schar* chars,
+ int length,
+ uint32_t seed);
// The characteristics of a string are stored in its map. Retrieving these
@@ -6391,7 +6393,8 @@ class String: public HeapObject {
inline uint32_t Hash();
static uint32_t ComputeHashField(unibrow::CharacterStream* buffer,
- int length);
+ int length,
+ uint32_t seed);
static bool ComputeArrayIndex(unibrow::CharacterStream* buffer,
uint32_t* index,
@@ -6456,6 +6459,10 @@ class String: public HeapObject {
// Shift constant retrieving hash code from hash field.
static const int kHashShift = kNofHashBitFields;
+ // Only these bits are relevant in the hash, since the top two are shifted
+ // out.
+ static const uint32_t kHashBitMask = 0xffffffffu >> kHashShift;
+
// Array index strings this short can keep their index in the hash
// field.
static const int kMaxCachedArrayIndexLength = 7;
diff --git a/deps/v8/src/platform-openbsd.cc b/deps/v8/src/platform-openbsd.cc
index b3f4924eee5..772d08b587c 100644
--- a/deps/v8/src/platform-openbsd.cc
+++ b/deps/v8/src/platform-openbsd.cc
@@ -25,8 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Platform specific code for OpenBSD goes here. For the POSIX comaptible parts
-// the implementation is in platform-posix.cc.
+// Platform specific code for OpenBSD and NetBSD goes here. For the POSIX
+// comaptible parts the implementation is in platform-posix.cc.
#include <pthread.h>
#include <semaphore.h>
@@ -742,8 +742,20 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
if (sample == NULL) sample = &sample_obj;
// Extracting the sample from the context is extremely machine dependent.
- ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
sample->state = isolate->current_vm_state();
+ ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
+#ifdef __NetBSD__
+ mcontext_t& mcontext = ucontext->uc_mcontext;
+#if V8_HOST_ARCH_IA32
+ sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]);
+ sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]);
+ sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]);
+#elif V8_HOST_ARCH_X64
+ sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]);
+ sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]);
+ sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]);
+#endif // V8_HOST_ARCH
+#else // OpenBSD
#if V8_HOST_ARCH_IA32
sample->pc = reinterpret_cast<Address>(ucontext->sc_eip);
sample->sp = reinterpret_cast<Address>(ucontext->sc_esp);
@@ -752,7 +764,8 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
sample->pc = reinterpret_cast<Address>(ucontext->sc_rip);
sample->sp = reinterpret_cast<Address>(ucontext->sc_rsp);
sample->fp = reinterpret_cast<Address>(ucontext->sc_rbp);
-#endif
+#endif // V8_HOST_ARCH
+#endif // __NetBSD__
sampler->SampleStack(sample);
sampler->Tick(sample);
}
diff --git a/deps/v8/src/platform-posix.cc b/deps/v8/src/platform-posix.cc
index a59d0bbdc3d..08417ff9bcf 100644
--- a/deps/v8/src/platform-posix.cc
+++ b/deps/v8/src/platform-posix.cc
@@ -71,7 +71,8 @@ intptr_t OS::MaxVirtualMemory() {
intptr_t OS::CommitPageSize() {
- return 4096;
+ static intptr_t page_size = getpagesize();
+ return page_size;
}
diff --git a/deps/v8/src/profile-generator.cc b/deps/v8/src/profile-generator.cc
index a46122be67e..00fc7b736a7 100644
--- a/deps/v8/src/profile-generator.cc
+++ b/deps/v8/src/profile-generator.cc
@@ -110,7 +110,8 @@ const char* StringsStorage::GetCopy(const char* src) {
Vector<char> dst = Vector<char>::New(len + 1);
OS::StrNCpy(dst, src, len);
dst[len] = '\0';
- uint32_t hash = HashSequentialString(dst.start(), len);
+ uint32_t hash =
+ HashSequentialString(dst.start(), len, HEAP->StringHashSeed());
return AddOrDisposeString(dst.start(), hash);
}
@@ -143,7 +144,8 @@ const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
DeleteArray(str.start());
return format;
}
- uint32_t hash = HashSequentialString(str.start(), len);
+ uint32_t hash = HashSequentialString(
+ str.start(), len, HEAP->StringHashSeed());
return AddOrDisposeString(str.start(), hash);
}
@@ -153,7 +155,8 @@ const char* StringsStorage::GetName(String* name) {
int length = Min(kMaxNameSize, name->length());
SmartArrayPointer<char> data =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, 0, length);
- uint32_t hash = HashSequentialString(*data, length);
+ uint32_t hash =
+ HashSequentialString(*data, length, name->GetHeap()->StringHashSeed());
return AddOrDisposeString(data.Detach(), hash);
}
return "";
@@ -1501,7 +1504,9 @@ void HeapObjectsMap::RemoveDeadEntries() {
uint64_t HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
uint64_t id = static_cast<uint64_t>(info->GetHash());
const char* label = info->GetLabel();
- id ^= HashSequentialString(label, static_cast<int>(strlen(label)));
+ id ^= HashSequentialString(label,
+ static_cast<int>(strlen(label)),
+ HEAP->StringHashSeed());
intptr_t element_count = info->GetElementCount();
if (element_count != -1)
id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count));
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc
index fb46114f66e..811d72d91d6 100644
--- a/deps/v8/src/runtime.cc
+++ b/deps/v8/src/runtime.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -8707,14 +8707,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Call) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
HandleScope scope(isolate);
ASSERT(args.length() == 5);
- CONVERT_CHECKED(JSReceiver, fun, args[0]);
- Object* receiver = args[1];
- CONVERT_CHECKED(JSObject, arguments, args[2]);
- CONVERT_CHECKED(Smi, shift, args[3]);
- CONVERT_CHECKED(Smi, arity, args[4]);
-
- int offset = shift->value();
- int argc = arity->value();
+ CONVERT_ARG_CHECKED(JSReceiver, fun, 0);
+ Handle<Object> receiver = args.at<Object>(1);
+ CONVERT_ARG_CHECKED(JSObject, arguments, 2);
+ CONVERT_SMI_ARG_CHECKED(offset, 3);
+ CONVERT_SMI_ARG_CHECKED(argc, 4);
ASSERT(offset >= 0);
ASSERT(argc >= 0);
@@ -8730,17 +8727,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) {
}
for (int i = 0; i < argc; ++i) {
- MaybeObject* maybe = arguments->GetElement(offset + i);
- Object* object;
- if (!maybe->To<Object>(&object)) return maybe;
- argv[i] = Handle<Object>(object);
+ argv[i] = Object::GetElement(arguments, offset + i);
}
bool threw;
- Handle<JSReceiver> hfun(fun);
- Handle<Object> hreceiver(receiver);
Handle<Object> result =
- Execution::Call(hfun, hreceiver, argc, argv, &threw, true);
+ Execution::Call(fun, receiver, argc, argv, &threw, true);
if (threw) return Failure::Exception();
return *result;
diff --git a/deps/v8/src/spaces.cc b/deps/v8/src/spaces.cc
index 84b0f1bcb49..ebd3e651920 100644
--- a/deps/v8/src/spaces.cc
+++ b/deps/v8/src/spaces.cc
@@ -1256,24 +1256,29 @@ bool SemiSpace::ShrinkTo(int new_capacity) {
ASSERT((new_capacity & Page::kPageAlignmentMask) == 0);
ASSERT(new_capacity >= initial_capacity_);
ASSERT(new_capacity < capacity_);
- // Semispaces grow backwards from the end of their allocated capacity,
- // so we find the before and after start addresses relative to the
- // end of the space.
- Address space_end = start_ + maximum_capacity_;
- Address old_start = space_end - capacity_;
- size_t delta = capacity_ - new_capacity;
- ASSERT(IsAligned(delta, OS::AllocateAlignment()));
- if (!heap()->isolate()->memory_allocator()->UncommitBlock(old_start, delta)) {
- return false;
+ if (is_committed()) {
+ // Semispaces grow backwards from the end of their allocated capacity,
+ // so we find the before and after start addresses relative to the
+ // end of the space.
+ Address space_end = start_ + maximum_capacity_;
+ Address old_start = space_end - capacity_;
+ size_t delta = capacity_ - new_capacity;
+ ASSERT(IsAligned(delta, OS::AllocateAlignment()));
+
+ MemoryAllocator* allocator = heap()->isolate()->memory_allocator();
+ if (!allocator->UncommitBlock(old_start, delta)) {
+ return false;
+ }
+
+ int pages_after = new_capacity / Page::kPageSize;
+ NewSpacePage* new_last_page =
+ NewSpacePage::FromAddress(space_end - pages_after * Page::kPageSize);
+ new_last_page->set_next_page(anchor());
+ anchor()->set_prev_page(new_last_page);
+ ASSERT((current_page_ <= first_page()) && (current_page_ >= new_last_page));
}
- capacity_ = new_capacity;
- int pages_after = capacity_ / Page::kPageSize;
- NewSpacePage* new_last_page =
- NewSpacePage::FromAddress(space_end - pages_after * Page::kPageSize);
- new_last_page->set_next_page(anchor());
- anchor()->set_prev_page(new_last_page);
- ASSERT((current_page_ <= first_page()) && (current_page_ >= new_last_page));
+ capacity_ = new_capacity;
return true;
}
diff --git a/deps/v8/src/store-buffer.cc b/deps/v8/src/store-buffer.cc
index c0315f27a8e..0f1fed0286e 100644
--- a/deps/v8/src/store-buffer.cc
+++ b/deps/v8/src/store-buffer.cc
@@ -49,8 +49,9 @@ StoreBuffer::StoreBuffer(Heap* heap)
callback_(NULL),
may_move_store_buffer_entries_(true),
virtual_memory_(NULL),
- hash_map_1_(NULL),
- hash_map_2_(NULL) {
+ hash_set_1_(NULL),
+ hash_set_2_(NULL),
+ hash_sets_are_empty_(true) {
}
@@ -97,18 +98,19 @@ void StoreBuffer::Setup() {
false)); // Not executable.
heap_->public_set_store_buffer_top(start_);
- hash_map_1_ = new uintptr_t[kHashMapLength];
- hash_map_2_ = new uintptr_t[kHashMapLength];
+ hash_set_1_ = new uintptr_t[kHashSetLength];
+ hash_set_2_ = new uintptr_t[kHashSetLength];
+ hash_sets_are_empty_ = false;
- ZapHashTables();
+ ClearFilteringHashSets();
}
void StoreBuffer::TearDown() {
delete virtual_memory_;
delete old_virtual_memory_;
- delete[] hash_map_1_;
- delete[] hash_map_2_;
+ delete[] hash_set_1_;
+ delete[] hash_set_2_;
old_start_ = old_top_ = old_limit_ = old_reserved_limit_ = NULL;
start_ = limit_ = NULL;
heap_->public_set_store_buffer_top(start_);
@@ -148,7 +150,6 @@ static int CompareAddresses(const void* void_a, const void* void_b) {
void StoreBuffer::Uniq() {
- ASSERT(HashTablesAreZapped());
// Remove adjacent duplicates and cells that do not point at new space.
Address previous = NULL;
Address* write = old_start_;
@@ -272,13 +273,16 @@ void StoreBuffer::Filter(int flag) {
}
}
old_top_ = new_top;
+
+ // Filtering hash sets are inconsistent with the store buffer after this
+ // operation.
+ ClearFilteringHashSets();
}
void StoreBuffer::SortUniq() {
Compact();
if (old_buffer_is_sorted_) return;
- ZapHashTables();
qsort(reinterpret_cast<void*>(old_start_),
old_top_ - old_start_,
sizeof(*old_top_),
@@ -286,6 +290,10 @@ void StoreBuffer::SortUniq() {
Uniq();
old_buffer_is_sorted_ = true;
+
+ // Filtering hash sets are inconsistent with the store buffer after this
+ // operation.
+ ClearFilteringHashSets();
}
@@ -301,35 +309,23 @@ bool StoreBuffer::PrepareForIteration() {
if (page_has_scan_on_scavenge_flag) {
Filter(MemoryChunk::SCAN_ON_SCAVENGE);
}
- ZapHashTables();
+
+ // Filtering hash sets are inconsistent with the store buffer after
+ // iteration.
+ ClearFilteringHashSets();
+
return page_has_scan_on_scavenge_flag;
}
#ifdef DEBUG
void StoreBuffer::Clean() {
- ZapHashTables();
+ ClearFilteringHashSets();
Uniq(); // Also removes things that no longer point to new space.
CheckForFullBuffer();
}
-static bool Zapped(char* start, int size) {
- for (int i = 0; i < size; i++) {
- if (start[i] != 0) return false;
- }
- return true;
-}
-
-
-bool StoreBuffer::HashTablesAreZapped() {
- return Zapped(reinterpret_cast<char*>(hash_map_1_),
- sizeof(uintptr_t) * kHashMapLength) &&
- Zapped(reinterpret_cast<char*>(hash_map_2_),
- sizeof(uintptr_t) * kHashMapLength);
-}
-
-
static Address* in_store_buffer_1_element_cache = NULL;
@@ -357,18 +353,21 @@ bool StoreBuffer::CellIsInStoreBuffer(Address cell_address) {
#endif
-void StoreBuffer::ZapHashTables() {
- memset(reinterpret_cast<void*>(hash_map_1_),
- 0,
- sizeof(uintptr_t) * kHashMapLength);
- memset(reinterpret_cast<void*>(hash_map_2_),
- 0,
- sizeof(uintptr_t) * kHashMapLength);
+void StoreBuffer::ClearFilteringHashSets() {
+ if (!hash_sets_are_empty_) {
+ memset(reinterpret_cast<void*>(hash_set_1_),
+ 0,
+ sizeof(uintptr_t) * kHashSetLength);
+ memset(reinterpret_cast<void*>(hash_set_2_),
+ 0,
+ sizeof(uintptr_t) * kHashSetLength);
+ hash_sets_are_empty_ = true;
+ }
}
void StoreBuffer::GCPrologue() {
- ZapHashTables();
+ ClearFilteringHashSets();
during_gc_ = true;
}
@@ -676,8 +675,9 @@ void StoreBuffer::Compact() {
ASSERT(may_move_store_buffer_entries_);
// Goes through the addresses in the store buffer attempting to remove
// duplicates. In the interest of speed this is a lossy operation. Some
- // duplicates will remain. We have two hash tables with different hash
+ // duplicates will remain. We have two hash sets with different hash
// functions to reduce the number of unnecessary clashes.
+ hash_sets_are_empty_ = false; // Hash sets are in use.
for (Address* current = start_; current < top; current++) {
ASSERT(!heap_->cell_space()->Contains(*current));
ASSERT(!heap_->code_space()->Contains(*current));
@@ -686,21 +686,21 @@ void StoreBuffer::Compact() {
// Shift out the last bits including any tags.
int_addr >>= kPointerSizeLog2;
int hash1 =
- ((int_addr ^ (int_addr >> kHashMapLengthLog2)) & (kHashMapLength - 1));
- if (hash_map_1_[hash1] == int_addr) continue;
- int hash2 =
- ((int_addr - (int_addr >> kHashMapLengthLog2)) & (kHashMapLength - 1));
- hash2 ^= hash2 >> (kHashMapLengthLog2 * 2);
- if (hash_map_2_[hash2] == int_addr) continue;
- if (hash_map_1_[hash1] == 0) {
- hash_map_1_[hash1] = int_addr;
- } else if (hash_map_2_[hash2] == 0) {
- hash_map_2_[hash2] = int_addr;
+ ((int_addr ^ (int_addr >> kHashSetLengthLog2)) & (kHashSetLength - 1));
+ if (hash_set_1_[hash1] == int_addr) continue;
+ uintptr_t hash2 = (int_addr - (int_addr >> kHashSetLengthLog2));
+ hash2 ^= hash2 >> (kHashSetLengthLog2 * 2);
+ hash2 &= (kHashSetLength - 1);
+ if (hash_set_2_[hash2] == int_addr) continue;
+ if (hash_set_1_[hash1] == 0) {
+ hash_set_1_[hash1] = int_addr;
+ } else if (hash_set_2_[hash2] == 0) {
+ hash_set_2_[hash2] = int_addr;
} else {
// Rather than slowing down we just throw away some entries. This will
// cause some duplicates to remain undetected.
- hash_map_1_[hash1] = int_addr;
- hash_map_2_[hash2] = 0;
+ hash_set_1_[hash1] = int_addr;
+ hash_set_2_[hash2] = 0;
}
old_buffer_is_sorted_ = false;
old_buffer_is_filtered_ = false;
diff --git a/deps/v8/src/store-buffer.h b/deps/v8/src/store-buffer.h
index ab2593808fd..204fa3ff4e0 100644
--- a/deps/v8/src/store-buffer.h
+++ b/deps/v8/src/store-buffer.h
@@ -85,8 +85,8 @@ class StoreBuffer {
static const int kStoreBufferSize = kStoreBufferOverflowBit;
static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address);
static const int kOldStoreBufferLength = kStoreBufferLength * 16;
- static const int kHashMapLengthLog2 = 12;
- static const int kHashMapLength = 1 << kHashMapLengthLog2;
+ static const int kHashSetLengthLog2 = 12;
+ static const int kHashSetLength = 1 << kHashSetLengthLog2;
void Compact();
@@ -148,13 +148,18 @@ class StoreBuffer {
bool may_move_store_buffer_entries_;
VirtualMemory* virtual_memory_;
- uintptr_t* hash_map_1_;
- uintptr_t* hash_map_2_;
+
+ // Two hash sets used for filtering.
+ // If address is in the hash set then it is guaranteed to be in the
+ // old part of the store buffer.
+ uintptr_t* hash_set_1_;
+ uintptr_t* hash_set_2_;
+ bool hash_sets_are_empty_;
+
+ void ClearFilteringHashSets();
void CheckForFullBuffer();
void Uniq();
- void ZapHashTables();
- bool HashTablesAreZapped();
void ExemptPopularPages(int prime_sample_step, int threshold);
void FindPointersToNewSpaceInRegion(Address start,
diff --git a/deps/v8/src/v8.cc b/deps/v8/src/v8.cc
index 0354fc101a8..c882d86f8d9 100644
--- a/deps/v8/src/v8.cc
+++ b/deps/v8/src/v8.cc
@@ -51,6 +51,7 @@ bool V8::has_been_setup_ = false;
bool V8::has_been_disposed_ = false;
bool V8::has_fatal_error_ = false;
bool V8::use_crankshaft_ = true;
+List<CallCompletedCallback>* V8::call_completed_callbacks_ = NULL;
static Mutex* entropy_mutex = OS::CreateMutex();
static EntropySource entropy_source;
@@ -104,6 +105,9 @@ void V8::TearDown() {
is_running_ = false;
has_been_disposed_ = true;
+
+ delete call_completed_callbacks_;
+ call_completed_callbacks_ = NULL;
}
@@ -169,6 +173,41 @@ bool V8::IdleNotification(int hint) {
}
+void V8::AddCallCompletedCallback(CallCompletedCallback callback) {
+ if (call_completed_callbacks_ == NULL) { // Lazy init.
+ call_completed_callbacks_ = new List<CallCompletedCallback>();
+ }
+ for (int i = 0; i < call_completed_callbacks_->length(); i++) {
+ if (callback == call_completed_callbacks_->at(i)) return;
+ }
+ call_completed_callbacks_->Add(callback);
+}
+
+
+void V8::RemoveCallCompletedCallback(CallCompletedCallback callback) {
+ if (call_completed_callbacks_ == NULL) return;
+ for (int i = 0; i < call_completed_callbacks_->length(); i++) {
+ if (callback == call_completed_callbacks_->at(i)) {
+ call_completed_callbacks_->Remove(i);
+ }
+ }
+}
+
+
+void V8::FireCallCompletedCallback(Isolate* isolate) {
+ if (call_completed_callbacks_ == NULL) return;
+ HandleScopeImplementer* handle_scope_implementer =
+ isolate->handle_scope_implementer();
+ if (!handle_scope_implementer->CallDepthIsZero()) return;
+ // Fire callbacks. Increase call depth to prevent recursive callbacks.
+ handle_scope_implementer->IncrementCallDepth();
+ for (int i = 0; i < call_completed_callbacks_->length(); i++) {
+ call_completed_callbacks_->at(i)();
+ }
+ handle_scope_implementer->DecrementCallDepth();
+}
+
+
// Use a union type to avoid type-aliasing optimizations in GCC.
typedef union {
double double_value;
diff --git a/deps/v8/src/v8.h b/deps/v8/src/v8.h
index 71e7fe4bf4b..b9a3e053861 100644
--- a/deps/v8/src/v8.h
+++ b/deps/v8/src/v8.h
@@ -108,6 +108,10 @@ class V8 : public AllStatic {
// Idle notification directly from the API.
static bool IdleNotification(int hint);
+ static void AddCallCompletedCallback(CallCompletedCallback callback);
+ static void RemoveCallCompletedCallback(CallCompletedCallback callback);
+ static void FireCallCompletedCallback(Isolate* isolate);
+
private:
static void InitializeOncePerProcess();
@@ -123,6 +127,8 @@ class V8 : public AllStatic {
static bool has_been_disposed_;
// True if we are using the crankshaft optimizing compiler.
static bool use_crankshaft_;
+ // List of callbacks when a Call completes.
+ static List<CallCompletedCallback>* call_completed_callbacks_;
};
diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc
index 46b2b1a3d52..617b7d1c502 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 3
#define MINOR_VERSION 8
-#define BUILD_NUMBER 4
+#define BUILD_NUMBER 5
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/deps/v8/src/x64/builtins-x64.cc b/deps/v8/src/x64/builtins-x64.cc
index dff55fb74de..ef63c7a27bb 100644
--- a/deps/v8/src/x64/builtins-x64.cc
+++ b/deps/v8/src/x64/builtins-x64.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -1199,7 +1199,8 @@ static void AllocateJSArray(MacroAssembler* masm,
// a construct call and a normal call.
static void ArrayNativeCode(MacroAssembler* masm,
Label *call_generic_code) {
- Label argc_one_or_more, argc_two_or_more, empty_array, not_empty_array;
+ Label argc_one_or_more, argc_two_or_more, empty_array, not_empty_array,
+ has_non_smi_element;
// Check for array construction with zero arguments.
__ testq(rax, rax);
@@ -1306,7 +1307,7 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ bind(&loop);
__ movq(kScratchRegister, Operand(r9, rcx, times_pointer_size, 0));
if (FLAG_smi_only_arrays) {
- __ JumpIfNotSmi(kScratchRegister, call_generic_code);
+ __ JumpIfNotSmi(kScratchRegister, &has_non_smi_element);
}
__ movq(Operand(rdx, 0), kScratchRegister);
__ addq(rdx, Immediate(kPointerSize));
@@ -1324,6 +1325,10 @@ static void ArrayNativeCode(MacroAssembler* masm,
__ push(rcx);
__ movq(rax, rbx);
__ ret(0);
+
+ __ bind(&has_non_smi_element);
+ __ UndoAllocationInNewSpace(rbx);
+ __ jmp(call_generic_code);
}
diff --git a/deps/v8/src/x64/code-stubs-x64.cc b/deps/v8/src/x64/code-stubs-x64.cc
index 1d67bae60ad..ea9c494e8a9 100644
--- a/deps/v8/src/x64/code-stubs-x64.cc
+++ b/deps/v8/src/x64/code-stubs-x64.cc
@@ -4958,10 +4958,13 @@ void StringHelper::GenerateHashInit(MacroAssembler* masm,
Register hash,
Register character,
Register scratch) {
- // hash = character + (character << 10);
- __ movl(hash, character);
- __ shll(hash, Immediate(10));
- __ addl(hash, character);
+ // hash = (seed + character) + ((seed + character) << 10);
+ __ LoadRoot(scratch, Heap::kStringHashSeedRootIndex);
+ __ SmiToInteger32(scratch, scratch);
+ __ addl(scratch, character);
+ __ movl(hash, scratch);
+ __ shll(scratch, Immediate(10));
+ __ addl(hash, scratch);
// hash ^= hash >> 6;
__ movl(scratch, hash);
__ shrl(scratch, Immediate(6));
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index dab8b7c286c..fb8becda384 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -14238,7 +14238,7 @@ THREADED_TEST(RoundRobinGetFromCache) {
" for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);"
" for (var i = 0; i < 16; i++) {"
" var v = %_GetFromCache(0, keys[i]);"
- " if (v !== values[i])"
+ " if (v.toString() !== values[i].toString())"
" return 'Wrong value for ' + "
" keys[i] + ': ' + v + ' vs. ' + values[i];"
" };"
@@ -15726,3 +15726,98 @@ THREADED_TEST(ForeignFunctionReceiver) {
foreign_context.Dispose();
}
+
+
+uint8_t callback_fired = 0;
+
+
+void CallCompletedCallback1() {
+ i::OS::Print("Firing callback 1.\n");
+ callback_fired ^= 1; // Toggle first bit.
+}
+
+
+void CallCompletedCallback2() {
+ i::OS::Print("Firing callback 2.\n");
+ callback_fired ^= 2; // Toggle second bit.
+}
+
+
+Handle<Value> RecursiveCall(const Arguments& args) {
+ int32_t level = args[0]->Int32Value();
+ if (level < 3) {
+ level++;
+ i::OS::Print("Entering recursion level %d.\n", level);
+ char script[64];
+ i::Vector<char> script_vector(script, sizeof(script));
+ i::OS::SNPrintF(script_vector, "recursion(%d)", level);
+ CompileRun(script_vector.start());
+ i::OS::Print("Leaving recursion level %d.\n", level);
+ CHECK_EQ(0, callback_fired);
+ } else {
+ i::OS::Print("Recursion ends.\n");
+ CHECK_EQ(0, callback_fired);
+ }
+ return Undefined();
+}
+
+
+TEST(CallCompletedCallback) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::Handle<v8::FunctionTemplate> recursive_runtime =
+ v8::FunctionTemplate::New(RecursiveCall);
+ env->Global()->Set(v8_str("recursion"),
+ recursive_runtime->GetFunction());
+ // Adding the same callback a second time has no effect.
+ v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
+ v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
+ v8::V8::AddCallCompletedCallback(CallCompletedCallback2);
+ i::OS::Print("--- Script (1) ---\n");
+ Local<Script> script =
+ v8::Script::Compile(v8::String::New("recursion(0)"));
+ script->Run();
+ CHECK_EQ(3, callback_fired);
+
+ i::OS::Print("\n--- Script (2) ---\n");
+ callback_fired = 0;
+ v8::V8::RemoveCallCompletedCallback(CallCompletedCallback1);
+ script->Run();
+ CHECK_EQ(2, callback_fired);
+
+ i::OS::Print("\n--- Function ---\n");
+ callback_fired = 0;
+ Local<Function> recursive_function =
+ Local<Function>::Cast(env->Global()->Get(v8_str("recursion")));
+ v8::Handle<Value> args[] = { v8_num(0) };
+ recursive_function->Call(env->Global(), 1, args);
+ CHECK_EQ(2, callback_fired);
+}
+
+
+void CallCompletedCallbackNoException() {
+ v8::HandleScope scope;
+ CompileRun("1+1;");
+}
+
+
+void CallCompletedCallbackException() {
+ v8::HandleScope scope;
+ CompileRun("throw 'second exception';");
+}
+
+
+TEST(CallCompletedCallbackOneException) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::V8::AddCallCompletedCallback(CallCompletedCallbackNoException);
+ CompileRun("throw 'exception';");
+}
+
+
+TEST(CallCompletedCallbackTwoExceptions) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::V8::AddCallCompletedCallback(CallCompletedCallbackException);
+ CompileRun("throw 'first exception';");
+}
diff --git a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js
index 9ed1dbbedba..8447df536d3 100644
--- a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js
+++ b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js
@@ -50,10 +50,12 @@ function listener(event, exec_state, event_data, data) {
var expected_y = (i + 1) * 2 + 2 + ((i + 1) * 2 + 2) / 100;
// All frames except the bottom one has normal variables a and b.
- assertEquals('a', frame.localName(0));
- assertEquals('b', frame.localName(1));
- assertEquals(expected_a, frame.localValue(0).value());
- assertEquals(expected_b, frame.localValue(1).value());
+ var a = ('a' === frame.localName(0)) ? 0 : 1;
+ var b = 1 - a;
+ assertEquals('a', frame.localName(a));
+ assertEquals('b', frame.localName(b));
+ assertEquals(expected_a, frame.localValue(a).value());
+ assertEquals(expected_b, frame.localValue(b).value());
// All frames except the bottom one has arguments variables x and y.
assertEquals('x', frame.argumentName(0));
diff --git a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js
index 683c139d833..c3cd5eb2eb8 100644
--- a/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js
+++ b/deps/v8/test/mjsunit/debug-evaluate-locals-optimized.js
@@ -50,10 +50,12 @@ function listener(event, exec_state, event_data, data) {
var expected_y = (i + 1) * 2 + 2;
// All frames except the bottom one has normal variables a and b.
- assertEquals('a', frame.localName(0));
- assertEquals('b', frame.localName(1));
- assertEquals(expected_a, frame.localValue(0).value());
- assertEquals(expected_b, frame.localValue(1).value());
+ var a = ('a' === frame.localName(0)) ? 0 : 1;
+ var b = 1 - a;
+ assertEquals('a', frame.localName(a));
+ assertEquals('b', frame.localName(b));
+ assertEquals(expected_a, frame.localValue(a).value());
+ assertEquals(expected_b, frame.localValue(b).value());
// All frames except the bottom one has arguments variables x and y.
assertEquals('x', frame.argumentName(0));
@@ -119,7 +121,7 @@ function listener(event, exec_state, event_data, data) {
listenerComplete = true;
}
} catch (e) {
- exception = e
+ exception = e.stack;
};
};
diff --git a/deps/v8/test/mjsunit/harmony/collections.js b/deps/v8/test/mjsunit/harmony/collections.js
index 4b435c16141..412e6f14c32 100644
--- a/deps/v8/test/mjsunit/harmony/collections.js
+++ b/deps/v8/test/mjsunit/harmony/collections.js
@@ -274,6 +274,40 @@ var o = Object.create({}, { myValue: {
assertEquals(10, o.myValue);
+// Regression test for issue 1884: Invoking any of the methods for Harmony
+// maps, sets, or weak maps, with a wrong type of receiver should be throwing
+// a proper TypeError.
+var alwaysBogus = [ undefined, null, true, "x", 23, {} ];
+var bogusReceiversTestSet = [
+ { proto: Set.prototype,
+ funcs: [ 'add', 'has', 'delete' ],
+ receivers: alwaysBogus.concat([ new Map, new WeakMap ]),
+ },
+ { proto: Map.prototype,
+ funcs: [ 'get', 'set', 'has', 'delete' ],
+ receivers: alwaysBogus.concat([ new Set, new WeakMap ]),
+ },
+ { proto: WeakMap.prototype,
+ funcs: [ 'get', 'set', 'has', 'delete' ],
+ receivers: alwaysBogus.concat([ new Set, new Map ]),
+ },
+];
+function TestBogusReceivers(testSet) {
+ for (var i = 0; i < testSet.length; i++) {
+ var proto = testSet[i].proto;
+ var funcs = testSet[i].funcs;
+ var receivers = testSet[i].receivers;
+ for (var j = 0; j < funcs.length; j++) {
+ var func = proto[funcs[j]];
+ for (var k = 0; k < receivers.length; k++) {
+ assertThrows(function () { func.call(receivers[k], {}) }, TypeError);
+ }
+ }
+ }
+}
+TestBogusReceivers(bogusReceiversTestSet);
+
+
// Stress Test
// There is a proposed stress-test available at the es-discuss mailing list
// which cannot be reasonably automated. Check it out by hand if you like:
diff --git a/deps/v8/tools/grokdump.py b/deps/v8/tools/grokdump.py
index 0c7e125e4b6..44f9518f63f 100755
--- a/deps/v8/tools/grokdump.py
+++ b/deps/v8/tools/grokdump.py
@@ -486,7 +486,7 @@ class MinidumpReader(object):
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
return self.exception_context.rsp
elif self.arch == MD_CPU_ARCHITECTURE_X86:
- return self.exception_context.rbp
+ return self.exception_context.esp
def FormatIntPtr(self, value):
if self.arch == MD_CPU_ARCHITECTURE_AMD64:
@@ -523,13 +523,20 @@ INSTANCE_TYPES = {
66: "EXTERNAL_SYMBOL_TYPE",
74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE",
70: "EXTERNAL_ASCII_SYMBOL_TYPE",
+ 82: "SHORT_EXTERNAL_SYMBOL_TYPE",
+ 90: "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE",
+ 86: "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE",
0: "STRING_TYPE",
4: "ASCII_STRING_TYPE",
1: "CONS_STRING_TYPE",
5: "CONS_ASCII_STRING_TYPE",
+ 3: "SLICED_STRING_TYPE",
2: "EXTERNAL_STRING_TYPE",
10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE",
6: "EXTERNAL_ASCII_STRING_TYPE",
+ 18: "SHORT_EXTERNAL_STRING_TYPE",
+ 26: "SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE",
+ 22: "SHORT_EXTERNAL_ASCII_STRING_TYPE",
6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE",
128: "MAP_TYPE",
129: "CODE_TYPE",
@@ -538,43 +545,45 @@ INSTANCE_TYPES = {
132: "HEAP_NUMBER_TYPE",
133: "FOREIGN_TYPE",
134: "BYTE_ARRAY_TYPE",
- 135: "EXTERNAL_BYTE_ARRAY_TYPE",
- 136: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE",
- 137: "EXTERNAL_SHORT_ARRAY_TYPE",
- 138: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE",
- 139: "EXTERNAL_INT_ARRAY_TYPE",
- 140: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE",
- 141: "EXTERNAL_FLOAT_ARRAY_TYPE",
- 143: "EXTERNAL_PIXEL_ARRAY_TYPE",
- 145: "FILLER_TYPE",
- 146: "ACCESSOR_INFO_TYPE",
- 147: "ACCESS_CHECK_INFO_TYPE",
- 148: "INTERCEPTOR_INFO_TYPE",
- 149: "CALL_HANDLER_INFO_TYPE",
- 150: "FUNCTION_TEMPLATE_INFO_TYPE",
- 151: "OBJECT_TEMPLATE_INFO_TYPE",
- 152: "SIGNATURE_INFO_TYPE",
- 153: "TYPE_SWITCH_INFO_TYPE",
- 154: "SCRIPT_TYPE",
- 155: "CODE_CACHE_TYPE",
- 156: "POLYMORPHIC_CODE_CACHE_TYPE",
- 159: "FIXED_ARRAY_TYPE",
- 160: "SHARED_FUNCTION_INFO_TYPE",
- 161: "JS_MESSAGE_OBJECT_TYPE",
- 162: "JS_VALUE_TYPE",
- 163: "JS_OBJECT_TYPE",
- 164: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
- 165: "JS_GLOBAL_OBJECT_TYPE",
- 166: "JS_BUILTINS_OBJECT_TYPE",
- 167: "JS_GLOBAL_PROXY_TYPE",
- 168: "JS_ARRAY_TYPE",
- 169: "JS_PROXY_TYPE",
- 170: "JS_WEAK_MAP_TYPE",
- 171: "JS_REGEXP_TYPE",
- 172: "JS_FUNCTION_TYPE",
- 173: "JS_FUNCTION_PROXY_TYPE",
- 157: "DEBUG_INFO_TYPE",
- 158: "BREAK_POINT_INFO_TYPE",
+ 135: "FREE_SPACE_TYPE",
+ 136: "EXTERNAL_BYTE_ARRAY_TYPE",
+ 137: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE",
+ 138: "EXTERNAL_SHORT_ARRAY_TYPE",
+ 139: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE",
+ 140: "EXTERNAL_INT_ARRAY_TYPE",
+ 141: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE",
+ 142: "EXTERNAL_FLOAT_ARRAY_TYPE",
+ 144: "EXTERNAL_PIXEL_ARRAY_TYPE",
+ 146: "FILLER_TYPE",
+ 147: "ACCESSOR_INFO_TYPE",
+ 148: "ACCESS_CHECK_INFO_TYPE",
+ 149: "INTERCEPTOR_INFO_TYPE",
+ 150: "CALL_HANDLER_INFO_TYPE",
+ 151: "FUNCTION_TEMPLATE_INFO_TYPE",
+ 152: "OBJECT_TEMPLATE_INFO_TYPE",
+ 153: "SIGNATURE_INFO_TYPE",
+ 154: "TYPE_SWITCH_INFO_TYPE",
+ 155: "SCRIPT_TYPE",
+ 156: "CODE_CACHE_TYPE",
+ 157: "POLYMORPHIC_CODE_CACHE_TYPE",
+ 160: "FIXED_ARRAY_TYPE",
+ 145: "FIXED_DOUBLE_ARRAY_TYPE",
+ 161: "SHARED_FUNCTION_INFO_TYPE",
+ 162: "JS_MESSAGE_OBJECT_TYPE",
+ 165: "JS_VALUE_TYPE",
+ 166: "JS_OBJECT_TYPE",
+ 167: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
+ 168: "JS_GLOBAL_OBJECT_TYPE",
+ 169: "JS_BUILTINS_OBJECT_TYPE",
+ 170: "JS_GLOBAL_PROXY_TYPE",
+ 171: "JS_ARRAY_TYPE",
+ 164: "JS_PROXY_TYPE",
+ 174: "JS_WEAK_MAP_TYPE",
+ 175: "JS_REGEXP_TYPE",
+ 176: "JS_FUNCTION_TYPE",
+ 163: "JS_FUNCTION_PROXY_TYPE",
+ 158: "DEBUG_INFO_TYPE",
+ 159: "BREAK_POINT_INFO_TYPE",
}
@@ -652,7 +661,7 @@ class HeapObject(object):
class Map(HeapObject):
- def InstanceTypeOffset():
+ def InstanceTypeOffset(self):
return self.heap.PointerSize() + self.heap.IntSize()
def __init__(self, heap, map, address):
@@ -886,7 +895,7 @@ class Code(HeapObject):
def HeaderSize(heap):
return (heap.PointerSize() + heap.IntSize() + \
4 * heap.PointerSize() + 3 * heap.IntSize() + \
- CODE_ALIGNMENT_MASK) & ~CODE_ALIGNMENT_MASK
+ Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -916,6 +925,9 @@ class V8Heap(object):
"EXTERNAL_SYMBOL_TYPE": ExternalString,
"EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString,
"EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString,
+ "SHORT_EXTERNAL_SYMBOL_TYPE": ExternalString,
+ "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString,
+ "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString,
"STRING_TYPE": SeqString,
"ASCII_STRING_TYPE": SeqString,
"CONS_STRING_TYPE": ConsString,
@@ -945,7 +957,7 @@ class V8Heap(object):
def FindObject(self, tagged_address):
if tagged_address in self.objects:
return self.objects[tagged_address]
- if (tagged_address & 1) != 1: return None
+ if (tagged_address & self.ObjectAlignmentMask()) != 1: return None
address = tagged_address - 1
if not self.reader.IsValidAddress(address): return None
map_tagged_address = self.reader.ReadUIntPtr(address)
@@ -957,7 +969,7 @@ class V8Heap(object):
meta_map.map = meta_map
object = meta_map
else:
- map = self.FindObject(map_tagged_address)
+ map = self.FindMap(map_tagged_address)
if map is None: return None
instance_type_name = INSTANCE_TYPES.get(map.instance_type)
if instance_type_name is None: return None
@@ -966,9 +978,27 @@ class V8Heap(object):
self.objects[tagged_address] = object
return object
+ def FindMap(self, tagged_address):
+ if (tagged_address & self.MapAlignmentMask()) != 1: return None
+ address = tagged_address - 1
+ if not self.reader.IsValidAddress(address): return None
+ object = Map(self, None, address)
+ return object
+
+ def IntSize(self):
+ return 4
+
def PointerSize(self):
return self.reader.PointerSize()
+ def ObjectAlignmentMask(self):
+ return self.PointerSize() - 1
+
+ def MapAlignmentMask(self):
+ if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64:
+ return (1 << 4) - 1
+ elif self.reader.arch == MD_CPU_ARCHITECTURE_X86:
+ return (1 << 5) - 1
EIP_PROXIMITY = 64
diff --git a/deps/v8/tools/gyp/v8.gyp b/deps/v8/tools/gyp/v8.gyp
index 66a26b5ed53..57e2cbdf83c 100644
--- a/deps/v8/tools/gyp/v8.gyp
+++ b/deps/v8/tools/gyp/v8.gyp
@@ -1,4 +1,4 @@
-# Copyright 2011 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
@@ -684,6 +684,17 @@
],
}
],
+ ['OS=="netbsd"', {
+ 'link_settings': {
+ 'libraries': [
+ '-L/usr/pkg/lib -Wl,-R/usr/pkg/lib -lexecinfo',
+ ]},
+ 'sources': [
+ '../../src/platform-openbsd.cc',
+ '../../src/platform-posix.cc'
+ ],
+ }
+ ],
['OS=="solaris"', {
'sources': [
'../../src/platform-solaris.cc',