summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2015-01-17 23:02:56 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2015-01-18 13:05:00 +0100
commit5e7ebc7af6d08d4e31cf66f4ae22d29c688ef814 (patch)
tree337fbefdc52c893da4b6957309d6e2846576c403 /deps
parentea7750bddd8051f39fa538905e05f9bf1d1afa5f (diff)
downloadnode-new-5e7ebc7af6d08d4e31cf66f4ae22d29c688ef814.tar.gz
deps: upgrade v8 to 4.1.0.7
This commit upgrades V8 from 3.31.74.1 to 4.1.0.7. Despite the major version bump, there are no API or ABI changes, it's a bug fix release only. PR-URL: https://github.com/iojs/io.js/pull/490 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Fedor Indutny <fedor@indutny.com> Reviewed-By: Kenan Sulayman <kenan@sly.mn> Reviewed-By: Rod Vagg <rod@vagg.org>
Diffstat (limited to 'deps')
-rw-r--r--deps/v8/ChangeLog31
-rw-r--r--deps/v8/DEPS2
-rw-r--r--deps/v8/build/features.gypi2
-rw-r--r--deps/v8/src/api.cc1
-rw-r--r--deps/v8/src/base/platform/platform-freebsd.cc2
-rw-r--r--deps/v8/src/base/platform/platform-posix.cc2
-rw-r--r--deps/v8/src/compiler/control-reducer.cc24
-rw-r--r--deps/v8/src/compiler/js-typed-lowering.cc192
-rw-r--r--deps/v8/src/compiler/js-typed-lowering.h3
-rw-r--r--deps/v8/src/compiler/opcodes.h1
-rw-r--r--deps/v8/src/compiler/pipeline.cc2
-rw-r--r--deps/v8/src/compiler/simplified-lowering.cc41
-rw-r--r--deps/v8/src/compiler/simplified-lowering.h6
-rw-r--r--deps/v8/src/compiler/simplified-operator-reducer.cc40
-rw-r--r--deps/v8/src/compiler/simplified-operator-reducer.h4
-rw-r--r--deps/v8/src/compiler/simplified-operator.cc1
-rw-r--r--deps/v8/src/compiler/simplified-operator.h2
-rw-r--r--deps/v8/src/compiler/typer.cc49
-rw-r--r--deps/v8/src/compiler/verifier.cc4
-rw-r--r--deps/v8/src/d8.cc2
-rw-r--r--deps/v8/src/debug.cc2
-rw-r--r--deps/v8/src/deoptimizer.cc15
-rw-r--r--deps/v8/src/flag-definitions.h11
-rw-r--r--deps/v8/src/heap/heap.cc2
-rw-r--r--deps/v8/src/heap/heap.h2
-rw-r--r--deps/v8/src/heap/incremental-marking.cc2
-rw-r--r--deps/v8/src/heap/spaces.cc3
-rw-r--r--deps/v8/src/ia32/assembler-ia32.cc33
-rw-r--r--deps/v8/src/parser.h3
-rw-r--r--deps/v8/src/preparser.h2
-rw-r--r--deps/v8/src/runtime.js2
-rw-r--r--deps/v8/src/unique.h2
-rw-r--r--deps/v8/src/version.cc8
-rw-r--r--deps/v8/src/x64/assembler-x64.cc33
-rw-r--r--deps/v8/test/cctest/compiler/test-js-typed-lowering.cc43
-rw-r--r--deps/v8/test/cctest/compiler/test-simplified-lowering.cc58
-rw-r--r--deps/v8/test/cctest/test-alloc.cc3
-rw-r--r--deps/v8/test/cctest/test-api.cc42
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-445876.js12
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-446156.js11
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-446778.js17
-rw-r--r--deps/v8/test/mjsunit/compiler/regress-ntl-effect.js16
-rw-r--r--deps/v8/test/mjsunit/regress/regress-447756.js48
-rw-r--r--deps/v8/test/unittests/compiler/change-lowering-unittest.cc4
-rw-r--r--deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc9
-rw-r--r--deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc327
-rw-r--r--deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc16
-rw-r--r--deps/v8/test/unittests/compiler/node-test-utils.cc1
-rw-r--r--deps/v8/test/unittests/compiler/node-test-utils.h1
-rw-r--r--deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc67
-rw-r--r--deps/v8/test/unittests/compiler/simplified-operator-unittest.cc1
-rw-r--r--deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt2
-rw-r--r--deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js2
-rw-r--r--deps/v8/testing/gmock-support.h38
-rwxr-xr-xdeps/v8/tools/push-to-trunk/generate_version.py78
-rwxr-xr-xdeps/v8/tools/run_perf.py19
-rw-r--r--deps/v8/tools/whitespace.txt2
57 files changed, 962 insertions, 386 deletions
diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog
index d016b794ff..d42a2f1564 100644
--- a/deps/v8/ChangeLog
+++ b/deps/v8/ChangeLog
@@ -1,3 +1,34 @@
+2015-01-07: Version 3.32.3
+
+ Performance and stability improvements on all platforms.
+
+
+2015-01-07: Version 3.32.2
+
+ Performance and stability improvements on all platforms.
+
+
+2015-01-07: Version 3.32.1
+
+ [turbofan] Don't crash when typing load from a Uint8ClampedArray
+ (Chromium issue 446156).
+
+ [turbofan] Truncation of Bit/Word8/16 to Word32 is a no-op (Chromium
+ issue 445859).
+
+ [x64] Rearrange code for OOB integer loads (Chromium issue 445858).
+
+ Fix %NeverOptimizeFunction() intrinsic (Chromium issue 445732).
+
+ [turbofan] Fix invalid bounds check with overflowing offset (Chromium
+ issue 445267).
+
+ [turbofan] Raise max virtual registers and call parameter limit (issue
+ 3786).
+
+ Performance and stability improvements on all platforms.
+
+
2014-12-23: Version 3.31.74
[turbofan] Turn DCHECK for fixed slot index into a CHECK (Chromium issue
diff --git a/deps/v8/DEPS b/deps/v8/DEPS
index e85604b0b7..a81c7ecc38 100644
--- a/deps/v8/DEPS
+++ b/deps/v8/DEPS
@@ -18,7 +18,7 @@ deps = {
"v8/testing/gmock":
Var("git_url") + "/external/googlemock.git" + "@" + "29763965ab52f24565299976b936d1265cb6a271", # from svn revision 501
"v8/tools/clang":
- Var("git_url") + "/chromium/src/tools/clang.git" + "@" + "90fb65e7a9a5c9d6d9613dfb0e78921c52ca9cfc",
+ Var("git_url") + "/chromium/src/tools/clang.git" + "@" + "c945be21f6485fa177b43814f910b76cce921653",
}
deps_os = {
diff --git a/deps/v8/build/features.gypi b/deps/v8/build/features.gypi
index 25041ce42f..465eba9148 100644
--- a/deps/v8/build/features.gypi
+++ b/deps/v8/build/features.gypi
@@ -117,7 +117,7 @@
'Release': {
'variables': {
'v8_enable_extra_checks%': 0,
- 'v8_enable_handle_zapping%': 1,
+ 'v8_enable_handle_zapping%': 0,
},
'conditions': [
['v8_enable_extra_checks==1', {
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 61e565f97b..88d3c889b9 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -1780,6 +1780,7 @@ Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
// Do the parsing tasks which need to be done on the main thread. This will
// also handle parse errors.
source->parser->Internalize();
+ source->parser->HandleSourceURLComments();
i::Handle<i::SharedFunctionInfo> result =
i::Handle<i::SharedFunctionInfo>::null();
diff --git a/deps/v8/src/base/platform/platform-freebsd.cc b/deps/v8/src/base/platform/platform-freebsd.cc
index 58316f8bc1..507b946f69 100644
--- a/deps/v8/src/base/platform/platform-freebsd.cc
+++ b/deps/v8/src/base/platform/platform-freebsd.cc
@@ -141,7 +141,7 @@ std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
if (bytes_read < 8) break;
unsigned end = StringToLong(addr_buffer);
char buffer[MAP_LENGTH];
- bytes_read = -1;
+ int bytes_read = -1;
do {
bytes_read++;
if (bytes_read >= MAP_LENGTH - 1)
diff --git a/deps/v8/src/base/platform/platform-posix.cc b/deps/v8/src/base/platform/platform-posix.cc
index 64aed2b8d1..c2fa26a9ea 100644
--- a/deps/v8/src/base/platform/platform-posix.cc
+++ b/deps/v8/src/base/platform/platform-posix.cc
@@ -261,7 +261,7 @@ int OS::GetCurrentThreadId() {
#elif V8_OS_ANDROID
return static_cast<int>(gettid());
#else
- return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self()));
+ return static_cast<int>(pthread_self());
#endif
}
diff --git a/deps/v8/src/compiler/control-reducer.cc b/deps/v8/src/compiler/control-reducer.cc
index e738ccf24e..eef8a49fb1 100644
--- a/deps/v8/src/compiler/control-reducer.cc
+++ b/deps/v8/src/compiler/control-reducer.cc
@@ -196,6 +196,9 @@ class ControlReducerImpl {
merge = graph()->NewNode(common_->Merge(2), merge, loop);
end->ReplaceInput(0, merge);
to_add = merge;
+ // Mark the node as visited so that we can revisit later.
+ EnsureStateSize(merge->id());
+ state_[merge->id()] = kVisited;
} else {
// Append a new input to the final merge at the end.
merge->AppendInput(graph()->zone(), loop);
@@ -293,14 +296,17 @@ class ControlReducerImpl {
if (replacement != node) Recurse(replacement);
}
+ void EnsureStateSize(size_t id) {
+ if (id >= state_.size()) {
+ state_.resize((3 * id) / 2, kUnvisited);
+ }
+ }
+
// Push a node onto the stack if its state is {kUnvisited} or {kRevisit}.
bool Recurse(Node* node) {
size_t id = static_cast<size_t>(node->id());
- if (id < state_.size()) {
- if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
- } else {
- state_.resize((3 * id) / 2, kUnvisited);
- }
+ EnsureStateSize(id);
+ if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
Push(node);
return true;
}
@@ -403,6 +409,14 @@ class ControlReducerImpl {
if (n <= 1) return dead(); // No non-control inputs.
if (n == 2) return node->InputAt(0); // Only one non-control input.
+ // Never remove an effect phi from a (potentially non-terminating) loop.
+ // Otherwise, we might end up eliminating effect nodes, such as calls,
+ // before the loop.
+ if (node->opcode() == IrOpcode::kEffectPhi &&
+ NodeProperties::GetControlInput(node)->opcode() == IrOpcode::kLoop) {
+ return node;
+ }
+
Node* replacement = NULL;
Node::Inputs inputs = node->inputs();
for (InputIter it = inputs.begin(); n > 1; --n, ++it) {
diff --git a/deps/v8/src/compiler/js-typed-lowering.cc b/deps/v8/src/compiler/js-typed-lowering.cc
index 2338866d6d..761837576b 100644
--- a/deps/v8/src/compiler/js-typed-lowering.cc
+++ b/deps/v8/src/compiler/js-typed-lowering.cc
@@ -490,124 +490,34 @@ Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
}
-Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) {
- if (input->opcode() == IrOpcode::kJSToBoolean) {
- // Recursively try to reduce the input first.
- Reduction result = ReduceJSToBoolean(input);
- if (result.Changed()) return result;
- return Changed(input); // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x)
- }
- // Check if we have a cached conversion.
- Node* conversion = FindConversion<IrOpcode::kJSToBoolean>(input);
- if (conversion) return Replace(conversion);
+Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
+ Node* input = node->InputAt(0);
Type* input_type = NodeProperties::GetBounds(input).upper;
if (input_type->Is(Type::Boolean())) {
- return Changed(input); // JSToBoolean(x:boolean) => x
- }
- if (input_type->Is(Type::Undefined())) {
- // JSToBoolean(undefined) => #false
- return Replace(jsgraph()->FalseConstant());
- }
- if (input_type->Is(Type::Null())) {
- // JSToBoolean(null) => #false
- return Replace(jsgraph()->FalseConstant());
- }
- if (input_type->Is(Type::DetectableReceiver())) {
- // JSToBoolean(x:detectable) => #true
- return Replace(jsgraph()->TrueConstant());
- }
- if (input_type->Is(Type::Undetectable())) {
- // JSToBoolean(x:undetectable) => #false
- return Replace(jsgraph()->FalseConstant());
- }
- if (input_type->Is(Type::OrderedNumber())) {
- // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
- Node* cmp = graph()->NewNode(simplified()->NumberEqual(), input,
- jsgraph()->ZeroConstant());
- Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp);
- return Replace(inv);
- }
- if (input_type->Is(Type::String())) {
- // JSToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
- FieldAccess access = AccessBuilder::ForStringLength();
- Node* length = graph()->NewNode(simplified()->LoadField(access), input,
- graph()->start(), graph()->start());
- Node* cmp = graph()->NewNode(simplified()->NumberEqual(), length,
- jsgraph()->ZeroConstant());
- Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp);
- return Replace(inv);
+ // JSUnaryNot(x:boolean,context) => BooleanNot(x)
+ node->set_op(simplified()->BooleanNot());
+ node->TrimInputCount(1);
+ return Changed(node);
}
- return NoChange();
+ // JSUnaryNot(x,context) => BooleanNot(AnyToBoolean(x))
+ node->set_op(simplified()->BooleanNot());
+ node->ReplaceInput(0, graph()->NewNode(simplified()->AnyToBoolean(), input));
+ node->TrimInputCount(1);
+ return Changed(node);
}
Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
- // Try to reduce the input first.
- Node* const input = node->InputAt(0);
- Reduction reduction = ReduceJSToBooleanInput(input);
- if (reduction.Changed()) return reduction;
- if (input->opcode() == IrOpcode::kPhi) {
- // JSToBoolean(phi(x1,...,xn,control),context)
- // => phi(JSToBoolean(x1,no-context),...,JSToBoolean(xn,no-context))
- int const input_count = input->InputCount() - 1;
- Node* const control = input->InputAt(input_count);
- DCHECK_LE(0, input_count);
- DCHECK(NodeProperties::IsControl(control));
- DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean()));
- DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean()));
- node->set_op(common()->Phi(kMachAnyTagged, input_count));
- for (int i = 0; i < input_count; ++i) {
- // We must be very careful not to introduce cycles when pushing
- // operations into phis. It is safe for {value}, since it appears
- // as input to the phi that we are replacing, but it's not safe
- // to simply reuse the context of the {node}. However, ToBoolean()
- // does not require a context anyways, so it's safe to discard it
- // here and pass the dummy context.
- Node* const value = ConvertToBoolean(input->InputAt(i));
- if (i < node->InputCount()) {
- node->ReplaceInput(i, value);
- } else {
- node->AppendInput(graph()->zone(), value);
- }
- }
- if (input_count < node->InputCount()) {
- node->ReplaceInput(input_count, control);
- } else {
- node->AppendInput(graph()->zone(), control);
- }
- node->TrimInputCount(input_count + 1);
- return Changed(node);
- }
- if (input->opcode() == IrOpcode::kSelect) {
- // JSToBoolean(select(c,x1,x2),context)
- // => select(c,JSToBoolean(x1,no-context),...,JSToBoolean(x2,no-context))
- int const input_count = input->InputCount();
- BranchHint const input_hint = SelectParametersOf(input->op()).hint();
- DCHECK_EQ(3, input_count);
- DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Boolean()));
- DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Boolean()));
- node->set_op(common()->Select(kMachAnyTagged, input_hint));
- node->InsertInput(graph()->zone(), 0, input->InputAt(0));
- for (int i = 1; i < input_count; ++i) {
- // We must be very careful not to introduce cycles when pushing
- // operations into selects. It is safe for {value}, since it appears
- // as input to the select that we are replacing, but it's not safe
- // to simply reuse the context of the {node}. However, ToBoolean()
- // does not require a context anyways, so it's safe to discard it
- // here and pass the dummy context.
- Node* const value = ConvertToBoolean(input->InputAt(i));
- node->ReplaceInput(i, value);
- }
- DCHECK_EQ(3, node->InputCount());
- return Changed(node);
- }
- InsertConversion(node);
- if (node->InputAt(1) != jsgraph()->NoContextConstant()) {
- // JSToBoolean(x,context) => JSToBoolean(x,no-context)
- node->ReplaceInput(1, jsgraph()->NoContextConstant());
- return Changed(node);
+ Node* input = node->InputAt(0);
+ Type* input_type = NodeProperties::GetBounds(input).upper;
+ if (input_type->Is(Type::Boolean())) {
+ // JSToBoolean(x:boolean,context) => x
+ return Replace(input);
}
- return NoChange();
+ // JSToBoolean(x,context) => AnyToBoolean(x)
+ node->set_op(simplified()->AnyToBoolean());
+ node->TrimInputCount(1);
+ return Changed(node);
}
@@ -927,14 +837,36 @@ Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
Reduction JSTypedLowering::Reduce(Node* node) {
// Check if the output type is a singleton. In that case we already know the
- // result value and can simply replace the node unless there are effects.
+ // result value and can simply replace the node if it's eliminable.
if (NodeProperties::IsTyped(node) &&
- NodeProperties::GetBounds(node).upper->IsConstant() &&
!IrOpcode::IsLeafOpcode(node->opcode()) &&
- node->op()->EffectOutputCount() == 0) {
- return ReplaceEagerly(node, jsgraph()->Constant(
- NodeProperties::GetBounds(node).upper->AsConstant()->Value()));
- // TODO(neis): Extend this to Range(x,x), NaN, MinusZero, ...?
+ node->op()->HasProperty(Operator::kEliminatable)) {
+ Type* upper = NodeProperties::GetBounds(node).upper;
+ if (upper->IsConstant()) {
+ Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value());
+ NodeProperties::ReplaceWithValue(node, replacement);
+ return Changed(replacement);
+ } else if (upper->Is(Type::MinusZero())) {
+ Node* replacement = jsgraph()->Constant(factory()->minus_zero_value());
+ NodeProperties::ReplaceWithValue(node, replacement);
+ return Changed(replacement);
+ } else if (upper->Is(Type::NaN())) {
+ Node* replacement = jsgraph()->NaNConstant();
+ NodeProperties::ReplaceWithValue(node, replacement);
+ return Changed(replacement);
+ } else if (upper->Is(Type::Null())) {
+ Node* replacement = jsgraph()->NullConstant();
+ NodeProperties::ReplaceWithValue(node, replacement);
+ return Changed(replacement);
+ } else if (upper->Is(Type::PlainNumber()) && upper->Min() == upper->Max()) {
+ Node* replacement = jsgraph()->Constant(upper->Min());
+ NodeProperties::ReplaceWithValue(node, replacement);
+ return Changed(replacement);
+ } else if (upper->Is(Type::Undefined())) {
+ Node* replacement = jsgraph()->UndefinedConstant();
+ NodeProperties::ReplaceWithValue(node, replacement);
+ return Changed(replacement);
+ }
}
switch (node->opcode()) {
case IrOpcode::kJSEqual:
@@ -972,18 +904,8 @@ Reduction JSTypedLowering::Reduce(Node* node) {
return ReduceNumberBinop(node, simplified()->NumberDivide());
case IrOpcode::kJSModulus:
return ReduceNumberBinop(node, simplified()->NumberModulus());
- case IrOpcode::kJSUnaryNot: {
- Reduction result = ReduceJSToBooleanInput(node->InputAt(0));
- if (result.Changed()) {
- // JSUnaryNot(x:boolean) => BooleanNot(x)
- node = result.replacement();
- } else {
- // JSUnaryNot(x) => BooleanNot(JSToBoolean(x))
- node->set_op(javascript()->ToBoolean());
- }
- Node* value = graph()->NewNode(simplified()->BooleanNot(), node);
- return Replace(value);
- }
+ case IrOpcode::kJSUnaryNot:
+ return ReduceJSUnaryNot(node);
case IrOpcode::kJSToBoolean:
return ReduceJSToBoolean(node);
case IrOpcode::kJSToNumber:
@@ -1005,17 +927,6 @@ Reduction JSTypedLowering::Reduce(Node* node) {
}
-Node* JSTypedLowering::ConvertToBoolean(Node* input) {
- // Avoid inserting too many eager ToBoolean() operations.
- Reduction const reduction = ReduceJSToBooleanInput(input);
- if (reduction.Changed()) return reduction.replacement();
- Node* const conversion = graph()->NewNode(javascript()->ToBoolean(), input,
- jsgraph()->NoContextConstant());
- InsertConversion(conversion);
- return conversion;
-}
-
-
Node* JSTypedLowering::ConvertToNumber(Node* input) {
DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive()));
// Avoid inserting too many eager ToNumber() operations.
@@ -1043,8 +954,7 @@ Node* JSTypedLowering::FindConversion(Node* input) {
void JSTypedLowering::InsertConversion(Node* conversion) {
- DCHECK(conversion->opcode() == IrOpcode::kJSToBoolean ||
- conversion->opcode() == IrOpcode::kJSToNumber);
+ DCHECK(conversion->opcode() == IrOpcode::kJSToNumber);
size_t const input_id = conversion->InputAt(0)->id();
if (input_id >= conversions_.size()) {
conversions_.resize(2 * input_id + 1);
diff --git a/deps/v8/src/compiler/js-typed-lowering.h b/deps/v8/src/compiler/js-typed-lowering.h
index aa7510bb0e..838085e40c 100644
--- a/deps/v8/src/compiler/js-typed-lowering.h
+++ b/deps/v8/src/compiler/js-typed-lowering.h
@@ -41,7 +41,7 @@ class JSTypedLowering FINAL : public Reducer {
Reduction ReduceJSStoreContext(Node* node);
Reduction ReduceJSEqual(Node* node, bool invert);
Reduction ReduceJSStrictEqual(Node* node, bool invert);
- Reduction ReduceJSToBooleanInput(Node* input);
+ Reduction ReduceJSUnaryNot(Node* node);
Reduction ReduceJSToBoolean(Node* node);
Reduction ReduceJSToNumberInput(Node* input);
Reduction ReduceJSToNumber(Node* node);
@@ -52,7 +52,6 @@ class JSTypedLowering FINAL : public Reducer {
Reduction ReduceUI32Shift(Node* node, Signedness left_signedness,
const Operator* shift_op);
- Node* ConvertToBoolean(Node* input);
Node* ConvertToNumber(Node* input);
template <IrOpcode::Value>
Node* FindConversion(Node* input);
diff --git a/deps/v8/src/compiler/opcodes.h b/deps/v8/src/compiler/opcodes.h
index 3f00e6a178..d229b6da99 100644
--- a/deps/v8/src/compiler/opcodes.h
+++ b/deps/v8/src/compiler/opcodes.h
@@ -132,6 +132,7 @@
// Opcodes for VirtuaMachine-level operators.
#define SIMPLIFIED_OP_LIST(V) \
+ V(AnyToBoolean) \
V(BooleanNot) \
V(BooleanToNumber) \
V(NumberEqual) \
diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc
index 0e806238f1..c7432c6ea5 100644
--- a/deps/v8/src/compiler/pipeline.cc
+++ b/deps/v8/src/compiler/pipeline.cc
@@ -441,7 +441,7 @@ struct SimplifiedLoweringPhase {
void Run(PipelineData* data, Zone* temp_zone) {
SourcePositionTable::Scope pos(data->source_positions(),
SourcePosition::Unknown());
- SimplifiedLowering lowering(data->jsgraph());
+ SimplifiedLowering lowering(data->jsgraph(), temp_zone);
lowering.LowerAllNodes();
ValueNumberingReducer vn_reducer(temp_zone);
SimplifiedOperatorReducer simple_reducer(data->jsgraph());
diff --git a/deps/v8/src/compiler/simplified-lowering.cc b/deps/v8/src/compiler/simplified-lowering.cc
index bb5761469d..1461709dab 100644
--- a/deps/v8/src/compiler/simplified-lowering.cc
+++ b/deps/v8/src/compiler/simplified-lowering.cc
@@ -77,6 +77,9 @@ class RepresentationSelector {
memset(info_, 0, sizeof(NodeInfo) * count_);
Factory* f = zone->isolate()->factory();
+ safe_bit_range_ =
+ Type::Union(Type::Boolean(),
+ Type::Range(f->NewNumber(0), f->NewNumber(1), zone), zone);
safe_int_additive_range_ =
Type::Range(f->NewNumber(-std::pow(2.0, 52.0)),
f->NewNumber(std::pow(2.0, 52.0)), zone);
@@ -304,8 +307,8 @@ class RepresentationSelector {
if ((use & kRepMask) == kRepTagged) {
// only tagged uses.
return kRepTagged;
- } else if (IsSafeIntAdditiveOperand(node)) {
- // Integer within [-2^52, 2^52] range.
+ } else if (upper->Is(Type::Integral32())) {
+ // Integer within [-2^31, 2^32[ range.
if ((use & kRepMask) == kRepFloat64) {
// only float64 uses.
return kRepFloat64;
@@ -315,12 +318,12 @@ class RepresentationSelector {
} else if ((use & kRepMask) == kRepWord32 ||
(use & kTypeMask) == kTypeInt32 ||
(use & kTypeMask) == kTypeUint32) {
- // The type is a safe integer, but we only use 32 bits.
+ // We only use 32 bits or we use the result consistently.
return kRepWord32;
} else {
return kRepFloat64;
}
- } else if (upper->Is(Type::Boolean())) {
+ } else if (IsSafeBitOperand(node)) {
// multiple uses => pick kRepBit.
return kRepBit;
} else if (upper->Is(Type::Number())) {
@@ -414,6 +417,11 @@ class RepresentationSelector {
return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use);
}
+ bool IsSafeBitOperand(Node* node) {
+ Type* type = NodeProperties::GetBounds(node).upper;
+ return type->Is(safe_bit_range_);
+ }
+
bool IsSafeIntAdditiveOperand(Node* node) {
Type* type = NodeProperties::GetBounds(node).upper;
// TODO(jarin): Unfortunately, bitset types are not subtypes of larger
@@ -521,6 +529,28 @@ class RepresentationSelector {
//------------------------------------------------------------------
// Simplified operators.
//------------------------------------------------------------------
+ case IrOpcode::kAnyToBoolean: {
+ if (IsSafeBitOperand(node->InputAt(0))) {
+ VisitUnop(node, kRepBit, kRepBit);
+ if (lower()) DeferReplacement(node, node->InputAt(0));
+ } else {
+ VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged);
+ if (lower()) {
+ // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context)
+ Operator::Properties properties = node->op()->properties();
+ Callable callable = CodeFactory::ToBoolean(
+ jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
+ CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite;
+ CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+ callable.descriptor(), 0, flags, properties, jsgraph_->zone());
+ node->set_op(jsgraph_->common()->Call(desc));
+ node->InsertInput(jsgraph_->zone(), 0,
+ jsgraph_->HeapConstant(callable.code()));
+ node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
+ }
+ }
+ break;
+ }
case IrOpcode::kBooleanNot: {
if (lower()) {
MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
@@ -1034,6 +1064,7 @@ class RepresentationSelector {
Phase phase_; // current phase of algorithm
RepresentationChanger* changer_; // for inserting representation changes
ZoneQueue<Node*> queue_; // queue for traversing the graph
+ Type* safe_bit_range_;
Type* safe_int_additive_range_;
NodeInfo* GetInfo(Node* node) {
@@ -1058,7 +1089,7 @@ void SimplifiedLowering::LowerAllNodes() {
SimplifiedOperatorBuilder simplified(graph()->zone());
RepresentationChanger changer(jsgraph(), &simplified,
graph()->zone()->isolate());
- RepresentationSelector selector(jsgraph(), zone(), &changer);
+ RepresentationSelector selector(jsgraph(), zone_, &changer);
selector.Run(this);
}
diff --git a/deps/v8/src/compiler/simplified-lowering.h b/deps/v8/src/compiler/simplified-lowering.h
index 852ac7eaa0..b21cf21ffd 100644
--- a/deps/v8/src/compiler/simplified-lowering.h
+++ b/deps/v8/src/compiler/simplified-lowering.h
@@ -20,7 +20,8 @@ class RepresentationChanger;
class SimplifiedLowering FINAL {
public:
- explicit SimplifiedLowering(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
+ SimplifiedLowering(JSGraph* jsgraph, Zone* zone)
+ : jsgraph_(jsgraph), zone_(zone) {}
~SimplifiedLowering() {}
void LowerAllNodes();
@@ -41,7 +42,8 @@ class SimplifiedLowering FINAL {
void DoStringLessThanOrEqual(Node* node);
private:
- JSGraph* jsgraph_;
+ JSGraph* const jsgraph_;
+ Zone* const zone_;
Node* SmiTag(Node* node);
Node* IsTagged(Node* node);
diff --git a/deps/v8/src/compiler/simplified-operator-reducer.cc b/deps/v8/src/compiler/simplified-operator-reducer.cc
index 0868cab3fc..9d45e5b192 100644
--- a/deps/v8/src/compiler/simplified-operator-reducer.cc
+++ b/deps/v8/src/compiler/simplified-operator-reducer.cc
@@ -2,10 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/compiler/simplified-operator-reducer.h"
+
+#include "src/compiler/access-builder.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-matchers.h"
-#include "src/compiler/simplified-operator-reducer.h"
+#include "src/compiler/node-properties-inl.h"
namespace v8 {
namespace internal {
@@ -20,6 +23,8 @@ SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
switch (node->opcode()) {
+ case IrOpcode::kAnyToBoolean:
+ return ReduceAnyToBoolean(node);
case IrOpcode::kBooleanNot: {
HeapObjectMatcher<HeapObject> m(node->InputAt(0));
if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) {
@@ -105,8 +110,36 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
}
+Reduction SimplifiedOperatorReducer::ReduceAnyToBoolean(Node* node) {
+ Node* const input = NodeProperties::GetValueInput(node, 0);
+ Type* const input_type = NodeProperties::GetBounds(input).upper;
+ if (input_type->Is(Type::Boolean())) {
+ // AnyToBoolean(x:boolean) => x
+ return Replace(input);
+ }
+ if (input_type->Is(Type::OrderedNumber())) {
+ // AnyToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
+ Node* compare = graph()->NewNode(simplified()->NumberEqual(), input,
+ jsgraph()->ZeroConstant());
+ return Change(node, simplified()->BooleanNot(), compare);
+ }
+ if (input_type->Is(Type::String())) {
+ // AnyToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
+ FieldAccess const access = AccessBuilder::ForStringLength();
+ Node* length = graph()->NewNode(simplified()->LoadField(access), input,
+ graph()->start(), graph()->start());
+ Node* compare = graph()->NewNode(simplified()->NumberEqual(), length,
+ jsgraph()->ZeroConstant());
+ return Change(node, simplified()->BooleanNot(), compare);
+ }
+ return NoChange();
+}
+
+
Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
Node* a) {
+ DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
+ DCHECK_LE(1, node->InputCount());
node->set_op(op);
node->ReplaceInput(0, a);
return Changed(node);
@@ -141,6 +174,11 @@ Factory* SimplifiedOperatorReducer::factory() const {
}
+CommonOperatorBuilder* SimplifiedOperatorReducer::common() const {
+ return jsgraph()->common();
+}
+
+
MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
return jsgraph()->machine();
}
diff --git a/deps/v8/src/compiler/simplified-operator-reducer.h b/deps/v8/src/compiler/simplified-operator-reducer.h
index 8f6c9aa807..1e565b8b13 100644
--- a/deps/v8/src/compiler/simplified-operator-reducer.h
+++ b/deps/v8/src/compiler/simplified-operator-reducer.h
@@ -17,6 +17,7 @@ class Heap;
namespace compiler {
// Forward declarations.
+class CommonOperatorBuilder;
class JSGraph;
class MachineOperatorBuilder;
@@ -28,6 +29,8 @@ class SimplifiedOperatorReducer FINAL : public Reducer {
Reduction Reduce(Node* node) FINAL;
private:
+ Reduction ReduceAnyToBoolean(Node* node);
+
Reduction Change(Node* node, const Operator* op, Node* a);
Reduction ReplaceFloat64(double value);
Reduction ReplaceInt32(int32_t value);
@@ -40,6 +43,7 @@ class SimplifiedOperatorReducer FINAL : public Reducer {
Graph* graph() const;
Factory* factory() const;
JSGraph* jsgraph() const { return jsgraph_; }
+ CommonOperatorBuilder* common() const;
MachineOperatorBuilder* machine() const;
SimplifiedOperatorBuilder* simplified() { return &simplified_; }
diff --git a/deps/v8/src/compiler/simplified-operator.cc b/deps/v8/src/compiler/simplified-operator.cc
index e082a4b30a..9d88d12301 100644
--- a/deps/v8/src/compiler/simplified-operator.cc
+++ b/deps/v8/src/compiler/simplified-operator.cc
@@ -158,6 +158,7 @@ const ElementAccess& ElementAccessOf(const Operator* op) {
#define PURE_OP_LIST(V) \
+ V(AnyToBoolean, Operator::kNoProperties, 1) \
V(BooleanNot, Operator::kNoProperties, 1) \
V(BooleanToNumber, Operator::kNoProperties, 1) \
V(NumberEqual, Operator::kCommutative, 2) \
diff --git a/deps/v8/src/compiler/simplified-operator.h b/deps/v8/src/compiler/simplified-operator.h
index 72608eee8c..22664fa8f7 100644
--- a/deps/v8/src/compiler/simplified-operator.h
+++ b/deps/v8/src/compiler/simplified-operator.h
@@ -128,6 +128,8 @@ class SimplifiedOperatorBuilder FINAL {
public:
explicit SimplifiedOperatorBuilder(Zone* zone);
+ const Operator* AnyToBoolean();
+
const Operator* BooleanNot();
const Operator* BooleanToNumber();
diff --git a/deps/v8/src/compiler/typer.cc b/deps/v8/src/compiler/typer.cc
index a170a71512..137829e92d 100644
--- a/deps/v8/src/compiler/typer.cc
+++ b/deps/v8/src/compiler/typer.cc
@@ -33,10 +33,11 @@ enum LazyCachedType {
kImulFunc,
kClz32Func,
kArrayBufferFunc,
-#define NATIVE_TYPE_CASE(Type) k##Type, k##Type##Array, k##Type##ArrayFunc,
- NATIVE_TYPES(NATIVE_TYPE_CASE)
-#undef NATIVE_TYPE_CASE
- kNumLazyCachedTypes
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ k##Type, k##Type##Array, k##Type##ArrayFunc,
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+ kNumLazyCachedTypes
};
@@ -75,6 +76,8 @@ class LazyTypeCache FINAL : public ZoneObject {
return CreateNative(Type::Number(), Type::UntaggedFloat32());
case kFloat64:
return CreateNative(Type::Number(), Type::UntaggedFloat64());
+ case kUint8Clamped:
+ return Get(kUint8);
case kNumberFunc0:
return Type::Function(Type::Number(), zone());
case kNumberFunc1:
@@ -89,13 +92,13 @@ class LazyTypeCache FINAL : public ZoneObject {
return Type::Function(CreateRange(0, 32), Type::Number(), zone());
case kArrayBufferFunc:
return Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
-#define NATIVE_TYPE_CASE(Type) \
- case k##Type##Array: \
- return CreateArray(Get(k##Type)); \
- case k##Type##ArrayFunc: \
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case k##Type##Array: \
+ return CreateArray(Get(k##Type)); \
+ case k##Type##ArrayFunc: \
return CreateArrayFunction(Get(k##Type##Array));
- NATIVE_TYPES(NATIVE_TYPE_CASE)
-#undef NATIVE_TYPE_CASE
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
case kNumLazyCachedTypes:
break;
}
@@ -1438,6 +1441,11 @@ Bounds Typer::Visitor::TypeJSDebugger(Node* node) {
// Simplified operators.
+Bounds Typer::Visitor::TypeAnyToBoolean(Node* node) {
+ return TypeUnaryOp(node, ToBoolean);
+}
+
+
Bounds Typer::Visitor::TypeBooleanNot(Node* node) {
return Bounds(Type::None(zone()), Type::Boolean(zone()));
}
@@ -1615,13 +1623,11 @@ Bounds Typer::Visitor::TypeLoadBuffer(Node* node) {
// TODO(bmeurer): This typing is not yet correct. Since we can still access
// out of bounds, the type in the general case has to include Undefined.
switch (BufferAccessOf(node->op()).external_array_type()) {
-#define NATIVE_TYPE_CASE(Type) \
- case kExternal##Type##Array: \
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case kExternal##Type##Array: \
return Bounds(typer_->cache_->Get(k##Type));
- NATIVE_TYPES(NATIVE_TYPE_CASE)
-#undef NATIVE_TYPE_CASE
- case kExternalUint8ClampedArray:
- break;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
}
UNREACHABLE();
return Bounds();
@@ -2088,14 +2094,11 @@ Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
}
} else if (value->IsJSTypedArray()) {
switch (JSTypedArray::cast(*value)->type()) {
-#define NATIVE_TYPE_CASE(Type) \
- case kExternal##Type##Array: \
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case kExternal##Type##Array: \
return typer_->cache_->Get(k##Type##Array);
- NATIVE_TYPES(NATIVE_TYPE_CASE)
-#undef NATIVE_TYPE_CASE
- case kExternalUint8ClampedArray:
- // TODO(rossberg): Do we want some ClampedArray type to express this?
- break;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
}
}
return Type::Constant(value, zone());
diff --git a/deps/v8/src/compiler/verifier.cc b/deps/v8/src/compiler/verifier.cc
index 84b060f92a..693b414650 100644
--- a/deps/v8/src/compiler/verifier.cc
+++ b/deps/v8/src/compiler/verifier.cc
@@ -482,6 +482,10 @@ void Verifier::Visitor::Pre(Node* node) {
// Simplified operators
// -------------------------------
+ case IrOpcode::kAnyToBoolean:
+ // Type is Boolean.
+ CheckUpperIs(node, Type::Boolean());
+ break;
case IrOpcode::kBooleanNot:
// Boolean -> Boolean
CheckValueInputIs(node, 0, Type::Boolean());
diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc
index 132891e2b8..7157cb81ac 100644
--- a/deps/v8/src/d8.cc
+++ b/deps/v8/src/d8.cc
@@ -1577,7 +1577,7 @@ class StartupDataHandler {
const char* last_slash = strrchr(exec_path, '/');
if (last_slash) {
int after_slash = last_slash - exec_path + 1;
- int name_length = strlen(name);
+ int name_length = static_cast<int>(strlen(name));
*buffer =
reinterpret_cast<char*>(calloc(after_slash + name_length + 1, 1));
strncpy(*buffer, exec_path, after_slash);
diff --git a/deps/v8/src/debug.cc b/deps/v8/src/debug.cc
index cdcb0a759f..93ef1cfc09 100644
--- a/deps/v8/src/debug.cc
+++ b/deps/v8/src/debug.cc
@@ -573,7 +573,7 @@ void Debug::ThreadInit() {
thread_local_.step_out_fp_ = 0;
// TODO(isolates): frames_are_dropped_?
base::NoBarrier_Store(&thread_local_.current_debug_scope_,
- static_cast<base::AtomicWord>(0));
+ static_cast<base::AtomicWord>(NULL));
thread_local_.restarter_frame_function_pointer_ = NULL;
}
diff --git a/deps/v8/src/deoptimizer.cc b/deps/v8/src/deoptimizer.cc
index 554ba8e7b1..748f95eff7 100644
--- a/deps/v8/src/deoptimizer.cc
+++ b/deps/v8/src/deoptimizer.cc
@@ -637,7 +637,7 @@ Code* Deoptimizer::FindOptimizedCode(JSFunction* function,
void Deoptimizer::PrintFunctionName() {
if (function_->IsJSFunction()) {
- function_->PrintName(trace_scope_->file());
+ function_->ShortPrint(trace_scope_->file());
} else {
PrintF(trace_scope_->file(),
"%s", Code::Kind2String(compiled_code_->kind()));
@@ -761,10 +761,8 @@ void Deoptimizer::DoComputeOutputFrames() {
if (trace_scope_ != NULL) {
timer.Start();
- PrintF(trace_scope_->file(),
- "[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ",
- MessageFor(bailout_type_),
- reinterpret_cast<intptr_t>(function_));
+ PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ",
+ MessageFor(bailout_type_));
PrintFunctionName();
PrintF(trace_scope_->file(),
" (opt #%d) @%d, FP to SP delta: %d]\n",
@@ -850,11 +848,8 @@ void Deoptimizer::DoComputeOutputFrames() {
if (trace_scope_ != NULL) {
double ms = timer.Elapsed().InMillisecondsF();
int index = output_count_ - 1; // Index of the topmost frame.
- JSFunction* function = output_[index]->GetFunction();
- PrintF(trace_scope_->file(),
- "[deoptimizing (%s): end 0x%08" V8PRIxPTR " ",
- MessageFor(bailout_type_),
- reinterpret_cast<intptr_t>(function));
+ PrintF(trace_scope_->file(), "[deoptimizing (%s): end ",
+ MessageFor(bailout_type_));
PrintFunctionName();
PrintF(trace_scope_->file(),
" @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h
index 6f36199347..348a52e73a 100644
--- a/deps/v8/src/flag-definitions.h
+++ b/deps/v8/src/flag-definitions.h
@@ -183,16 +183,17 @@ DEFINE_IMPLICATION(es_staging, harmony)
V(harmony_unicode, "harmony unicode escapes")
// Features that are complete (but still behind --harmony/es-staging flag).
-#define HARMONY_STAGED(V) V(harmony_tostring, "harmony toString")
+#define HARMONY_STAGED(V) \
+ V(harmony_tostring, "harmony toString") \
+ V(harmony_classes, \
+ "harmony classes (implies block scoping & object literal extension)") \
+ V(harmony_object_literals, "harmony object literal extensions")
// Features that are shipping (turned on by default, but internal flag remains).
#define HARMONY_SHIPPING(V) \
V(harmony_numeric_literals, "harmony numeric literals") \
V(harmony_strings, "harmony string methods") \
V(harmony_scoping, "harmony block scoping") \
- V(harmony_classes, \
- "harmony classes (implies block scoping & object literal extension)") \
- V(harmony_object_literals, "harmony object literal extensions") \
V(harmony_templates, "harmony template literals")
// Once a shipping feature has proved stable in the wild, it will be dropped
@@ -498,7 +499,7 @@ DEFINE_BOOL(trace_stub_failures, false,
"trace deoptimization of generated code stubs")
DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
-DEFINE_BOOL(serialize_inner, false, "enable caching of inner functions")
+DEFINE_BOOL(serialize_inner, true, "enable caching of inner functions")
DEFINE_BOOL(trace_serializer, false, "print code serializer trace")
// compiler.cc
diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc
index cf67dab2b4..0b817e4d6d 100644
--- a/deps/v8/src/heap/heap.cc
+++ b/deps/v8/src/heap/heap.cc
@@ -4611,7 +4611,7 @@ bool Heap::IdleNotification(double deadline_in_seconds) {
}
-bool Heap::RecentIdleNotifcationHappened() {
+bool Heap::RecentIdleNotificationHappened() {
return (last_idle_notification_time_ +
GCIdleTimeHandler::kMaxFrameRenderingIdleTime) >
MonotonicallyIncreasingTimeInMs();
diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h
index 30271313e9..e6ccf2eaec 100644
--- a/deps/v8/src/heap/heap.h
+++ b/deps/v8/src/heap/heap.h
@@ -1298,7 +1298,7 @@ class Heap {
int gc_count() const { return gc_count_; }
- bool RecentIdleNotifcationHappened();
+ bool RecentIdleNotificationHappened();
// Completely clear the Instanceof cache (to stop it keeping objects alive
// around a GC).
diff --git a/deps/v8/src/heap/incremental-marking.cc b/deps/v8/src/heap/incremental-marking.cc
index 33f9de0da4..aadd17c94b 100644
--- a/deps/v8/src/heap/incremental-marking.cc
+++ b/deps/v8/src/heap/incremental-marking.cc
@@ -891,7 +891,7 @@ intptr_t IncrementalMarking::Step(intptr_t allocated_bytes,
// If an idle notification happened recently, we delay marking steps.
if (marking == DO_NOT_FORCE_MARKING &&
- heap_->RecentIdleNotifcationHappened()) {
+ heap_->RecentIdleNotificationHappened()) {
return 0;
}
diff --git a/deps/v8/src/heap/spaces.cc b/deps/v8/src/heap/spaces.cc
index 37a123d91d..3802e470bd 100644
--- a/deps/v8/src/heap/spaces.cc
+++ b/deps/v8/src/heap/spaces.cc
@@ -140,7 +140,8 @@ bool CodeRange::SetUp(size_t requested) {
base += kReservedCodeRangePages * base::OS::CommitPageSize();
}
Address aligned_base = RoundUp(base, MemoryChunk::kAlignment);
- size_t size = code_range_->size() - (aligned_base - base);
+ size_t size = code_range_->size() - (aligned_base - base) -
+ kReservedCodeRangePages * base::OS::CommitPageSize();
allocation_list_.Add(FreeBlock(aligned_base, size));
current_allocation_block_index_ = 0;
diff --git a/deps/v8/src/ia32/assembler-ia32.cc b/deps/v8/src/ia32/assembler-ia32.cc
index 2805fa0f9a..168a196449 100644
--- a/deps/v8/src/ia32/assembler-ia32.cc
+++ b/deps/v8/src/ia32/assembler-ia32.cc
@@ -34,7 +34,11 @@
// significantly by Google Inc.
// Copyright 2012 the V8 project authors. All rights reserved.
-#include "src/v8.h"
+#include "src/ia32/assembler-ia32.h"
+
+#if V8_OS_MACOSX
+#include <sys/sysctl.h>
+#endif
#if V8_TARGET_ARCH_IA32
@@ -42,7 +46,7 @@
#include "src/base/cpu.h"
#include "src/disassembler.h"
#include "src/macro-assembler.h"
-#include "src/serialize.h"
+#include "src/v8.h"
namespace v8 {
namespace internal {
@@ -50,6 +54,29 @@ namespace internal {
// -----------------------------------------------------------------------------
// Implementation of CpuFeatures
+namespace {
+
+bool EnableAVX() {
+#if V8_OS_MACOSX
+ // Mac OS X 10.9 has a bug where AVX transitions were indeed being caused by
+ // ISRs, so we detect Mac OS X 10.9 here and disable AVX in that case.
+ char buffer[128];
+ size_t buffer_size = arraysize(buffer);
+ int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
+ if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
+ V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
+ }
+ // The buffer now contains a string of the form XX.YY.ZZ, where
+ // XX is the major kernel version component. 13.x.x (Mavericks) is
+ // affected by this bug, so disable AVX there.
+ if (memcmp(buffer, "13.", 3) == 0) return false;
+#endif // V8_OS_MACOSX
+ return FLAG_enable_avx;
+}
+
+} // namespace
+
+
void CpuFeatures::ProbeImpl(bool cross_compile) {
base::CPU cpu;
CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
@@ -60,7 +87,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
- if (cpu.has_avx() && FLAG_enable_avx) supported_ |= 1u << AVX;
+ if (cpu.has_avx() && EnableAVX()) supported_ |= 1u << AVX;
if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3;
}
diff --git a/deps/v8/src/parser.h b/deps/v8/src/parser.h
index 02dfe15f8e..219f1c4b21 100644
--- a/deps/v8/src/parser.h
+++ b/deps/v8/src/parser.h
@@ -682,6 +682,7 @@ class Parser : public ParserBase<ParserTraits> {
// Handle errors detected during parsing, move statistics to Isolate,
// internalize strings (move them to the heap).
void Internalize();
+ void HandleSourceURLComments();
private:
friend class ParserTraits;
@@ -879,8 +880,6 @@ class Parser : public ParserBase<ParserTraits> {
const AstRawString* function_name, int pos, Variable* fvar,
Token::Value fvar_init_op, bool is_generator, bool* ok);
- void HandleSourceURLComments();
-
void ThrowPendingError();
TemplateLiteralState OpenTemplateLiteral(int pos);
diff --git a/deps/v8/src/preparser.h b/deps/v8/src/preparser.h
index ad27744e9d..18004a5096 100644
--- a/deps/v8/src/preparser.h
+++ b/deps/v8/src/preparser.h
@@ -467,7 +467,7 @@ class ParserBase : public Traits {
void ReportMessageAt(Scanner::Location location, const char* message,
bool is_reference_error = false) {
Traits::ReportMessageAt(location, message,
- reinterpret_cast<const char*>(0),
+ reinterpret_cast<const char*>(NULL),
is_reference_error);
}
diff --git a/deps/v8/src/runtime.js b/deps/v8/src/runtime.js
index 79824e4e02..978429ea3b 100644
--- a/deps/v8/src/runtime.js
+++ b/deps/v8/src/runtime.js
@@ -672,7 +672,7 @@ function DefaultString(x) {
}
function ToPositiveInteger(x, rangeErrorName) {
- var i = TO_INTEGER(x);
+ var i = TO_INTEGER_MAP_MINUS_ZERO(x);
if (i < 0) throw MakeRangeError(rangeErrorName);
return i;
}
diff --git a/deps/v8/src/unique.h b/deps/v8/src/unique.h
index 321eb3683d..9232f85970 100644
--- a/deps/v8/src/unique.h
+++ b/deps/v8/src/unique.h
@@ -117,7 +117,7 @@ class Unique {
// TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
static Unique<T> CreateUninitialized(Handle<T> handle) {
- return Unique<T>(NULL, handle);
+ return Unique<T>(reinterpret_cast<Address>(NULL), handle);
}
static Unique<T> CreateImmovable(Handle<T> handle) {
diff --git a/deps/v8/src/version.cc b/deps/v8/src/version.cc
index e84633da5f..c71ecff342 100644
--- a/deps/v8/src/version.cc
+++ b/deps/v8/src/version.cc
@@ -32,10 +32,10 @@
// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
-#define MAJOR_VERSION 3
-#define MINOR_VERSION 31
-#define BUILD_NUMBER 74
-#define PATCH_LEVEL 1
+#define MAJOR_VERSION 4
+#define MINOR_VERSION 1
+#define BUILD_NUMBER 0
+#define PATCH_LEVEL 7
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/deps/v8/src/x64/assembler-x64.cc b/deps/v8/src/x64/assembler-x64.cc
index 469ebe9888..fd722b23bd 100644
--- a/deps/v8/src/x64/assembler-x64.cc
+++ b/deps/v8/src/x64/assembler-x64.cc
@@ -2,13 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/v8.h"
+#include "src/x64/assembler-x64.h"
+
+#if V8_OS_MACOSX
+#include <sys/sysctl.h>
+#endif
#if V8_TARGET_ARCH_X64
#include "src/base/bits.h"
#include "src/macro-assembler.h"
-#include "src/serialize.h"
+#include "src/v8.h"
namespace v8 {
namespace internal {
@@ -16,6 +20,29 @@ namespace internal {
// -----------------------------------------------------------------------------
// Implementation of CpuFeatures
+namespace {
+
+bool EnableAVX() {
+#if V8_OS_MACOSX
+ // Mac OS X 10.9 has a bug where AVX transitions were indeed being caused by
+ // ISRs, so we detect Mac OS X 10.9 here and disable AVX in that case.
+ char buffer[128];
+ size_t buffer_size = arraysize(buffer);
+ int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
+ if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
+ V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
+ }
+ // The buffer now contains a string of the form XX.YY.ZZ, where
+ // XX is the major kernel version component. 13.x.x (Mavericks) is
+ // affected by this bug, so disable AVX there.
+ if (memcmp(buffer, "13.", 3) == 0) return false;
+#endif // V8_OS_MACOSX
+ return FLAG_enable_avx;
+}
+
+} // namespace
+
+
void CpuFeatures::ProbeImpl(bool cross_compile) {
base::CPU cpu;
CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
@@ -28,7 +55,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
// SAHF is not generally available in long mode.
if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF;
- if (cpu.has_avx() && FLAG_enable_avx) supported_ |= 1u << AVX;
+ if (cpu.has_avx() && EnableAVX()) supported_ |= 1u << AVX;
if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3;
}
diff --git a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
index 70b1312cc1..3023837f4c 100644
--- a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
@@ -507,24 +507,6 @@ TEST(JSToBoolean) {
CHECK_EQ(IrOpcode::kParameter, r->opcode());
}
- { // ToBoolean(ordered-number)
- Node* r = R.ReduceUnop(op, Type::OrderedNumber());
- CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
- Node* i = r->InputAt(0);
- CHECK_EQ(IrOpcode::kNumberEqual, i->opcode());
- // ToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
- }
-
- { // ToBoolean(string)
- Node* r = R.ReduceUnop(op, Type::String());
- CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
- Node* i = r->InputAt(0);
- CHECK_EQ(IrOpcode::kNumberEqual, i->opcode());
- Node* j = i->InputAt(0);
- CHECK_EQ(IrOpcode::kLoadField, j->opcode());
- // ToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
- }
-
{ // ToBoolean(object)
Node* r = R.ReduceUnop(op, Type::DetectableObject());
R.CheckTrue(r);
@@ -537,30 +519,7 @@ TEST(JSToBoolean) {
{ // ToBoolean(object)
Node* r = R.ReduceUnop(op, Type::Object());
- CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
- }
-}
-
-
-TEST(JSToBoolean_replacement) {
- JSTypedLoweringTester R;
-
- Type* types[] = {Type::Null(), Type::Undefined(),
- Type::Boolean(), Type::OrderedNumber(),
- Type::DetectableObject(), Type::Undetectable()};
-
- for (size_t i = 0; i < arraysize(types); i++) {
- Node* n = R.Parameter(types[i]);
- Node* c = R.graph.NewNode(R.javascript.ToBoolean(), n, R.context());
- Node* r = R.reduce(c);
-
- if (types[i]->Is(Type::Boolean())) {
- CHECK_EQ(n, r);
- } else if (types[i]->Is(Type::OrderedNumber())) {
- CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
- } else {
- CHECK_EQ(IrOpcode::kHeapConstant, r->opcode());
- }
+ CHECK_EQ(IrOpcode::kAnyToBoolean, r->opcode());
}
}
diff --git a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
index d463997691..147aa323ff 100644
--- a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
@@ -39,7 +39,7 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
typer(this->graph(), MaybeHandle<Context>()),
javascript(this->zone()),
jsgraph(this->graph(), this->common(), &javascript, this->machine()),
- lowering(&jsgraph) {}
+ lowering(&jsgraph, this->zone()) {}
Typer typer;
JSOperatorBuilder javascript;
@@ -698,9 +698,7 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
CHECK_EQ(expected, node->opcode());
}
- void Lower() {
- SimplifiedLowering(&jsgraph).LowerAllNodes();
- }
+ void Lower() { SimplifiedLowering(&jsgraph, jsgraph.zone()).LowerAllNodes(); }
// Inserts the node as the return value of the graph.
Node* Return(Node* node) {
@@ -789,6 +787,50 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
};
+TEST(LowerAnyToBoolean_bit_bit) {
+ // AnyToBoolean(x: kRepBit) used as kRepBit
+ HandleAndZoneScope scope;
+ Factory* f = scope.main_zone()->isolate()->factory();
+ Handle<Object> zero = f->NewNumber(0);
+ Handle<Object> one = f->NewNumber(1);
+ Type* singleton_zero = Type::Constant(zero, scope.main_zone());
+ Type* singleton_one = Type::Constant(one, scope.main_zone());
+ Type* zero_one_range = Type::Range(zero, one, scope.main_zone());
+ static Type* kTypes[] = {
+ singleton_zero, singleton_one, zero_one_range, Type::Boolean(),
+ Type::Union(Type::Boolean(), singleton_zero, scope.main_zone()),
+ Type::Union(Type::Boolean(), singleton_one, scope.main_zone()),
+ Type::Union(Type::Boolean(), zero_one_range, scope.main_zone())};
+ for (Type* type : kTypes) {
+ TestingGraph t(type);
+ Node* x = t.ExampleWithTypeAndRep(type, kRepBit);
+ Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
+ Node* use = t.Branch(cnv);
+ t.Lower();
+ CHECK_EQ(x, use->InputAt(0));
+ }
+}
+
+
+#if V8_TURBOFAN_TARGET
+
+TEST(LowerAnyToBoolean_tagged_tagged) {
+ // AnyToBoolean(x: kRepTagged) used as kRepTagged
+ TestingGraph t(Type::Any());
+ Node* x = t.p0;
+ Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
+ Node* use = t.Use(cnv, kRepTagged);
+ t.Return(use);
+ t.Lower();
+ CHECK_EQ(IrOpcode::kCall, cnv->opcode());
+ CHECK_EQ(IrOpcode::kHeapConstant, cnv->InputAt(0)->opcode());
+ CHECK_EQ(x, cnv->InputAt(1));
+ CHECK_EQ(t.jsgraph.NoContextConstant(), cnv->InputAt(2));
+}
+
+#endif
+
+
TEST(LowerBooleanNot_bit_bit) {
// BooleanNot(x: kRepBit) used as kRepBit
TestingGraph t(Type::Boolean());
@@ -1995,11 +2037,6 @@ TEST(PhiRepresentation) {
HandleAndZoneScope scope;
Zone* z = scope.main_zone();
- Factory* f = z->isolate()->factory();
- Handle<Object> range_min = f->NewNumber(-1e13);
- Handle<Object> range_max = f->NewNumber(1e+15);
- Type* range = Type::Range(range_min, range_max, z);
-
struct TestData {
Type* arg1;
Type* arg2;
@@ -2010,7 +2047,8 @@ TEST(PhiRepresentation) {
TestData test_data[] = {
{Type::Signed32(), Type::Unsigned32(), kMachInt32,
kRepWord32 | kTypeNumber},
- {range, range, kMachUint32, kRepWord32 | kTypeNumber},
+ {Type::Signed32(), Type::Unsigned32(), kMachUint32,
+ kRepWord32 | kTypeNumber},
{Type::Signed32(), Type::Signed32(), kMachInt32, kMachInt32},
{Type::Unsigned32(), Type::Unsigned32(), kMachInt32, kMachUint32},
{Type::Number(), Type::Signed32(), kMachInt32, kMachFloat64},
diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/test-alloc.cc
index 54d516e13e..2e071acc73 100644
--- a/deps/v8/test/cctest/test-alloc.cc
+++ b/deps/v8/test/cctest/test-alloc.cc
@@ -198,7 +198,8 @@ TEST(CodeRange) {
const size_t code_range_size = 32*MB;
CcTest::InitializeVM();
CodeRange code_range(reinterpret_cast<Isolate*>(CcTest::isolate()));
- code_range.SetUp(code_range_size);
+ code_range.SetUp(code_range_size +
+ kReservedCodeRangePages * v8::base::OS::CommitPageSize());
size_t current_allocated = 0;
size_t total_allocated = 0;
List< ::Block> blocks(1000);
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 5c8584d0f5..d18059cd54 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -23999,10 +23999,8 @@ TEST(ScriptNameAndLineNumber) {
CHECK_EQ(13, line_number);
}
-
-void SourceURLHelper(const char* source, const char* expected_source_url,
- const char* expected_source_mapping_url) {
- Local<Script> script = v8_compile(source);
+void CheckMagicComments(Handle<Script> script, const char* expected_source_url,
+ const char* expected_source_mapping_url) {
if (expected_source_url != NULL) {
v8::String::Utf8Value url(script->GetUnboundScript()->GetSourceURL());
CHECK_EQ(expected_source_url, *url);
@@ -24018,6 +24016,12 @@ void SourceURLHelper(const char* source, const char* expected_source_url,
}
}
+void SourceURLHelper(const char* source, const char* expected_source_url,
+ const char* expected_source_mapping_url) {
+ Local<Script> script = v8_compile(source);
+ CheckMagicComments(script, expected_source_url, expected_source_mapping_url);
+}
+
TEST(ScriptSourceURLAndSourceMappingURL) {
LocalContext env;
@@ -24209,7 +24213,9 @@ class TestSourceStream : public v8::ScriptCompiler::ExternalSourceStream {
void RunStreamingTest(const char** chunks,
v8::ScriptCompiler::StreamedSource::Encoding encoding =
v8::ScriptCompiler::StreamedSource::ONE_BYTE,
- bool expected_success = true) {
+ bool expected_success = true,
+ const char* expected_source_url = NULL,
+ const char* expected_source_mapping_url = NULL) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
@@ -24238,6 +24244,8 @@ void RunStreamingTest(const char** chunks,
v8::Handle<Value> result(script->Run());
// All scripts are supposed to return the fixed value 13 when ran.
CHECK_EQ(13, result->Int32Value());
+ CheckMagicComments(script, expected_source_url,
+ expected_source_mapping_url);
} else {
CHECK(script.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -24727,3 +24735,27 @@ TEST(ClassPrototypeCreationContext) {
CompileRun("'use strict'; class Example { }; Example.prototype"));
CHECK(env.local() == result->CreationContext());
}
+
+
+TEST(SimpleStreamingScriptWithSourceURL) {
+ const char* chunks[] = {"function foo() { ret", "urn 13; } f", "oo();\n",
+ "//# sourceURL=bar2.js\n", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true,
+ "bar2.js");
+}
+
+
+TEST(StreamingScriptWithSplitSourceURL) {
+ const char* chunks[] = {"function foo() { ret", "urn 13; } f",
+ "oo();\n//# sourceURL=b", "ar2.js\n", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true,
+ "bar2.js");
+}
+
+
+TEST(StreamingScriptWithSourceMappingURLInTheMiddle) {
+ const char* chunks[] = {"function foo() { ret", "urn 13; }\n//#",
+ " sourceMappingURL=bar2.js\n", "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL,
+ "bar2.js");
+}
diff --git a/deps/v8/test/mjsunit/compiler/regress-445876.js b/deps/v8/test/mjsunit/compiler/regress-445876.js
new file mode 100644
index 0000000000..30e10e56c3
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-445876.js
@@ -0,0 +1,12 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+ while (1) { s++; }
+ while (x) { s++; }
+}
+
+assertThrows(function () { f(1); });
diff --git a/deps/v8/test/mjsunit/compiler/regress-446156.js b/deps/v8/test/mjsunit/compiler/regress-446156.js
new file mode 100644
index 0000000000..f3cd2dd94e
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-446156.js
@@ -0,0 +1,11 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function Module(stdlib, foreign, heap) {
+ "use asm";
+ // This is not valid asm.js, but should nevertheless work.
+ var MEM = new Uint8ClampedArray(heap);
+ function foo( ) { MEM[0] ^= 1; }
+ return {foo: foo};
+})(this, {}, new ArrayBuffer( ) ).foo();
diff --git a/deps/v8/test/mjsunit/compiler/regress-446778.js b/deps/v8/test/mjsunit/compiler/regress-446778.js
new file mode 100644
index 0000000000..a7fa3fdad8
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-446778.js
@@ -0,0 +1,17 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module() {
+ "use asm";
+ function f() {
+ var i = (140737463189505);
+ do {
+ i = i + i | 0;
+ x = undefined + i | 0;
+ } while (!i);
+ }
+ return { f: f };
+}
+
+Module().f();
diff --git a/deps/v8/test/mjsunit/compiler/regress-ntl-effect.js b/deps/v8/test/mjsunit/compiler/regress-ntl-effect.js
new file mode 100644
index 0000000000..708fe32828
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-ntl-effect.js
@@ -0,0 +1,16 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function g() {
+ throw 0;
+}
+
+function f() {
+ g();
+ while (1) {}
+}
+
+assertThrows(function () { f(); });
diff --git a/deps/v8/test/mjsunit/regress/regress-447756.js b/deps/v8/test/mjsunit/regress/regress-447756.js
new file mode 100644
index 0000000000..1fc7518c13
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-447756.js
@@ -0,0 +1,48 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --allow-natives-syntax
+
+function TestConstructor(c) {
+ var a = new c(-0);
+ assertSame(Infinity, 1 / a.length);
+ assertSame(Infinity, 1 / a.byteLength);
+
+ var ab = new ArrayBuffer(-0);
+ assertSame(Infinity, 1 / ab.byteLength);
+
+ var a1 = new c(ab, -0, -0);
+ assertSame(Infinity, 1 / a1.length);
+ assertSame(Infinity, 1 / a1.byteLength);
+ assertSame(Infinity, 1 / a1.byteOffset);
+}
+
+var constructors =
+ [ Uint8Array, Int8Array, Uint8ClampedArray,
+ Uint16Array, Int16Array,
+ Uint32Array, Int32Array,
+ Float32Array, Float64Array ];
+for (var i = 0; i < constructors.length; i++) {
+ TestConstructor(constructors[i]);
+}
+
+
+function TestOptimizedCode() {
+ var a = new Uint8Array(-0);
+ assertSame(Infinity, 1 / a.length);
+ assertSame(Infinity, 1 / a.byteLength);
+
+ var ab = new ArrayBuffer(-0);
+ assertSame(Infinity, 1 / ab.byteLength);
+
+ var a1 = new Uint8Array(ab, -0, -0);
+ assertSame(Infinity, 1 / a1.length);
+ assertSame(Infinity, 1 / a1.byteLength);
+ assertSame(Infinity, 1 / a1.byteOffset);
+}
+
+%OptimizeFunctionOnNextCall(Uint8Array);
+for (var i = 0; i < 1000; i++) {
+ TestOptimizedCode();
+}
diff --git a/deps/v8/test/unittests/compiler/change-lowering-unittest.cc b/deps/v8/test/unittests/compiler/change-lowering-unittest.cc
index 763a44352f..060b1c1842 100644
--- a/deps/v8/test/unittests/compiler/change-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/change-lowering-unittest.cc
@@ -15,6 +15,7 @@
using testing::_;
using testing::AllOf;
+using testing::BitEq;
using testing::Capture;
using testing::CaptureEq;
@@ -78,7 +79,8 @@ class ChangeLoweringTest : public GraphTest {
const Matcher<Node*>& control_matcher) {
return IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
AllocateHeapNumberStub(isolate()).GetCode())),
- IsNumberConstant(0.0), effect_matcher, control_matcher);
+ IsNumberConstant(BitEq(0.0)), effect_matcher,
+ control_matcher);
}
Matcher<Node*> IsLoadHeapNumber(const Matcher<Node*>& value_matcher,
const Matcher<Node*>& control_matcher) {
diff --git a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
index 87d1ad53b8..9c572820e7 100644
--- a/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
@@ -10,6 +10,7 @@
#include "test/unittests/compiler/node-test-utils.h"
#include "testing/gmock-support.h"
+using testing::BitEq;
using testing::Capture;
namespace v8 {
@@ -83,9 +84,11 @@ TEST_F(JSBuiltinReducerTest, MathAbs) {
} else {
Capture<Node*> branch;
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsSelect(kMachNone, IsNumberLessThan(IsNumberConstant(0), p0),
- p0, IsNumberSubtract(IsNumberConstant(0), p0)));
+ EXPECT_THAT(
+ r.replacement(),
+ IsSelect(kMachNone,
+ IsNumberLessThan(IsNumberConstant(BitEq(0.0)), p0), p0,
+ IsNumberSubtract(IsNumberConstant(BitEq(0.0)), p0)));
}
}
}
diff --git a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
index e4ea4a581f..97ff106329 100644
--- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
+++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
@@ -8,10 +8,14 @@
#include "src/compiler/js-typed-lowering.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/typer.h"
#include "test/unittests/compiler/compiler-test-utils.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::BitEq;
+using testing::IsNaN;
+
namespace v8 {
namespace internal {
@@ -25,9 +29,35 @@ const ExternalArrayType kExternalArrayTypes[] = {
kExternalFloat32Array, kExternalFloat64Array};
+const double kFloat64Values[] = {
+ -V8_INFINITY, -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
+ -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
+ -1.67813e+72, -2.3382e+55, -3.179e+30, -1.441e+09, -1.0647e+09,
+ -7.99361e+08, -5.77375e+08, -2.20984e+08, -32757, -13171, -9970, -3984,
+ -107, -105, -92, -77, -61, -0.000208163, -1.86685e-06, -1.17296e-10,
+ -9.26358e-11, -5.08004e-60, -1.74753e-65, -1.06561e-71, -5.67879e-79,
+ -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
+ -4.40497e-267, -2.19666e-273, -4.9998e-276, -5.59821e-278, -2.03855e-282,
+ -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0, 0.0, 2.22507e-308,
+ 1.30127e-270, 7.62898e-260, 4.00313e-249, 3.16829e-233, 1.85244e-228,
+ 2.03544e-129, 1.35126e-110, 1.01182e-106, 5.26333e-94, 1.35292e-90,
+ 2.85394e-83, 1.78323e-77, 5.4967e-57, 1.03207e-25, 4.57401e-25, 1.58738e-05,
+ 2, 125, 2310, 9636, 14802, 17168, 28945, 29305, 4.81336e+07, 1.41207e+08,
+ 4.65962e+08, 1.40499e+09, 2.12648e+09, 8.80006e+30, 1.4446e+45, 1.12164e+54,
+ 2.48188e+89, 6.71121e+102, 3.074e+112, 4.9699e+152, 5.58383e+166,
+ 4.30654e+172, 7.08824e+185, 9.6586e+214, 2.028e+223, 6.63277e+243,
+ 1.56192e+261, 1.23202e+269, 5.72883e+289, 8.5798e+290, 1.40256e+294,
+ 1.79769e+308, V8_INFINITY};
+
+
const size_t kIndices[] = {0, 1, 42, 100, 1024};
+const double kIntegerValues[] = {-V8_INFINITY, INT_MIN, -1000.0, -42.0,
+ -1.0, 0.0, 1.0, 42.0,
+ 1000.0, INT_MAX, UINT_MAX, V8_INFINITY};
+
+
Type* const kJSTypes[] = {Type::Undefined(), Type::Null(), Type::Boolean(),
Type::Number(), Type::String(), Type::Object()};
@@ -69,124 +99,264 @@ class JSTypedLoweringTest : public TypedGraphTest {
// -----------------------------------------------------------------------------
-// JSToBoolean
-
+// JSUnaryNot
-TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) {
- Node* input = Parameter(Type::Boolean());
- Node* context = UndefinedConstant();
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithBoolean) {
+ Node* input = Parameter(Type::Boolean(), 0);
+ Node* context = Parameter(Type::Any(), 1);
Reduction r =
- Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+ Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
ASSERT_TRUE(r.Changed());
- EXPECT_EQ(input, r.replacement());
+ EXPECT_THAT(r.replacement(), IsBooleanNot(input));
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithUndefined) {
- Node* input = Parameter(Type::Undefined());
- Node* context = UndefinedConstant();
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithFalsish) {
+ Handle<Object> zero = factory()->NewNumber(0);
+ Node* input = Parameter(
+ Type::Union(
+ Type::MinusZero(),
+ Type::Union(
+ Type::NaN(),
+ Type::Union(
+ Type::Null(),
+ Type::Union(
+ Type::Undefined(),
+ Type::Union(
+ Type::Undetectable(),
+ Type::Union(
+ Type::Constant(factory()->false_value(), zone()),
+ Type::Range(zero, zero, zone()), zone()),
+ zone()),
+ zone()),
+ zone()),
+ zone()),
+ zone()),
+ 0);
+ Node* context = Parameter(Type::Any(), 1);
+ Reduction r =
+ Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsTrueConstant());
+}
+
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithTruish) {
+ Node* input = Parameter(
+ Type::Union(
+ Type::Constant(factory()->true_value(), zone()),
+ Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
+ zone()),
+ 0);
+ Node* context = Parameter(Type::Any(), 1);
Reduction r =
- Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+ Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFalseConstant());
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithNull) {
- Node* input = Parameter(Type::Null());
- Node* context = UndefinedConstant();
-
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithNonZeroPlainNumber) {
+ Node* input = Parameter(
+ Type::Range(factory()->NewNumber(1), factory()->NewNumber(42), zone()),
+ 0);
+ Node* context = Parameter(Type::Any(), 1);
Reduction r =
- Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+ Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFalseConstant());
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithDetectableReceiver) {
- Node* input = Parameter(Type::DetectableReceiver());
- Node* context = UndefinedConstant();
-
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithAny) {
+ Node* input = Parameter(Type::Any(), 0);
+ Node* context = Parameter(Type::Any(), 1);
Reduction r =
- Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+ Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsTrueConstant());
+ EXPECT_THAT(r.replacement(), IsBooleanNot(IsAnyToBoolean(input)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Constant propagation
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithMinusZero) {
+ {
+ Reduction r = Reduce(
+ Parameter(Type::Constant(factory()->minus_zero_value(), zone())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
+ }
+ {
+ Reduction r = Reduce(Parameter(Type::MinusZero()));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
+ }
+ {
+ Reduction r = Reduce(Parameter(
+ Type::Union(Type::MinusZero(),
+ Type::Constant(factory()->NewNumber(0), zone()), zone())));
+ EXPECT_FALSE(r.Changed());
+ }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithNull) {
+ Handle<HeapObject> null = factory()->null_value();
+ {
+ Reduction r = Reduce(Parameter(Type::Constant(null, zone())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsHeapConstant(Unique<HeapObject>::CreateImmovable(null)));
+ }
+ {
+ Reduction r = Reduce(Parameter(Type::Null()));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsHeapConstant(Unique<HeapObject>::CreateImmovable(null)));
+ }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithNaN) {
+ const double kNaNs[] = {base::OS::nan_value(),
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::signaling_NaN()};
+ TRACED_FOREACH(double, nan, kNaNs) {
+ Handle<Object> constant = factory()->NewNumber(nan);
+ Reduction r = Reduce(Parameter(Type::Constant(constant, zone())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+ }
+ {
+ Reduction r =
+ Reduce(Parameter(Type::Constant(factory()->nan_value(), zone())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+ }
+ {
+ Reduction r = Reduce(Parameter(Type::NaN()));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+ }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithPlainNumber) {
+ TRACED_FOREACH(double, value, kFloat64Values) {
+ Handle<Object> constant = factory()->NewNumber(value);
+ Reduction r = Reduce(Parameter(Type::Constant(constant, zone())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(value));
+ }
+ TRACED_FOREACH(double, value, kIntegerValues) {
+ Handle<Object> constant = factory()->NewNumber(value);
+ Reduction r = Reduce(Parameter(Type::Range(constant, constant, zone())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(), IsNumberConstant(value));
+ }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithUndefined) {
+ Handle<HeapObject> undefined = factory()->undefined_value();
+ {
+ Reduction r = Reduce(Parameter(Type::Undefined()));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsHeapConstant(Unique<HeapObject>::CreateImmovable(undefined)));
+ }
+ {
+ Reduction r = Reduce(Parameter(Type::Constant(undefined, zone())));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsHeapConstant(Unique<HeapObject>::CreateImmovable(undefined)));
+ }
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithUndetectable) {
- Node* input = Parameter(Type::Undetectable());
- Node* context = UndefinedConstant();
+// -----------------------------------------------------------------------------
+// JSToBoolean
+
+TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) {
+ Node* input = Parameter(Type::Boolean(), 0);
+ Node* context = Parameter(Type::Any(), 1);
Reduction r =
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsFalseConstant());
+ EXPECT_EQ(input, r.replacement());
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithOrderedNumber) {
- Node* input = Parameter(Type::OrderedNumber());
- Node* context = UndefinedConstant();
-
+TEST_F(JSTypedLoweringTest, JSToBooleanWithFalsish) {
+ Handle<Object> zero = factory()->NewNumber(0);
+ Node* input = Parameter(
+ Type::Union(
+ Type::MinusZero(),
+ Type::Union(
+ Type::NaN(),
+ Type::Union(
+ Type::Null(),
+ Type::Union(
+ Type::Undefined(),
+ Type::Union(
+ Type::Undetectable(),
+ Type::Union(
+ Type::Constant(factory()->false_value(), zone()),
+ Type::Range(zero, zero, zone()), zone()),
+ zone()),
+ zone()),
+ zone()),
+ zone()),
+ zone()),
+ 0);
+ Node* context = Parameter(Type::Any(), 1);
Reduction r =
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0))));
+ EXPECT_THAT(r.replacement(), IsFalseConstant());
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithString) {
- Node* input = Parameter(Type::String());
- Node* context = UndefinedConstant();
-
+TEST_F(JSTypedLoweringTest, JSToBooleanWithTruish) {
+ Node* input = Parameter(
+ Type::Union(
+ Type::Constant(factory()->true_value(), zone()),
+ Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
+ zone()),
+ 0);
+ Node* context = Parameter(Type::Any(), 1);
Reduction r =
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsBooleanNot(IsNumberEqual(
- IsLoadField(AccessBuilder::ForStringLength(), input,
- graph()->start(), graph()->start()),
- IsNumberConstant(0))));
+ EXPECT_THAT(r.replacement(), IsTrueConstant());
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithPhi) {
- Node* p0 = Parameter(Type::OrderedNumber(), 0);
- Node* p1 = Parameter(Type::Boolean(), 1);
- Node* context = UndefinedConstant();
- Node* control = graph()->start();
-
- Reduction r = Reduce(graph()->NewNode(
- javascript()->ToBoolean(),
- graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, control),
- context));
+TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) {
+ Node* input =
+ Parameter(Type::Range(factory()->NewNumber(1),
+ factory()->NewNumber(V8_INFINITY), zone()),
+ 0);
+ Node* context = Parameter(Type::Any(), 1);
+ Reduction r =
+ Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(
- r.replacement(),
- IsPhi(kMachAnyTagged,
- IsBooleanNot(IsNumberEqual(p0, IsNumberConstant(0))), p1, control));
+ EXPECT_THAT(r.replacement(), IsTrueConstant());
}
-TEST_F(JSTypedLoweringTest, JSToBooleanWithSelect) {
- Node* p0 = Parameter(Type::Boolean(), 0);
- Node* p1 = Parameter(Type::DetectableReceiver(), 1);
- Node* p2 = Parameter(Type::OrderedNumber(), 2);
- Node* context = UndefinedConstant();
-
- Reduction r = Reduce(graph()->NewNode(
- javascript()->ToBoolean(),
- graph()->NewNode(common()->Select(kMachAnyTagged, BranchHint::kTrue), p0,
- p1, p2),
- context));
+TEST_F(JSTypedLoweringTest, JSToBooleanWithAny) {
+ Node* input = Parameter(Type::Any(), 0);
+ Node* context = Parameter(Type::Any(), 1);
+ Reduction r =
+ Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(),
- IsSelect(kMachAnyTagged, p0, IsTrueConstant(),
- IsBooleanNot(IsNumberEqual(p2, IsNumberConstant(0)))));
+ EXPECT_THAT(r.replacement(), IsAnyToBoolean(input));
}
@@ -202,7 +372,7 @@ TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) {
Reduction r = Reduce(graph()->NewNode(javascript()->ToNumber(), input,
context, effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(0),
+ EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(BitEq(0.0)),
graph()->start(), control));
}
@@ -235,12 +405,13 @@ TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
- TRACED_FORRANGE(int32_t, rhs, 0, 31) {
+ TRACED_FORRANGE(double, rhs, 0, 31) {
Reduction r =
Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs,
NumberConstant(rhs), context, effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsWord32Shl(lhs, IsNumberConstant(rhs)));
+ EXPECT_THAT(r.replacement(),
+ IsWord32Shl(lhs, IsNumberConstant(BitEq(rhs))));
}
}
@@ -268,12 +439,13 @@ TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
- TRACED_FORRANGE(int32_t, rhs, 0, 31) {
+ TRACED_FORRANGE(double, rhs, 0, 31) {
Reduction r =
Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs,
NumberConstant(rhs), context, effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsWord32Sar(lhs, IsNumberConstant(rhs)));
+ EXPECT_THAT(r.replacement(),
+ IsWord32Sar(lhs, IsNumberConstant(BitEq(rhs))));
}
}
@@ -301,12 +473,13 @@ TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndConstant) {
Node* const context = UndefinedConstant();
Node* const effect = graph()->start();
Node* const control = graph()->start();
- TRACED_FORRANGE(int32_t, rhs, 0, 31) {
+ TRACED_FORRANGE(double, rhs, 0, 31) {
Reduction r =
Reduce(graph()->NewNode(javascript()->ShiftRightLogical(), lhs,
NumberConstant(rhs), context, effect, control));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsWord32Shr(lhs, IsNumberConstant(rhs)));
+ EXPECT_THAT(r.replacement(),
+ IsWord32Shr(lhs, IsNumberConstant(BitEq(rhs))));
}
}
diff --git a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
index b92bd28c97..6fdba35f58 100644
--- a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -12,6 +12,7 @@
#include "testing/gmock-support.h"
using testing::AllOf;
+using testing::BitEq;
using testing::Capture;
using testing::CaptureEq;
@@ -291,7 +292,7 @@ TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
Reduction reduction = Reduce(graph()->NewNode(
machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsFloat64Constant(x));
+ EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq<double>(x)));
}
}
@@ -355,7 +356,7 @@ TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
Reduction reduction = Reduce(
graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastI2D(x)));
+ EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
}
}
@@ -384,7 +385,7 @@ TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
Int32Constant(bit_cast<int32_t>(x))));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastUI2D(x)));
+ EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastUI2D(x))));
}
}
@@ -425,7 +426,8 @@ TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
Reduction reduction = Reduce(graph()->NewNode(
machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsFloat32Constant(DoubleToFloat32(x)));
+ EXPECT_THAT(reduction.replacement(),
+ IsFloat32Constant(BitEq(DoubleToFloat32(x))));
}
}
@@ -1268,13 +1270,15 @@ TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) {
Reduction r = Reduce(
graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(-1.0)));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsFloat64Sub(IsFloat64Constant(-0.0), p0));
+ EXPECT_THAT(r.replacement(),
+ IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
}
{
Reduction r = Reduce(
graph()->NewNode(machine()->Float64Mul(), Float64Constant(-1.0), p0));
ASSERT_TRUE(r.Changed());
- EXPECT_THAT(r.replacement(), IsFloat64Sub(IsFloat64Constant(-0.0), p0));
+ EXPECT_THAT(r.replacement(),
+ IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
}
}
diff --git a/deps/v8/test/unittests/compiler/node-test-utils.cc b/deps/v8/test/unittests/compiler/node-test-utils.cc
index 3162c548f3..74afda974a 100644
--- a/deps/v8/test/unittests/compiler/node-test-utils.cc
+++ b/deps/v8/test/unittests/compiler/node-test-utils.cc
@@ -1290,6 +1290,7 @@ IS_BINOP_MATCHER(Float64Sub)
Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \
return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
}
+IS_UNOP_MATCHER(AnyToBoolean)
IS_UNOP_MATCHER(BooleanNot)
IS_UNOP_MATCHER(ChangeFloat64ToInt32)
IS_UNOP_MATCHER(ChangeFloat64ToUint32)
diff --git a/deps/v8/test/unittests/compiler/node-test-utils.h b/deps/v8/test/unittests/compiler/node-test-utils.h
index f1f20cfe19..02b6e43175 100644
--- a/deps/v8/test/unittests/compiler/node-test-utils.h
+++ b/deps/v8/test/unittests/compiler/node-test-utils.h
@@ -75,6 +75,7 @@ Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsAnyToBoolean(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsNumberEqual(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
diff --git a/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc
index 066cbe9337..e5f46c0d53 100644
--- a/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc
@@ -2,22 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/compiler/access-builder.h"
#include "src/compiler/js-graph.h"
+#include "src/compiler/node-properties-inl.h"
#include "src/compiler/simplified-operator.h"
#include "src/compiler/simplified-operator-reducer.h"
#include "src/conversions.h"
#include "src/types.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::BitEq;
+
namespace v8 {
namespace internal {
namespace compiler {
-class SimplifiedOperatorReducerTest : public GraphTest {
+class SimplifiedOperatorReducerTest : public TypedGraphTest {
public:
explicit SimplifiedOperatorReducerTest(int num_parameters = 1)
- : GraphTest(num_parameters), simplified_(zone()) {}
+ : TypedGraphTest(num_parameters), simplified_(zone()) {}
~SimplifiedOperatorReducerTest() OVERRIDE {}
protected:
@@ -114,11 +120,6 @@ static const uint32_t kUint32Values[] = {
0xbeb15c0d, 0xc171c53d, 0xc743dd38, 0xc8e2af50, 0xc98e2df0, 0xd9d1cdf9,
0xdcc91049, 0xe46f396d, 0xee991950, 0xef64e521, 0xf7aeefc9, 0xffffffff};
-
-MATCHER(IsNaN, std::string(negation ? "isn't" : "is") + " NaN") {
- return std::isnan(arg);
-}
-
} // namespace
@@ -140,6 +141,7 @@ std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
static const UnaryOperator kUnaryOperators[] = {
+ {&SimplifiedOperatorBuilder::AnyToBoolean, "AnyToBoolean"},
{&SimplifiedOperatorBuilder::BooleanNot, "BooleanNot"},
{&SimplifiedOperatorBuilder::ChangeBitToBool, "ChangeBitToBool"},
{&SimplifiedOperatorBuilder::ChangeBoolToBit, "ChangeBoolToBit"},
@@ -161,8 +163,8 @@ typedef SimplifiedOperatorReducerTestWithParam<UnaryOperator>
TEST_P(SimplifiedUnaryOperatorTest, Parameter) {
const UnaryOperator& unop = GetParam();
- Reduction reduction = Reduce(
- graph()->NewNode((simplified()->*unop.constructor)(), Parameter(0)));
+ Reduction reduction = Reduce(graph()->NewNode(
+ (simplified()->*unop.constructor)(), Parameter(Type::Any())));
EXPECT_FALSE(reduction.Changed());
}
@@ -173,6 +175,39 @@ INSTANTIATE_TEST_CASE_P(SimplifiedOperatorReducerTest,
// -----------------------------------------------------------------------------
+// AnyToBoolean
+
+
+TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithBoolean) {
+ Node* p = Parameter(Type::Boolean());
+ Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_EQ(p, r.replacement());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithOrderedNumber) {
+ Node* p = Parameter(Type::OrderedNumber());
+ Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsBooleanNot(IsNumberEqual(p, IsNumberConstant(0))));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithString) {
+ Node* p = Parameter(Type::String());
+ Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsBooleanNot(
+ IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(), p,
+ graph()->start(), graph()->start()),
+ IsNumberConstant(0))));
+}
+
+
+// -----------------------------------------------------------------------------
// BooleanNot
@@ -271,7 +306,7 @@ TEST_F(SimplifiedOperatorReducerTest, ChangeFloat64ToTaggedWithConstant) {
Reduction reduction = Reduce(graph()->NewNode(
simplified()->ChangeFloat64ToTagged(), Float64Constant(n)));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsNumberConstant(n));
+ EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(n)));
}
}
@@ -285,7 +320,7 @@ TEST_F(SimplifiedOperatorReducerTest, ChangeInt32ToTaggedWithConstant) {
Reduction reduction = Reduce(graph()->NewNode(
simplified()->ChangeInt32ToTagged(), Int32Constant(n)));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsNumberConstant(FastI2D(n)));
+ EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastI2D(n))));
}
}
@@ -332,7 +367,7 @@ TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithConstant) {
Reduction reduction = Reduce(graph()->NewNode(
simplified()->ChangeTaggedToFloat64(), NumberConstant(n)));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsFloat64Constant(n));
+ EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(n)));
}
}
@@ -342,7 +377,8 @@ TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant1) {
Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
NumberConstant(-base::OS::nan_value())));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsFloat64Constant(IsNaN()));
+ EXPECT_THAT(reduction.replacement(),
+ IsFloat64Constant(BitEq(-base::OS::nan_value())));
}
@@ -351,7 +387,8 @@ TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant2) {
Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
NumberConstant(base::OS::nan_value())));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsFloat64Constant(IsNaN()));
+ EXPECT_THAT(reduction.replacement(),
+ IsFloat64Constant(BitEq(base::OS::nan_value())));
}
@@ -474,7 +511,7 @@ TEST_F(SimplifiedOperatorReducerTest, ChangeUint32ToTagged) {
Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(),
Int32Constant(bit_cast<int32_t>(n))));
ASSERT_TRUE(reduction.Changed());
- EXPECT_THAT(reduction.replacement(), IsNumberConstant(FastUI2D(n)));
+ EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastUI2D(n))));
}
}
diff --git a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
index e7fceba47d..bc537fd952 100644
--- a/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
@@ -38,6 +38,7 @@ const PureOperator kPureOperators[] = {
&SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
Operator::kPure | properties, input_count \
}
+ PURE(AnyToBoolean, Operator::kNoProperties, 1),
PURE(BooleanNot, Operator::kNoProperties, 1),
PURE(BooleanToNumber, Operator::kNoProperties, 1),
PURE(NumberEqual, Operator::kCommutative, 2),
diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
index c96c8361fd..0e00f23cad 100644
--- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
+++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
@@ -47,7 +47,7 @@ PASS getSortedOwnPropertyNames(encodeURIComponent) is ['arguments', 'caller', 'l
PASS getSortedOwnPropertyNames(Object) is ['arguments', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve']
PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
PASS getSortedOwnPropertyNames(Function) is ['arguments', 'caller', 'length', 'name', 'prototype']
-PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toMethod', 'toString']
+PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']
PASS getSortedOwnPropertyNames(Array) is ['arguments', 'caller', 'isArray', 'length', 'name', 'observe', 'prototype', 'unobserve']
PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'entries', 'every', 'filter', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']
PASS getSortedOwnPropertyNames(String) is ['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']
diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
index 46d7966664..72bd21b426 100644
--- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
+++ b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
@@ -74,7 +74,7 @@ var expectedPropertyNamesSet = {
"Object": "['arguments', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve']",
"Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']",
"Function": "['arguments', 'caller', 'length', 'name', 'prototype']",
- "Function.prototype": "['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toMethod', 'toString']",
+ "Function.prototype": "['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']",
"Array": "['arguments', 'caller', 'isArray', 'length', 'name', 'observe', 'prototype', 'unobserve']",
"Array.prototype": "['concat', 'constructor', 'entries', 'every', 'filter', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']",
"String": "['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']",
diff --git a/deps/v8/testing/gmock-support.h b/deps/v8/testing/gmock-support.h
index 44348b60e0..012775b5cb 100644
--- a/deps/v8/testing/gmock-support.h
+++ b/deps/v8/testing/gmock-support.h
@@ -5,6 +5,9 @@
#ifndef V8_TESTING_GMOCK_SUPPORT_H_
#define V8_TESTING_GMOCK_SUPPORT_H_
+#include <cmath>
+#include <cstring>
+
#include "testing/gmock/include/gmock/gmock.h"
namespace testing {
@@ -31,6 +34,25 @@ class Capture {
namespace internal {
+struct AnyBitEq {
+ template <typename A, typename B>
+ bool operator()(A const& a, B const& b) const {
+ if (sizeof(A) != sizeof(B)) return false;
+ return std::memcmp(&a, &b, sizeof(A)) == 0;
+ }
+};
+
+
+template <typename Rhs>
+class BitEqMatcher : public ComparisonBase<BitEqMatcher<Rhs>, Rhs, AnyBitEq> {
+ public:
+ explicit BitEqMatcher(Rhs const& rhs)
+ : ComparisonBase<BitEqMatcher<Rhs>, Rhs, AnyBitEq>(rhs) {}
+ static const char* Desc() { return "is bitwise equal to"; }
+ static const char* NegatedDesc() { return "isn't bitwise equal to"; }
+};
+
+
template <typename T>
class CaptureEqMatcher : public MatcherInterface<T> {
public:
@@ -60,13 +82,27 @@ class CaptureEqMatcher : public MatcherInterface<T> {
} // namespace internal
+// Creates a polymorphic matcher that matches anything whose bit representation
+// is equal to that of x.
+template <typename T>
+inline internal::BitEqMatcher<T> BitEq(T const& x) {
+ return internal::BitEqMatcher<T>(x);
+}
+
+
// CaptureEq(capture) captures the value passed in during matching as long as it
// is unset, and once set, compares the value for equality with the argument.
template <typename T>
-Matcher<T> CaptureEq(Capture<T>* capture) {
+inline Matcher<T> CaptureEq(Capture<T>* capture) {
return MakeMatcher(new internal::CaptureEqMatcher<T>(capture));
}
+
+// Creates a polymorphic matcher that matches any floating point NaN value.
+MATCHER(IsNaN, std::string(negation ? "isn't" : "is") + " not a number") {
+ return std::isnan(arg);
+}
+
} // namespace testing
#endif // V8_TESTING_GMOCK_SUPPORT_H_
diff --git a/deps/v8/tools/push-to-trunk/generate_version.py b/deps/v8/tools/push-to-trunk/generate_version.py
new file mode 100755
index 0000000000..b4a0221eae
--- /dev/null
+++ b/deps/v8/tools/push-to-trunk/generate_version.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Script to set v8's version file to the version given by the latest tag.
+"""
+
+
+import os
+import re
+import subprocess
+import sys
+
+
+CWD = os.path.abspath(
+ os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
+VERSION_CC = os.path.join(CWD, "src", "version.cc")
+
+def main():
+ tag = subprocess.check_output(
+ "git describe --tags",
+ shell=True,
+ cwd=CWD,
+ ).strip()
+ assert tag
+
+ # Check for commits not exactly matching a tag. Those are candidate builds
+ # for the next version. The output has the form
+ # <tag name>-<n commits>-<hash>.
+ if "-" in tag:
+ version = tag.split("-")[0]
+ candidate = "1"
+ else:
+ version = tag
+ candidate = "0"
+ version_levels = version.split(".")
+
+ # Set default patch level if none is given.
+ if len(version_levels) == 3:
+ version_levels.append("0")
+ assert len(version_levels) == 4
+
+ major, minor, build, patch = version_levels
+
+ # Increment build level for candidate builds.
+ if candidate == "1":
+ build = str(int(build) + 1)
+ patch = "0"
+
+ # Modify version.cc with the new values.
+ with open(VERSION_CC, "r") as f:
+ text = f.read()
+ output = []
+ for line in text.split("\n"):
+ for definition, substitute in (
+ ("MAJOR_VERSION", major),
+ ("MINOR_VERSION", minor),
+ ("BUILD_NUMBER", build),
+ ("PATCH_LEVEL", patch),
+ ("IS_CANDIDATE_VERSION", candidate)):
+ if line.startswith("#define %s" % definition):
+ line = re.sub("\d+$", substitute, line)
+ output.append(line)
+ with open(VERSION_CC, "w") as f:
+ f.write("\n".join(output))
+
+ # Log what was done.
+ candidate_txt = " (candidate)" if candidate == "1" else ""
+ patch_txt = ".%s" % patch if patch != "0" else ""
+ version_txt = ("%s.%s.%s%s%s" %
+ (major, minor, build, patch_txt, candidate_txt))
+ print "Modified version.cc. Set V8 version to %s" % version_txt
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/deps/v8/tools/run_perf.py b/deps/v8/tools/run_perf.py
index 14d67c56b0..63c9148515 100755
--- a/deps/v8/tools/run_perf.py
+++ b/deps/v8/tools/run_perf.py
@@ -529,10 +529,17 @@ class AndroidPlatform(Platform): # pragma: no cover
perf.SetDefaultPerfMode()
self.device.RunShellCommand(["rm", "-rf", AndroidPlatform.DEVICE_DIR])
+ def _SendCommand(self, cmd):
+ logging.info("adb -s %s %s" % (str(self.device), cmd))
+ return self.adb.SendCommand(cmd, timeout_time=60)
+
def _PushFile(self, host_dir, file_name, target_rel="."):
file_on_host = os.path.join(host_dir, file_name)
+ file_on_device_tmp = os.path.join(
+ AndroidPlatform.DEVICE_DIR, "_tmp_", file_name)
file_on_device = os.path.join(
AndroidPlatform.DEVICE_DIR, target_rel, file_name)
+ folder_on_device = os.path.dirname(file_on_device)
# Only push files not yet pushed in one execution.
if file_on_host in self.pushed:
@@ -540,8 +547,16 @@ class AndroidPlatform(Platform): # pragma: no cover
else:
self.pushed.add(file_on_host)
- logging.info("adb push %s %s" % (file_on_host, file_on_device))
- self.adb.Push(file_on_host, file_on_device)
+ # Work-around for "text file busy" errors. Push the files to a temporary
+ # location and then copy them with a shell command.
+ output = self._SendCommand(
+ "push %s %s" % (file_on_host, file_on_device_tmp))
+ # Success looks like this: "3035 KB/s (12512056 bytes in 4.025s)".
+ # Errors look like this: "failed to copy ... ".
+ if output and not re.search('^[0-9]', output.splitlines()[-1]):
+ logging.critical('PUSH FAILED: ' + output)
+ self._SendCommand("shell mkdir -p %s" % folder_on_device)
+ self._SendCommand("shell cp %s %s" % (file_on_device_tmp, file_on_device))
def PreTests(self, node, path):
suite_dir = os.path.abspath(os.path.dirname(path))
diff --git a/deps/v8/tools/whitespace.txt b/deps/v8/tools/whitespace.txt
index 55592a9254..657e68f42e 100644
--- a/deps/v8/tools/whitespace.txt
+++ b/deps/v8/tools/whitespace.txt
@@ -5,4 +5,4 @@ Try to write something funny. And please don't add trailing whitespace.
A Smi walks into a bar and says:
"I'm so deoptimized today!"
The doubles heard this and started to unbox.
-The Smi looked at them when a crazy v8-autoroll account showed up........
+The Smi looked at them when a crazy v8-autoroll account showed up...........