Browse Source

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>
v1.8.0-commit
Ben Noordhuis 10 years ago
parent
commit
5e7ebc7af6
  1. 31
      deps/v8/ChangeLog
  2. 2
      deps/v8/DEPS
  3. 2
      deps/v8/build/features.gypi
  4. 1
      deps/v8/src/api.cc
  5. 2
      deps/v8/src/base/platform/platform-freebsd.cc
  6. 2
      deps/v8/src/base/platform/platform-posix.cc
  7. 22
      deps/v8/src/compiler/control-reducer.cc
  8. 190
      deps/v8/src/compiler/js-typed-lowering.cc
  9. 3
      deps/v8/src/compiler/js-typed-lowering.h
  10. 1
      deps/v8/src/compiler/opcodes.h
  11. 2
      deps/v8/src/compiler/pipeline.cc
  12. 41
      deps/v8/src/compiler/simplified-lowering.cc
  13. 6
      deps/v8/src/compiler/simplified-lowering.h
  14. 40
      deps/v8/src/compiler/simplified-operator-reducer.cc
  15. 4
      deps/v8/src/compiler/simplified-operator-reducer.h
  16. 1
      deps/v8/src/compiler/simplified-operator.cc
  17. 2
      deps/v8/src/compiler/simplified-operator.h
  18. 37
      deps/v8/src/compiler/typer.cc
  19. 4
      deps/v8/src/compiler/verifier.cc
  20. 2
      deps/v8/src/d8.cc
  21. 2
      deps/v8/src/debug.cc
  22. 15
      deps/v8/src/deoptimizer.cc
  23. 11
      deps/v8/src/flag-definitions.h
  24. 2
      deps/v8/src/heap/heap.cc
  25. 2
      deps/v8/src/heap/heap.h
  26. 2
      deps/v8/src/heap/incremental-marking.cc
  27. 3
      deps/v8/src/heap/spaces.cc
  28. 33
      deps/v8/src/ia32/assembler-ia32.cc
  29. 3
      deps/v8/src/parser.h
  30. 2
      deps/v8/src/preparser.h
  31. 2
      deps/v8/src/runtime.js
  32. 2
      deps/v8/src/unique.h
  33. 8
      deps/v8/src/version.cc
  34. 33
      deps/v8/src/x64/assembler-x64.cc
  35. 43
      deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
  36. 58
      deps/v8/test/cctest/compiler/test-simplified-lowering.cc
  37. 3
      deps/v8/test/cctest/test-alloc.cc
  38. 40
      deps/v8/test/cctest/test-api.cc
  39. 12
      deps/v8/test/mjsunit/compiler/regress-445876.js
  40. 11
      deps/v8/test/mjsunit/compiler/regress-446156.js
  41. 17
      deps/v8/test/mjsunit/compiler/regress-446778.js
  42. 16
      deps/v8/test/mjsunit/compiler/regress-ntl-effect.js
  43. 48
      deps/v8/test/mjsunit/regress/regress-447756.js
  44. 4
      deps/v8/test/unittests/compiler/change-lowering-unittest.cc
  45. 9
      deps/v8/test/unittests/compiler/js-builtin-reducer-unittest.cc
  46. 323
      deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc
  47. 16
      deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc
  48. 1
      deps/v8/test/unittests/compiler/node-test-utils.cc
  49. 1
      deps/v8/test/unittests/compiler/node-test-utils.h
  50. 67
      deps/v8/test/unittests/compiler/simplified-operator-reducer-unittest.cc
  51. 1
      deps/v8/test/unittests/compiler/simplified-operator-unittest.cc
  52. 2
      deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
  53. 2
      deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js
  54. 38
      deps/v8/testing/gmock-support.h
  55. 78
      deps/v8/tools/push-to-trunk/generate_version.py
  56. 19
      deps/v8/tools/run_perf.py
  57. 2
      deps/v8/tools/whitespace.txt

31
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

2
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 = {

2
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', {

1
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();

2
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)

2
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
}

22
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()) {
EnsureStateSize(id);
if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
} else {
state_.resize((3 * id) / 2, kUnvisited);
}
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) {

190
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);
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);
}
InsertConversion(node);
if (node->InputAt(1) != jsgraph()->NoContextConstant()) {
// JSToBoolean(x,context) => JSToBoolean(x,no-context)
node->ReplaceInput(1, jsgraph()->NoContextConstant());
// JSToBoolean(x,context) => AnyToBoolean(x)
node->set_op(simplified()->AnyToBoolean());
node->TrimInputCount(1);
return Changed(node);
}
return NoChange();
}
@ -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);

3
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);

1
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) \

2
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());

41
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);
}

6
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);

40
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();
}

4
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_; }

1
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) \

2
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();

37
deps/v8/src/compiler/typer.cc

@ -33,9 +33,10 @@ 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
#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) \
#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) \
#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) \
#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());

4
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());

2
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);

2
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;
}

15
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,"

11
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

2
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();

2
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).

2
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;
}

3
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;

33
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;
}

3
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);

2
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);
}

2
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;
}

2
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) {

8
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

33
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;
}

43
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());
}
}

58
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},

3
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);

40
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,
void CheckMagicComments(Handle<Script> script, const char* expected_source_url,
const char* expected_source_mapping_url) {
Local<Script> script = v8_compile(source);
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");
}

12
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); });

11
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();

17
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();

16
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(); });

48
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();
}

4
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) {

9
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)));
}
}
}

323
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)));
}
TEST_F(JSTypedLoweringTest, JSToBooleanWithUndetectable) {
Node* input = Parameter(Type::Undetectable());
Node* context = UndefinedConstant();
// -----------------------------------------------------------------------------
// Constant propagation
Reduction r =
Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
TEST_F(JSTypedLoweringTest, ParameterWithMinusZero) {
{
Reduction r = Reduce(
Parameter(Type::Constant(factory()->minus_zero_value(), zone())));
ASSERT_TRUE(r.Changed());
EXPECT_THAT(r.replacement(), IsFalseConstant());
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, JSToBooleanWithOrderedNumber) {
Node* input = Parameter(Type::OrderedNumber());
Node* context = UndefinedConstant();
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(graph()->NewNode(javascript()->ToBoolean(), input, context));
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(),
IsBooleanNot(IsNumberEqual(input, IsNumberConstant(0))));
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, JSToBooleanWithString) {
Node* input = Parameter(Type::String());
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(),
IsBooleanNot(IsNumberEqual(
IsLoadField(AccessBuilder::ForStringLength(), input,
graph()->start(), graph()->start()),
IsNumberConstant(0))));
EXPECT_EQ(input, r.replacement());
}
TEST_F(JSTypedLoweringTest, JSToBooleanWithPhi) {
Node* p0 = Parameter(Type::OrderedNumber(), 0);
Node* p1 = Parameter(Type::Boolean(), 1);
Node* context = UndefinedConstant();
Node* control = graph()->start();
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(), IsFalseConstant());
}
Reduction r = Reduce(graph()->NewNode(
javascript()->ToBoolean(),
graph()->NewNode(common()->Phi(kMachAnyTagged, 2), p0, p1, control),
context));
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(),
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();
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(), IsTrueConstant());
}
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))));
}
}

16
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));
}
}

1
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)

1
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);

67
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());
}
@ -172,6 +174,39 @@ INSTANTIATE_TEST_CASE_P(SimplifiedOperatorReducerTest,
::testing::ValuesIn(kUnaryOperators));
// -----------------------------------------------------------------------------
// 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))));
}
}

1
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),

2
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']

2
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']",

38
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_

78
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())

19
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))

2
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...........

Loading…
Cancel
Save