Browse Source

Upgrade V8 to 2.2.21

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
2072925f12
  1. 15
      deps/v8/ChangeLog
  2. 12
      deps/v8/benchmarks/README.txt
  3. 28
      deps/v8/benchmarks/base.js
  4. 2
      deps/v8/benchmarks/crypto.js
  5. 8
      deps/v8/benchmarks/deltablue.js
  6. 2
      deps/v8/benchmarks/earley-boyer.js
  7. 2
      deps/v8/benchmarks/raytrace.js
  8. 2
      deps/v8/benchmarks/regexp.js
  9. 13
      deps/v8/benchmarks/revisions.html
  10. 2
      deps/v8/benchmarks/richards.js
  11. 2
      deps/v8/benchmarks/run.html
  12. 21
      deps/v8/benchmarks/splay.js
  13. 12
      deps/v8/src/arm/assembler-arm.cc
  14. 3
      deps/v8/src/arm/assembler-arm.h
  15. 371
      deps/v8/src/arm/codegen-arm.cc
  16. 96
      deps/v8/src/arm/codegen-arm.h
  17. 2
      deps/v8/src/arm/constants-arm.cc
  18. 5
      deps/v8/src/arm/disasm-arm.cc
  19. 2
      deps/v8/src/arm/ic-arm.cc
  20. 75
      deps/v8/src/arm/macro-assembler-arm.cc
  21. 49
      deps/v8/src/arm/macro-assembler-arm.h
  22. 9
      deps/v8/src/arm/simulator-arm.cc
  23. 1
      deps/v8/src/code-stubs.h
  24. 59
      deps/v8/src/debug-debugger.js
  25. 10
      deps/v8/src/handles.cc
  26. 6
      deps/v8/src/handles.h
  27. 10
      deps/v8/src/ia32/codegen-ia32.cc
  28. 2
      deps/v8/src/json.js
  29. 18
      deps/v8/src/jsregexp.cc
  30. 2
      deps/v8/src/objects.cc
  31. 4
      deps/v8/src/regexp-macro-assembler.cc
  32. 42
      deps/v8/src/runtime.cc
  33. 12
      deps/v8/src/runtime.js
  34. 2
      deps/v8/src/type-info.h
  35. 2
      deps/v8/src/version.cc
  36. 6
      deps/v8/src/x64/assembler-x64.cc
  37. 32
      deps/v8/src/x64/codegen-x64.cc
  38. 26
      deps/v8/src/x64/disasm-x64.cc
  39. 18
      deps/v8/src/x64/macro-assembler-x64.cc
  40. 2
      deps/v8/src/x64/virtual-frame-x64.cc
  41. 3
      deps/v8/test/cctest/SConscript
  42. 171
      deps/v8/test/cctest/test-api.cc
  43. 35
      deps/v8/test/cctest/test-disasm-arm.cc
  44. 56
      deps/v8/test/cctest/test-type-info.cc
  45. 2
      deps/v8/test/es5conform/README
  46. 217
      deps/v8/test/es5conform/es5conform.status
  47. 12
      deps/v8/test/mjsunit/debug-setbreakpoint.js
  48. 25
      deps/v8/test/mjsunit/math-sqrt.js
  49. 53
      deps/v8/test/mjsunit/mod.js
  50. 36
      deps/v8/test/mjsunit/regress/regress-753.js
  51. 86
      deps/v8/test/mjsunit/to_number_order.js
  52. 52
      deps/v8/test/mozilla/mozilla.status
  53. 26
      deps/v8/tools/stats-viewer.py

15
deps/v8/ChangeLog

@ -1,3 +1,18 @@
2010-06-30: Version 2.2.21
Fix bug in externalizing some ASCII strings (Chromium issue 47824).
Update JSON.stringify to floor the space parameter (issue 753).
Update the Mozilla test expectations to the newest version.
Update the ES5 Conformance Test expectations to the latest version.
Update the V8 benchmark suite.
Provide actual breakpoints locations in response to setBreakpoint
and listBreakpoints requests.
2010-06-28: Version 2.2.20 2010-06-28: Version 2.2.20
Fix bug with for-in on x64 platform (issue 748). Fix bug with for-in on x64 platform (issue 748).

12
deps/v8/benchmarks/README.txt

@ -66,6 +66,12 @@ extensions enabled.
Changes from Version 5 to Version 6 Changes from Version 5 to Version 6
=================================== ===================================
Removed dead code from the RayTrace benchmark and changed the Splay Removed dead code from the RayTrace benchmark and fixed a couple of
benchmark to avoid converting the same numeric key to a string over typos in the DeltaBlue implementation. Changed the Splay benchmark to
and over again. avoid converting the same numeric key to a string over and over again
and to avoid inserting and removing the same element repeatedly thus
increasing pressure on the memory subsystem.
Furthermore, the benchmark runner was changed to run the benchmarks
for at least a few times to stabilize the reported numbers on slower
machines.

28
deps/v8/benchmarks/base.js

@ -198,15 +198,33 @@ BenchmarkSuite.prototype.NotifyError = function(error) {
// Runs a single benchmark for at least a second and computes the // Runs a single benchmark for at least a second and computes the
// average time it takes to run a single iteration. // average time it takes to run a single iteration.
BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark) { BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
function Measure(data) {
var elapsed = 0; var elapsed = 0;
var start = new Date(); var start = new Date();
for (var n = 0; elapsed < 1000; n++) { for (var n = 0; elapsed < 1000; n++) {
benchmark.run(); benchmark.run();
elapsed = new Date() - start; elapsed = new Date() - start;
} }
var usec = (elapsed * 1000) / n; if (data != null) {
data.runs += n;
data.elapsed += elapsed;
}
}
if (data == null) {
// Measure the benchmark once for warm up and throw the result
// away. Return a fresh data object.
Measure(null);
return { runs: 0, elapsed: 0 };
} else {
Measure(data);
// If we've run too few iterations, we continue for another second.
if (data.runs < 32) return data;
var usec = (data.elapsed * 1000) / data.runs;
this.NotifyStep(new BenchmarkResult(benchmark, usec)); this.NotifyStep(new BenchmarkResult(benchmark, usec));
return null;
}
} }
@ -220,6 +238,7 @@ BenchmarkSuite.prototype.RunStep = function(runner) {
var length = this.benchmarks.length; var length = this.benchmarks.length;
var index = 0; var index = 0;
var suite = this; var suite = this;
var data;
// Run the setup, the actual benchmark, and the tear down in three // Run the setup, the actual benchmark, and the tear down in three
// separate steps to allow the framework to yield between any of the // separate steps to allow the framework to yield between any of the
@ -241,12 +260,13 @@ BenchmarkSuite.prototype.RunStep = function(runner) {
function RunNextBenchmark() { function RunNextBenchmark() {
try { try {
suite.RunSingleBenchmark(suite.benchmarks[index]); data = suite.RunSingleBenchmark(suite.benchmarks[index], data);
} catch (e) { } catch (e) {
suite.NotifyError(e); suite.NotifyError(e);
return null; return null;
} }
return RunNextTearDown; // If data is null, we're done with this benchmark.
return (data == null) ? RunNextTearDown : RunNextBenchmark();
} }
function RunNextTearDown() { function RunNextTearDown() {

2
deps/v8/benchmarks/crypto.js

@ -31,7 +31,7 @@
// The code has been adapted for use as a benchmark by Google. // The code has been adapted for use as a benchmark by Google.
var Crypto = new BenchmarkSuite('Crypto', 203037, [ var Crypto = new BenchmarkSuite('Crypto', 110465, [
new Benchmark("Encrypt", encrypt), new Benchmark("Encrypt", encrypt),
new Benchmark("Decrypt", decrypt) new Benchmark("Decrypt", decrypt)
]); ]);

8
deps/v8/benchmarks/deltablue.js

@ -23,13 +23,13 @@
// more like a JavaScript program. // more like a JavaScript program.
var DeltaBlue = new BenchmarkSuite('DeltaBlue', 71104, [ var DeltaBlue = new BenchmarkSuite('DeltaBlue', 30282, [
new Benchmark('DeltaBlue', deltaBlue) new Benchmark('DeltaBlue', deltaBlue)
]); ]);
/** /**
* A JavaScript implementation of the DeltaBlue constrain-solving * A JavaScript implementation of the DeltaBlue constraint-solving
* algorithm, as described in: * algorithm, as described in:
* *
* "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver" * "The DeltaBlue Algorithm: An Incremental Constraint Hierarchy Solver"
@ -349,13 +349,13 @@ function BinaryConstraint(var1, var2, strength) {
BinaryConstraint.inheritsFrom(Constraint); BinaryConstraint.inheritsFrom(Constraint);
/** /**
* Decides if this constratint can be satisfied and which way it * Decides if this constraint can be satisfied and which way it
* should flow based on the relative strength of the variables related, * should flow based on the relative strength of the variables related,
* and record that decision. * and record that decision.
*/ */
BinaryConstraint.prototype.chooseMethod = function (mark) { BinaryConstraint.prototype.chooseMethod = function (mark) {
if (this.v1.mark == mark) { if (this.v1.mark == mark) {
this.direction = (this.v1.mark != mark && Strength.stronger(this.strength, this.v2.walkStrength)) this.direction = (this.v2.mark != mark && Strength.stronger(this.strength, this.v2.walkStrength))
? Direction.FORWARD ? Direction.FORWARD
: Direction.NONE; : Direction.NONE;
} }

2
deps/v8/benchmarks/earley-boyer.js

@ -1,7 +1,7 @@
// This file is automatically generated by scheme2js, except for the // This file is automatically generated by scheme2js, except for the
// benchmark harness code at the beginning and end of the file. // benchmark harness code at the beginning and end of the file.
var EarleyBoyer = new BenchmarkSuite('EarleyBoyer', 765819, [ var EarleyBoyer = new BenchmarkSuite('EarleyBoyer', 280581, [
new Benchmark("Earley", function () { BgL_earleyzd2benchmarkzd2(); }), new Benchmark("Earley", function () { BgL_earleyzd2benchmarkzd2(); }),
new Benchmark("Boyer", function () { BgL_nboyerzd2benchmarkzd2(); }) new Benchmark("Boyer", function () { BgL_nboyerzd2benchmarkzd2(); })
]); ]);

2
deps/v8/benchmarks/raytrace.js

@ -8,7 +8,7 @@
// untouched. This file also contains a copy of parts of the Prototype // untouched. This file also contains a copy of parts of the Prototype
// JavaScript framework which is used by the ray tracer. // JavaScript framework which is used by the ray tracer.
var RayTrace = new BenchmarkSuite('RayTrace', 932666, [ var RayTrace = new BenchmarkSuite('RayTrace', 533115, [
new Benchmark('RayTrace', renderScene) new Benchmark('RayTrace', renderScene)
]); ]);

2
deps/v8/benchmarks/regexp.js

@ -35,7 +35,7 @@
// letters in the data are encoded using ROT13 in a way that does not // letters in the data are encoded using ROT13 in a way that does not
// affect how the regexps match their input. // affect how the regexps match their input.
var RegRxp = new BenchmarkSuite('RegExp', 995230, [ var RegRxp = new BenchmarkSuite('RegExp', 601250, [
new Benchmark("RegExp", runRegExpBenchmark) new Benchmark("RegExp", runRegExpBenchmark)
]); ]);

13
deps/v8/benchmarks/revisions.html

@ -22,10 +22,15 @@ the benchmark suite.
<div class="subtitle"><h3>Version 6 (<a href="http://v8.googlecode.com/svn/data/benchmarks/v6/run.html">link</a>)</h3></div> <div class="subtitle"><h3>Version 6 (<a href="http://v8.googlecode.com/svn/data/benchmarks/v6/run.html">link</a>)</h3></div>
<p>Removed dead code from the RayTrace benchmark and changed the Splay <p>Removed dead code from the RayTrace benchmark and fixed a couple of
benchmark to avoid converting the same numeric key to a string over typos in the DeltaBlue implementation. Changed the Splay benchmark to
and over again. avoid converting the same numeric key to a string over and over again
</p> and to avoid inserting and removing the same element repeatedly thus
increasing pressure on the memory subsystem.</p>
<p>Furthermore, the benchmark runner was changed to run the benchmarks
for at least a few times to stabilize the reported numbers on slower
machines.</p>
<div class="subtitle"><h3>Version 5 (<a href="http://v8.googlecode.com/svn/data/benchmarks/v5/run.html">link</a>)</h3></div> <div class="subtitle"><h3>Version 5 (<a href="http://v8.googlecode.com/svn/data/benchmarks/v5/run.html">link</a>)</h3></div>

2
deps/v8/benchmarks/richards.js

@ -35,7 +35,7 @@
// Martin Richards. // Martin Richards.
var Richards = new BenchmarkSuite('Richards', 34886, [ var Richards = new BenchmarkSuite('Richards', 20687, [
new Benchmark("Richards", runRichards) new Benchmark("Richards", runRichards)
]); ]);

2
deps/v8/benchmarks/run.html

@ -116,7 +116,7 @@ higher scores means better performance: <em>Bigger is better!</em>
<li><b>RegExp</b><br>Regular expression benchmark generated by extracting regular expression operations from 50 of the most popular web pages <li><b>RegExp</b><br>Regular expression benchmark generated by extracting regular expression operations from 50 of the most popular web pages
(<i>1614 lines</i>). (<i>1614 lines</i>).
</li> </li>
<li><b>Splay</b><br>Data manipulation benchmark that deals with splay trees and exercises the automatic memory management subsystem (<i>379 lines</i>).</li> <li><b>Splay</b><br>Data manipulation benchmark that deals with splay trees and exercises the automatic memory management subsystem (<i>394 lines</i>).</li>
</ul> </ul>
<p> <p>

21
deps/v8/benchmarks/splay.js

@ -33,7 +33,7 @@
// also has to deal with a lot of changes to the large tree object // also has to deal with a lot of changes to the large tree object
// graph. // graph.
var Splay = new BenchmarkSuite('Splay', 126125, [ var Splay = new BenchmarkSuite('Splay', 21915, [
new Benchmark("Splay", SplayRun, SplaySetup, SplayTearDown) new Benchmark("Splay", SplayRun, SplaySetup, SplayTearDown)
]); ]);
@ -230,9 +230,24 @@ SplayTree.prototype.find = function(key) {
}; };
/**
* @return {SplayTree.Node} Node having the maximum key value.
*/
SplayTree.prototype.findMax = function(opt_startNode) {
if (this.isEmpty()) {
return null;
}
var current = opt_startNode || this.root_;
while (current.right) {
current = current.right;
}
return current;
};
/** /**
* @return {SplayTree.Node} Node having the maximum key value that * @return {SplayTree.Node} Node having the maximum key value that
* is less or equal to the specified key value. * is less than the specified key value.
*/ */
SplayTree.prototype.findGreatestLessThan = function(key) { SplayTree.prototype.findGreatestLessThan = function(key) {
if (this.isEmpty()) { if (this.isEmpty()) {
@ -243,7 +258,7 @@ SplayTree.prototype.findGreatestLessThan = function(key) {
this.splay_(key); this.splay_(key);
// Now the result is either the root node or the greatest node in // Now the result is either the root node or the greatest node in
// the left subtree. // the left subtree.
if (this.root_.key <= key) { if (this.root_.key < key) {
return this.root_; return this.root_;
} else if (this.root_.left) { } else if (this.root_.left) {
return this.findMax(this.root_.left); return this.findMax(this.root_.left);

12
deps/v8/src/arm/assembler-arm.cc

@ -2112,6 +2112,18 @@ void Assembler::vmrs(Register dst, Condition cond) {
} }
void Assembler::vsqrt(const DwVfpRegister dst,
const DwVfpRegister src,
const Condition cond) {
// cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) |
// Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0)
ASSERT(CpuFeatures::IsEnabled(VFP3));
emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 |
dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code());
}
// Pseudo instructions. // Pseudo instructions.
void Assembler::nop(int type) { void Assembler::nop(int type) {
// This is mov rx, rx. // This is mov rx, rx.

3
deps/v8/src/arm/assembler-arm.h

@ -988,6 +988,9 @@ class Assembler : public Malloced {
const Condition cond = al); const Condition cond = al);
void vmrs(const Register dst, void vmrs(const Register dst,
const Condition cond = al); const Condition cond = al);
void vsqrt(const DwVfpRegister dst,
const DwVfpRegister src,
const Condition cond = al);
// Pseudo instructions // Pseudo instructions
void nop(int type = 0); void nop(int type = 0);

371
deps/v8/src/arm/codegen-arm.cc

@ -4279,22 +4279,147 @@ void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
} }
// Generates the Math.pow method - currently just calls runtime. // Generates the Math.pow method.
void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
ASSERT(args->length() == 2); ASSERT(args->length() == 2);
Load(args->at(0)); Load(args->at(0));
Load(args->at(1)); Load(args->at(1));
if (!CpuFeatures::IsSupported(VFP3)) {
frame_->CallRuntime(Runtime::kMath_pow, 2); frame_->CallRuntime(Runtime::kMath_pow, 2);
frame_->EmitPush(r0); frame_->EmitPush(r0);
} else {
CpuFeatures::Scope scope(VFP3);
JumpTarget runtime, done;
Label not_minus_half, allocate_return;
Register scratch1 = VirtualFrame::scratch0();
Register scratch2 = VirtualFrame::scratch1();
// Get base and exponent to registers.
Register exponent = frame_->PopToRegister();
Register base = frame_->PopToRegister(exponent);
// Set the frame for the runtime jump target. The code below jumps to the
// jump target label so the frame needs to be established before that.
ASSERT(runtime.entry_frame() == NULL);
runtime.set_entry_frame(frame_);
__ BranchOnSmi(exponent, runtime.entry_label());
// Special handling of raising to the power of -0.5 and 0.5. First check
// that the value is a heap number and that the lower bits (which for both
// values are zero).
Register heap_number_map = r6;
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
__ ldr(scratch1, FieldMemOperand(exponent, HeapObject::kMapOffset));
__ ldr(scratch2, FieldMemOperand(exponent, HeapNumber::kMantissaOffset));
__ cmp(scratch1, heap_number_map);
runtime.Branch(ne);
__ tst(scratch2, scratch2);
runtime.Branch(ne);
// Load the e
__ ldr(scratch1, FieldMemOperand(exponent, HeapNumber::kExponentOffset));
// Compare exponent with -0.5.
__ cmp(scratch1, Operand(0xbfe00000));
__ b(ne, &not_minus_half);
// Get the double value from the base into vfp register d0.
__ ObjectToDoubleVFPRegister(base, d0,
scratch1, scratch2, heap_number_map, s0,
runtime.entry_label(),
AVOID_NANS_AND_INFINITIES);
// Load 1.0 into d2.
__ mov(scratch2, Operand(0x3ff00000));
__ mov(scratch1, Operand(0));
__ vmov(d2, scratch1, scratch2);
// Calculate the reciprocal of the square root. 1/sqrt(x) = sqrt(1/x).
__ vdiv(d0, d2, d0);
__ vsqrt(d0, d0);
__ b(&allocate_return);
__ bind(&not_minus_half);
// Compare exponent with 0.5.
__ cmp(scratch1, Operand(0x3fe00000));
runtime.Branch(ne);
// Get the double value from the base into vfp register d0.
__ ObjectToDoubleVFPRegister(base, d0,
scratch1, scratch2, heap_number_map, s0,
runtime.entry_label(),
AVOID_NANS_AND_INFINITIES);
__ vsqrt(d0, d0);
__ bind(&allocate_return);
__ AllocateHeapNumberWithValue(
base, d0, scratch1, scratch2, heap_number_map, runtime.entry_label());
done.Jump();
runtime.Bind();
// Push back the arguments again for the runtime call.
frame_->EmitPush(base);
frame_->EmitPush(exponent);
frame_->CallRuntime(Runtime::kMath_pow, 2);
__ Move(base, r0);
done.Bind();
frame_->EmitPush(base);
}
} }
// Generates the Math.sqrt method - currently just calls runtime. // Generates the Math.sqrt method.
void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
ASSERT(args->length() == 1); ASSERT(args->length() == 1);
Load(args->at(0)); Load(args->at(0));
if (!CpuFeatures::IsSupported(VFP3)) {
frame_->CallRuntime(Runtime::kMath_sqrt, 1); frame_->CallRuntime(Runtime::kMath_sqrt, 1);
frame_->EmitPush(r0); frame_->EmitPush(r0);
} else {
CpuFeatures::Scope scope(VFP3);
JumpTarget runtime, done;
Register scratch1 = VirtualFrame::scratch0();
Register scratch2 = VirtualFrame::scratch1();
// Get the value from the frame.
Register tos = frame_->PopToRegister();
// Set the frame for the runtime jump target. The code below jumps to the
// jump target label so the frame needs to be established before that.
ASSERT(runtime.entry_frame() == NULL);
runtime.set_entry_frame(frame_);
Register heap_number_map = r6;
__ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
// Get the double value from the heap number into vfp register d0.
__ ObjectToDoubleVFPRegister(tos, d0,
scratch1, scratch2, heap_number_map, s0,
runtime.entry_label());
// Calculate the square root of d0 and place result in a heap number object.
__ vsqrt(d0, d0);
__ AllocateHeapNumberWithValue(
tos, d0, scratch1, scratch2, heap_number_map, runtime.entry_label());
done.Jump();
runtime.Bind();
// Push back the argument again for the runtime call.
frame_->EmitPush(tos);
frame_->CallRuntime(Runtime::kMath_sqrt, 1);
__ Move(tos, r0);
done.Bind();
frame_->EmitPush(tos);
}
} }
@ -6257,7 +6382,6 @@ bool CodeGenerator::HasValidEntryRegisters() { return true; }
#undef __ #undef __
#define __ ACCESS_MASM(masm) #define __ ACCESS_MASM(masm)
Handle<String> Reference::GetName() { Handle<String> Reference::GetName() {
ASSERT(type_ == NAMED); ASSERT(type_ == NAMED);
Property* property = expression_->AsProperty(); Property* property = expression_->AsProperty();
@ -6621,7 +6745,7 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) {
__ bind(&not_special); __ bind(&not_special);
// Count leading zeros. Uses mantissa for a scratch register on pre-ARM5. // Count leading zeros. Uses mantissa for a scratch register on pre-ARM5.
// Gets the wrong answer for 0, but we already checked for that case above. // Gets the wrong answer for 0, but we already checked for that case above.
__ CountLeadingZeros(source_, mantissa, zeros_); __ CountLeadingZeros(zeros_, source_, mantissa);
// Compute exponent and or it into the exponent register. // Compute exponent and or it into the exponent register.
// We use mantissa as a scratch register here. Use a fudge factor to // We use mantissa as a scratch register here. Use a fudge factor to
// divide the constant 31 + HeapNumber::kExponentBias, 0x41d, into two parts // divide the constant 31 + HeapNumber::kExponentBias, 0x41d, into two parts
@ -7350,7 +7474,7 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
// If we have floating point hardware, inline ADD, SUB, MUL, and DIV, // If we have floating point hardware, inline ADD, SUB, MUL, and DIV,
// using registers d7 and d6 for the double values. // using registers d7 and d6 for the double values.
if (use_fp_registers) { if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
__ mov(r7, Operand(rhs, ASR, kSmiTagSize)); __ mov(r7, Operand(rhs, ASR, kSmiTagSize));
__ vmov(s15, r7); __ vmov(s15, r7);
@ -7358,8 +7482,12 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
__ mov(r7, Operand(lhs, ASR, kSmiTagSize)); __ mov(r7, Operand(lhs, ASR, kSmiTagSize));
__ vmov(s13, r7); __ vmov(s13, r7);
__ vcvt_f64_s32(d6, s13); __ vcvt_f64_s32(d6, s13);
if (!use_fp_registers) {
__ vmov(r2, r3, d7);
__ vmov(r0, r1, d6);
}
} else { } else {
// Write Smi from rhs to r3 and r2 in double format. r3 is scratch. // Write Smi from rhs to r3 and r2 in double format. r9 is scratch.
__ mov(r7, Operand(rhs)); __ mov(r7, Operand(rhs));
ConvertToDoubleStub stub1(r3, r2, r7, r9); ConvertToDoubleStub stub1(r3, r2, r7, r9);
__ push(lr); __ push(lr);
@ -7434,12 +7562,15 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
__ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow); __ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow);
} }
if (use_fp_registers) { if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
// Convert smi in r0 to double in d7. // Convert smi in r0 to double in d7.
__ mov(r7, Operand(r0, ASR, kSmiTagSize)); __ mov(r7, Operand(r0, ASR, kSmiTagSize));
__ vmov(s15, r7); __ vmov(s15, r7);
__ vcvt_f64_s32(d7, s15); __ vcvt_f64_s32(d7, s15);
if (!use_fp_registers) {
__ vmov(r2, r3, d7);
}
} else { } else {
// Write Smi from r0 to r3 and r2 in double format. // Write Smi from r0 to r3 and r2 in double format.
__ mov(r7, Operand(r0)); __ mov(r7, Operand(r0));
@ -7490,12 +7621,15 @@ void GenericBinaryOpStub::HandleBinaryOpSlowCases(
__ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow); __ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow);
} }
if (use_fp_registers) { if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
// Convert smi in r1 to double in d6. // Convert smi in r1 to double in d6.
__ mov(r7, Operand(r1, ASR, kSmiTagSize)); __ mov(r7, Operand(r1, ASR, kSmiTagSize));
__ vmov(s13, r7); __ vmov(s13, r7);
__ vcvt_f64_s32(d6, s13); __ vcvt_f64_s32(d6, s13);
if (!use_fp_registers) {
__ vmov(r0, r1, d6);
}
} else { } else {
// Write Smi from r1 to r1 and r0 in double format. // Write Smi from r1 to r1 and r0 in double format.
__ mov(r7, Operand(r1)); __ mov(r7, Operand(r1));
@ -7942,6 +8076,173 @@ static void MultiplyByKnownInt2(
} }
// This uses versions of the sum-of-digits-to-see-if-a-number-is-divisible-by-3
// trick. See http://en.wikipedia.org/wiki/Divisibility_rule
// Takes the sum of the digits base (mask + 1) repeatedly until we have a
// number from 0 to mask. On exit the 'eq' condition flags are set if the
// answer is exactly the mask.
void IntegerModStub::DigitSum(MacroAssembler* masm,
Register lhs,
int mask,
int shift,
Label* entry) {
ASSERT(mask > 0);
ASSERT(mask <= 0xff); // This ensures we don't need ip to use it.
Label loop;
__ bind(&loop);
__ and_(ip, lhs, Operand(mask));
__ add(lhs, ip, Operand(lhs, LSR, shift));
__ bind(entry);
__ cmp(lhs, Operand(mask));
__ b(gt, &loop);
}
void IntegerModStub::DigitSum(MacroAssembler* masm,
Register lhs,
Register scratch,
int mask,
int shift1,
int shift2,
Label* entry) {
ASSERT(mask > 0);
ASSERT(mask <= 0xff); // This ensures we don't need ip to use it.
Label loop;
__ bind(&loop);
__ bic(scratch, lhs, Operand(mask));
__ and_(ip, lhs, Operand(mask));
__ add(lhs, ip, Operand(lhs, LSR, shift1));
__ add(lhs, lhs, Operand(scratch, LSR, shift2));
__ bind(entry);
__ cmp(lhs, Operand(mask));
__ b(gt, &loop);
}
// Splits the number into two halves (bottom half has shift bits). The top
// half is subtracted from the bottom half. If the result is negative then
// rhs is added.
void IntegerModStub::ModGetInRangeBySubtraction(MacroAssembler* masm,
Register lhs,
int shift,
int rhs) {
int mask = (1 << shift) - 1;
__ and_(ip, lhs, Operand(mask));
__ sub(lhs, ip, Operand(lhs, LSR, shift), SetCC);
__ add(lhs, lhs, Operand(rhs), LeaveCC, mi);
}
void IntegerModStub::ModReduce(MacroAssembler* masm,
Register lhs,
int max,
int denominator) {
int limit = denominator;
while (limit * 2 <= max) limit *= 2;
while (limit >= denominator) {
__ cmp(lhs, Operand(limit));
__ sub(lhs, lhs, Operand(limit), LeaveCC, ge);
limit >>= 1;
}
}
void IntegerModStub::ModAnswer(MacroAssembler* masm,
Register result,
Register shift_distance,
Register mask_bits,
Register sum_of_digits) {
__ add(result, mask_bits, Operand(sum_of_digits, LSL, shift_distance));
__ Ret();
}
// See comment for class.
void IntegerModStub::Generate(MacroAssembler* masm) {
__ mov(lhs_, Operand(lhs_, LSR, shift_distance_));
__ bic(odd_number_, odd_number_, Operand(1));
__ mov(odd_number_, Operand(odd_number_, LSL, 1));
// We now have (odd_number_ - 1) * 2 in the register.
// Build a switch out of branches instead of data because it avoids
// having to teach the assembler about intra-code-object pointers
// that are not in relative branch instructions.
Label mod3, mod5, mod7, mod9, mod11, mod13, mod15, mod17, mod19;
Label mod21, mod23, mod25;
{ Assembler::BlockConstPoolScope block_const_pool(masm);
__ add(pc, pc, Operand(odd_number_));
// When you read pc it is always 8 ahead, but when you write it you always
// write the actual value. So we put in two nops to take up the slack.
__ nop();
__ nop();
__ b(&mod3);
__ b(&mod5);
__ b(&mod7);
__ b(&mod9);
__ b(&mod11);
__ b(&mod13);
__ b(&mod15);
__ b(&mod17);
__ b(&mod19);
__ b(&mod21);
__ b(&mod23);
__ b(&mod25);
}
// For each denominator we find a multiple that is almost only ones
// when expressed in binary. Then we do the sum-of-digits trick for
// that number. If the multiple is not 1 then we have to do a little
// more work afterwards to get the answer into the 0-denominator-1
// range.
DigitSum(masm, lhs_, 3, 2, &mod3); // 3 = b11.
__ sub(lhs_, lhs_, Operand(3), LeaveCC, eq);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, 0xf, 4, &mod5); // 5 * 3 = b1111.
ModGetInRangeBySubtraction(masm, lhs_, 2, 5);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, 7, 3, &mod7); // 7 = b111.
__ sub(lhs_, lhs_, Operand(7), LeaveCC, eq);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, 0x3f, 6, &mod9); // 7 * 9 = b111111.
ModGetInRangeBySubtraction(masm, lhs_, 3, 9);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, r5, 0x3f, 6, 3, &mod11); // 5 * 11 = b110111.
ModReduce(masm, lhs_, 0x3f, 11);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, r5, 0xff, 8, 5, &mod13); // 19 * 13 = b11110111.
ModReduce(masm, lhs_, 0xff, 13);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, 0xf, 4, &mod15); // 15 = b1111.
__ sub(lhs_, lhs_, Operand(15), LeaveCC, eq);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, 0xff, 8, &mod17); // 15 * 17 = b11111111.
ModGetInRangeBySubtraction(masm, lhs_, 4, 17);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, r5, 0xff, 8, 5, &mod19); // 13 * 19 = b11110111.
ModReduce(masm, lhs_, 0xff, 19);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, 0x3f, 6, &mod21); // 3 * 21 = b111111.
ModReduce(masm, lhs_, 0x3f, 21);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, r5, 0xff, 8, 7, &mod23); // 11 * 23 = b11111101.
ModReduce(masm, lhs_, 0xff, 23);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
DigitSum(masm, lhs_, r5, 0x7f, 7, 6, &mod25); // 5 * 25 = b1111101.
ModReduce(masm, lhs_, 0x7f, 25);
ModAnswer(masm, result_, shift_distance_, mask_bits_, lhs_);
}
const char* GenericBinaryOpStub::GetName() { const char* GenericBinaryOpStub::GetName() {
if (name_ != NULL) return name_; if (name_ != NULL) return name_;
const int len = 100; const int len = 100;
@ -8069,7 +8370,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
case Token::MOD: { case Token::MOD: {
Label not_smi; Label not_smi;
if (ShouldGenerateSmiCode() && specialized_on_rhs_) { if (ShouldGenerateSmiCode() && specialized_on_rhs_) {
Label smi_is_unsuitable; Label lhs_is_unsuitable;
__ BranchOnNotSmi(lhs, &not_smi); __ BranchOnNotSmi(lhs, &not_smi);
if (IsPowerOf2(constant_rhs_)) { if (IsPowerOf2(constant_rhs_)) {
if (op_ == Token::MOD) { if (op_ == Token::MOD) {
@ -8090,14 +8391,14 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
__ eor(rhs, rhs, Operand(0x80000000u), SetCC); __ eor(rhs, rhs, Operand(0x80000000u), SetCC);
// Next two instructions are conditional on the answer being -0. // Next two instructions are conditional on the answer being -0.
__ mov(rhs, Operand(Smi::FromInt(constant_rhs_)), LeaveCC, eq); __ mov(rhs, Operand(Smi::FromInt(constant_rhs_)), LeaveCC, eq);
__ b(eq, &smi_is_unsuitable); __ b(eq, &lhs_is_unsuitable);
// We need to subtract the dividend. Eg. -3 % 4 == -3. // We need to subtract the dividend. Eg. -3 % 4 == -3.
__ sub(result, rhs, Operand(Smi::FromInt(constant_rhs_))); __ sub(result, rhs, Operand(Smi::FromInt(constant_rhs_)));
} else { } else {
ASSERT(op_ == Token::DIV); ASSERT(op_ == Token::DIV);
__ tst(lhs, __ tst(lhs,
Operand(0x80000000u | ((constant_rhs_ << kSmiTagSize) - 1))); Operand(0x80000000u | ((constant_rhs_ << kSmiTagSize) - 1)));
__ b(ne, &smi_is_unsuitable); // Go slow on negative or remainder. __ b(ne, &lhs_is_unsuitable); // Go slow on negative or remainder.
int shift = 0; int shift = 0;
int d = constant_rhs_; int d = constant_rhs_;
while ((d & 1) == 0) { while ((d & 1) == 0) {
@ -8110,7 +8411,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
} else { } else {
// Not a power of 2. // Not a power of 2.
__ tst(lhs, Operand(0x80000000u)); __ tst(lhs, Operand(0x80000000u));
__ b(ne, &smi_is_unsuitable); __ b(ne, &lhs_is_unsuitable);
// Find a fixed point reciprocal of the divisor so we can divide by // Find a fixed point reciprocal of the divisor so we can divide by
// multiplying. // multiplying.
double divisor = 1.0 / constant_rhs_; double divisor = 1.0 / constant_rhs_;
@ -8145,7 +8446,7 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
// (lhs / rhs) where / indicates integer division. // (lhs / rhs) where / indicates integer division.
if (op_ == Token::DIV) { if (op_ == Token::DIV) {
__ cmp(lhs, Operand(scratch, LSL, required_scratch_shift)); __ cmp(lhs, Operand(scratch, LSL, required_scratch_shift));
__ b(ne, &smi_is_unsuitable); // There was a remainder. __ b(ne, &lhs_is_unsuitable); // There was a remainder.
__ mov(result, Operand(scratch2, LSL, kSmiTagSize)); __ mov(result, Operand(scratch2, LSL, kSmiTagSize));
} else { } else {
ASSERT(op_ == Token::MOD); ASSERT(op_ == Token::MOD);
@ -8153,14 +8454,21 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
} }
} }
__ Ret(); __ Ret();
__ bind(&smi_is_unsuitable); __ bind(&lhs_is_unsuitable);
} else if (op_ == Token::MOD && } else if (op_ == Token::MOD &&
runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS &&
runtime_operands_type_ != BinaryOpIC::STRINGS) { runtime_operands_type_ != BinaryOpIC::STRINGS) {
// Do generate a bit of smi code for modulus even though the default for // Do generate a bit of smi code for modulus even though the default for
// modulus is not to do it, but as the ARM processor has no coprocessor // modulus is not to do it, but as the ARM processor has no coprocessor
// support for modulus checking for smis makes sense. // support for modulus checking for smis makes sense. We can handle
// 1 to 25 times any power of 2. This covers over half the numbers from
// 1 to 100 including all of the first 25. (Actually the constants < 10
// are handled above by reciprocal multiplication. We only get here for
// those cases if the right hand side is not a constant or for cases
// like 192 which is 3*2^6 and ends up in the 3 case in the integer mod
// stub.)
Label slow; Label slow;
Label not_power_of_2;
ASSERT(!ShouldGenerateSmiCode()); ASSERT(!ShouldGenerateSmiCode());
ASSERT(kSmiTag == 0); // Adjust code below. ASSERT(kSmiTag == 0); // Adjust code below.
// Check for two positive smis. // Check for two positive smis.
@ -8168,13 +8476,42 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
__ tst(smi_test_reg, Operand(0x80000000u | kSmiTagMask)); __ tst(smi_test_reg, Operand(0x80000000u | kSmiTagMask));
__ b(ne, &slow); __ b(ne, &slow);
// Check that rhs is a power of two and not zero. // Check that rhs is a power of two and not zero.
Register mask_bits = r3;
__ sub(scratch, rhs, Operand(1), SetCC); __ sub(scratch, rhs, Operand(1), SetCC);
__ b(mi, &slow); __ b(mi, &slow);
__ tst(rhs, scratch); __ and_(mask_bits, rhs, Operand(scratch), SetCC);
__ b(ne, &slow); __ b(ne, &not_power_of_2);
// Calculate power of two modulus. // Calculate power of two modulus.
__ and_(result, lhs, Operand(scratch)); __ and_(result, lhs, Operand(scratch));
__ Ret(); __ Ret();
__ bind(&not_power_of_2);
__ eor(scratch, scratch, Operand(mask_bits));
// At least two bits are set in the modulus. The high one(s) are in
// mask_bits and the low one is scratch + 1.
__ and_(mask_bits, scratch, Operand(lhs));
Register shift_distance = scratch;
scratch = no_reg;
// The rhs consists of a power of 2 multiplied by some odd number.
// The power-of-2 part we handle by putting the corresponding bits
// from the lhs in the mask_bits register, and the power in the
// shift_distance register. Shift distance is never 0 due to Smi
// tagging.
__ CountLeadingZeros(r4, shift_distance, shift_distance);
__ rsb(shift_distance, r4, Operand(32));
// Now we need to find out what the odd number is. The last bit is
// always 1.
Register odd_number = r4;
__ mov(odd_number, Operand(rhs, LSR, shift_distance));
__ cmp(odd_number, Operand(25));
__ b(gt, &slow);
IntegerModStub stub(
result, shift_distance, odd_number, mask_bits, lhs, r5);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); // Tail call.
__ bind(&slow); __ bind(&slow);
} }
HandleBinaryOpSlowCases( HandleBinaryOpSlowCases(

96
deps/v8/src/arm/codegen-arm.h

@ -881,6 +881,102 @@ class StringCompareStub: public CodeStub {
}; };
// This stub can do a fast mod operation without using fp.
// It is tail called from the GenericBinaryOpStub and it always
// returns an answer. It never causes GC so it doesn't need a real frame.
//
// The inputs are always positive Smis. This is never called
// where the denominator is a power of 2. We handle that separately.
//
// If we consider the denominator as an odd number multiplied by a power of 2,
// then:
// * The exponent (power of 2) is in the shift_distance register.
// * The odd number is in the odd_number register. It is always in the range
// of 3 to 25.
// * The bits from the numerator that are to be copied to the answer (there are
// shift_distance of them) are in the mask_bits register.
// * The other bits of the numerator have been shifted down and are in the lhs
// register.
class IntegerModStub : public CodeStub {
public:
IntegerModStub(Register result,
Register shift_distance,
Register odd_number,
Register mask_bits,
Register lhs,
Register scratch)
: result_(result),
shift_distance_(shift_distance),
odd_number_(odd_number),
mask_bits_(mask_bits),
lhs_(lhs),
scratch_(scratch) {
// We don't code these in the minor key, so they should always be the same.
// We don't really want to fix that since this stub is rather large and we
// don't want many copies of it.
ASSERT(shift_distance_.is(r9));
ASSERT(odd_number_.is(r4));
ASSERT(mask_bits_.is(r3));
ASSERT(scratch_.is(r5));
}
private:
Register result_;
Register shift_distance_;
Register odd_number_;
Register mask_bits_;
Register lhs_;
Register scratch_;
// Minor key encoding in 16 bits.
class ResultRegisterBits: public BitField<int, 0, 4> {};
class LhsRegisterBits: public BitField<int, 4, 4> {};
Major MajorKey() { return IntegerMod; }
int MinorKey() {
// Encode the parameters in a unique 16 bit value.
return ResultRegisterBits::encode(result_.code())
| LhsRegisterBits::encode(lhs_.code());
}
void Generate(MacroAssembler* masm);
const char* GetName() { return "IntegerModStub"; }
// Utility functions.
void DigitSum(MacroAssembler* masm,
Register lhs,
int mask,
int shift,
Label* entry);
void DigitSum(MacroAssembler* masm,
Register lhs,
Register scratch,
int mask,
int shift1,
int shift2,
Label* entry);
void ModGetInRangeBySubtraction(MacroAssembler* masm,
Register lhs,
int shift,
int rhs);
void ModReduce(MacroAssembler* masm,
Register lhs,
int max,
int denominator);
void ModAnswer(MacroAssembler* masm,
Register result,
Register shift_distance,
Register mask_bits,
Register sum_of_digits);
#ifdef DEBUG
void Print() { PrintF("IntegerModStub\n"); }
#endif
};
// This stub can convert a signed int32 to a heap number (double). It does // This stub can convert a signed int32 to a heap number (double). It does
// not work for int32s that are in Smi range! No GC occurs during this stub // not work for int32s that are in Smi range! No GC occurs during this stub
// so you don't have to set up the frame. // so you don't have to set up the frame.

2
deps/v8/src/arm/constants-arm.cc

@ -85,7 +85,7 @@ const char* VFPRegisters::names_[kNumVFPRegisters] = {
const char* VFPRegisters::Name(int reg, bool is_double) { const char* VFPRegisters::Name(int reg, bool is_double) {
ASSERT((0 <= reg) && (reg < kNumVFPRegisters)); ASSERT((0 <= reg) && (reg < kNumVFPRegisters));
return names_[reg + is_double ? kNumVFPSingleRegisters : 0]; return names_[reg + (is_double ? kNumVFPSingleRegisters : 0)];
} }

5
deps/v8/src/arm/disasm-arm.cc

@ -1038,7 +1038,8 @@ void Decoder::DecodeUnconditional(Instr* instr) {
// Dd = vmul(Dn, Dm) // Dd = vmul(Dn, Dm)
// Dd = vdiv(Dn, Dm) // Dd = vdiv(Dn, Dm)
// vcmp(Dd, Dm) // vcmp(Dd, Dm)
// VMRS // vmrs
// Dd = vsqrt(Dm)
void Decoder::DecodeTypeVFP(Instr* instr) { void Decoder::DecodeTypeVFP(Instr* instr) {
ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
ASSERT(instr->Bits(11, 9) == 0x5); ASSERT(instr->Bits(11, 9) == 0x5);
@ -1056,6 +1057,8 @@ void Decoder::DecodeTypeVFP(Instr* instr) {
} else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) && } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
(instr->Opc3Field() & 0x1)) { (instr->Opc3Field() & 0x1)) {
DecodeVCMP(instr); DecodeVCMP(instr);
} else if (((instr->Opc2Field() == 0x1)) && (instr->Opc3Field() == 0x3)) {
Format(instr, "vsqrt.f64'cond 'Dd, 'Dm");
} else { } else {
Unknown(instr); // Not used by V8. Unknown(instr); // Not used by V8.
} }

2
deps/v8/src/arm/ic-arm.cc

@ -1722,7 +1722,7 @@ static void ConvertIntToFloat(MacroAssembler* masm,
// Count leading zeros. // Count leading zeros.
// Gets the wrong answer for 0, but we already checked for that case above. // Gets the wrong answer for 0, but we already checked for that case above.
Register zeros = scratch2; Register zeros = scratch2;
__ CountLeadingZeros(ival, scratch1, zeros); __ CountLeadingZeros(zeros, ival, scratch1);
// Compute exponent and or it into the exponent register. // Compute exponent and or it into the exponent register.
__ rsb(scratch1, __ rsb(scratch1,

75
deps/v8/src/arm/macro-assembler-arm.cc

@ -1369,6 +1369,56 @@ void MacroAssembler::IntegerToDoubleConversionWithVFP3(Register inReg,
} }
void MacroAssembler::ObjectToDoubleVFPRegister(Register object,
DwVfpRegister result,
Register scratch1,
Register scratch2,
Register heap_number_map,
SwVfpRegister scratch3,
Label* not_number,
ObjectToDoubleFlags flags) {
Label done;
if ((flags & OBJECT_NOT_SMI) == 0) {
Label not_smi;
BranchOnNotSmi(object, &not_smi);
// Remove smi tag and convert to double.
mov(scratch1, Operand(object, ASR, kSmiTagSize));
vmov(scratch3, scratch1);
vcvt_f64_s32(result, scratch3);
b(&done);
bind(&not_smi);
}
// Check for heap number and load double value from it.
ldr(scratch1, FieldMemOperand(object, HeapObject::kMapOffset));
sub(scratch2, object, Operand(kHeapObjectTag));
cmp(scratch1, heap_number_map);
b(ne, not_number);
if ((flags & AVOID_NANS_AND_INFINITIES) != 0) {
// If exponent is all ones the number is either a NaN or +/-Infinity.
ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
Sbfx(scratch1,
scratch1,
HeapNumber::kExponentShift,
HeapNumber::kExponentBits);
// All-one value sign extend to -1.
cmp(scratch1, Operand(-1));
b(eq, not_number);
}
vldr(result, scratch2, HeapNumber::kValueOffset);
bind(&done);
}
void MacroAssembler::SmiToDoubleVFPRegister(Register smi,
DwVfpRegister value,
Register scratch1,
SwVfpRegister scratch2) {
mov(scratch1, Operand(smi, ASR, kSmiTagSize));
vmov(scratch2, scratch1);
vcvt_f64_s32(value, scratch2);
}
void MacroAssembler::GetLeastBitsFromSmi(Register dst, void MacroAssembler::GetLeastBitsFromSmi(Register dst,
Register src, Register src,
int num_least_bits) { int num_least_bits) {
@ -1686,14 +1736,31 @@ void MacroAssembler::AllocateHeapNumber(Register result,
} }
void MacroAssembler::CountLeadingZeros(Register source, void MacroAssembler::AllocateHeapNumberWithValue(Register result,
Register scratch, DwVfpRegister value,
Register zeros) { Register scratch1,
Register scratch2,
Register heap_number_map,
Label* gc_required) {
AllocateHeapNumber(result, scratch1, scratch2, heap_number_map, gc_required);
sub(scratch1, result, Operand(kHeapObjectTag));
vstr(value, scratch1, HeapNumber::kValueOffset);
}
void MacroAssembler::CountLeadingZeros(Register zeros, // Answer.
Register source, // Input.
Register scratch) {
ASSERT(!zeros.is(source) || !source.is(zeros));
ASSERT(!zeros.is(scratch));
ASSERT(!scratch.is(ip));
ASSERT(!source.is(ip));
ASSERT(!zeros.is(ip));
#ifdef CAN_USE_ARMV5_INSTRUCTIONS #ifdef CAN_USE_ARMV5_INSTRUCTIONS
clz(zeros, source); // This instruction is only supported after ARM5. clz(zeros, source); // This instruction is only supported after ARM5.
#else #else
mov(zeros, Operand(0)); mov(zeros, Operand(0));
mov(scratch, source); Move(scratch, source);
// Top 16. // Top 16.
tst(scratch, Operand(0xffff0000)); tst(scratch, Operand(0xffff0000));
add(zeros, zeros, Operand(16), LeaveCC, eq); add(zeros, zeros, Operand(16), LeaveCC, eq);

49
deps/v8/src/arm/macro-assembler-arm.h

@ -67,6 +67,17 @@ enum AllocationFlags {
}; };
// Flags used for the ObjectToDoubleVFPRegister function.
enum ObjectToDoubleFlags {
// No special flags.
NO_OBJECT_TO_DOUBLE_FLAGS = 0,
// Object is known to be a non smi.
OBJECT_NOT_SMI = 1 << 0,
// Don't load NaNs or infinities, branch to the non number case instead.
AVOID_NANS_AND_INFINITIES = 1 << 1
};
// MacroAssembler implements a collection of frequently used macros. // MacroAssembler implements a collection of frequently used macros.
class MacroAssembler: public Assembler { class MacroAssembler: public Assembler {
public: public:
@ -381,6 +392,13 @@ class MacroAssembler: public Assembler {
Register scratch2, Register scratch2,
Register heap_number_map, Register heap_number_map,
Label* gc_required); Label* gc_required);
void AllocateHeapNumberWithValue(Register result,
DwVfpRegister value,
Register scratch1,
Register scratch2,
Register heap_number_map,
Label* gc_required);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Support functions. // Support functions.
@ -469,12 +487,35 @@ class MacroAssembler: public Assembler {
Register outHighReg, Register outHighReg,
Register outLowReg); Register outLowReg);
// Load the value of a number object into a VFP double register. If the object
// is not a number a jump to the label not_number is performed and the VFP
// double register is unchanged.
void ObjectToDoubleVFPRegister(
Register object,
DwVfpRegister value,
Register scratch1,
Register scratch2,
Register heap_number_map,
SwVfpRegister scratch3,
Label* not_number,
ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS);
// Load the value of a smi object into a VFP double register. The register
// scratch1 can be the same register as smi in which case smi will hold the
// untagged value afterwards.
void SmiToDoubleVFPRegister(Register smi,
DwVfpRegister value,
Register scratch1,
SwVfpRegister scratch2);
// Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz
// instruction. On pre-ARM5 hardware this routine gives the wrong answer // instruction. On pre-ARM5 hardware this routine gives the wrong answer
// for 0 (31 instead of 32). // for 0 (31 instead of 32). Source and scratch can be the same in which case
void CountLeadingZeros(Register source, // the source is clobbered. Source and zeros can also be the same in which
Register scratch, // case scratch should be a different register.
Register zeros); void CountLeadingZeros(Register zeros,
Register source,
Register scratch);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Runtime calls // Runtime calls

9
deps/v8/src/arm/simulator-arm.cc

@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include <cstdarg> #include <cstdarg>
#include "v8.h" #include "v8.h"
@ -2262,7 +2263,8 @@ static int GlueRegCode(bool last_bit, int vm, int m) {
// Dd = vmul(Dn, Dm) // Dd = vmul(Dn, Dm)
// Dd = vdiv(Dn, Dm) // Dd = vdiv(Dn, Dm)
// vcmp(Dd, Dm) // vcmp(Dd, Dm)
// VMRS // vmrs
// Dd = vsqrt(Dm)
void Simulator::DecodeTypeVFP(Instr* instr) { void Simulator::DecodeTypeVFP(Instr* instr) {
ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
ASSERT(instr->Bits(11, 9) == 0x5); ASSERT(instr->Bits(11, 9) == 0x5);
@ -2284,6 +2286,11 @@ void Simulator::DecodeTypeVFP(Instr* instr) {
} else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) && } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
(instr->Opc3Field() & 0x1)) { (instr->Opc3Field() & 0x1)) {
DecodeVCMP(instr); DecodeVCMP(instr);
} else if (((instr->Opc2Field() == 0x1)) && (instr->Opc3Field() == 0x3)) {
// vsqrt
double dm_value = get_double_from_d_register(vm);
double dd_value = sqrt(dm_value);
set_d_register_from_double(vd, dd_value);
} else { } else {
UNREACHABLE(); // Not used by V8. UNREACHABLE(); // Not used by V8.
} }

1
deps/v8/src/code-stubs.h

@ -46,6 +46,7 @@ namespace internal {
V(RecordWrite) \ V(RecordWrite) \
V(ConvertToDouble) \ V(ConvertToDouble) \
V(WriteInt32ToHeapNumber) \ V(WriteInt32ToHeapNumber) \
V(IntegerMod) \
V(StackCheck) \ V(StackCheck) \
V(FastNewClosure) \ V(FastNewClosure) \
V(FastNewContext) \ V(FastNewContext) \

59
deps/v8/src/debug-debugger.js

@ -236,6 +236,7 @@ function ScriptBreakPoint(type, script_id_or_name, opt_line, opt_column,
this.active_ = true; this.active_ = true;
this.condition_ = null; this.condition_ = null;
this.ignoreCount_ = 0; this.ignoreCount_ = 0;
this.break_points_ = [];
} }
@ -289,6 +290,15 @@ ScriptBreakPoint.prototype.column = function() {
}; };
ScriptBreakPoint.prototype.actual_locations = function() {
var locations = [];
for (var i = 0; i < this.break_points_.length; i++) {
locations.push(this.break_points_[i].actual_location);
}
return locations;
}
ScriptBreakPoint.prototype.update_positions = function(line, column) { ScriptBreakPoint.prototype.update_positions = function(line, column) {
this.line_ = line; this.line_ = line;
this.column_ = column; this.column_ = column;
@ -334,10 +344,8 @@ ScriptBreakPoint.prototype.setIgnoreCount = function(ignoreCount) {
this.ignoreCount_ = ignoreCount; this.ignoreCount_ = ignoreCount;
// Set ignore count on all break points created from this script break point. // Set ignore count on all break points created from this script break point.
for (var i = 0; i < break_points.length; i++) { for (var i = 0; i < this.break_points_.length; i++) {
if (break_points[i].script_break_point() === this) { this.break_points_[i].setIgnoreCount(ignoreCount);
break_points[i].setIgnoreCount(ignoreCount);
}
} }
}; };
@ -379,20 +387,23 @@ ScriptBreakPoint.prototype.set = function (script) {
} }
// Convert the line and column into an absolute position within the script. // Convert the line and column into an absolute position within the script.
var pos = Debug.findScriptSourcePosition(script, this.line(), column); var position = Debug.findScriptSourcePosition(script, this.line(), column);
// If the position is not found in the script (the script might be shorter // If the position is not found in the script (the script might be shorter
// than it used to be) just ignore it. // than it used to be) just ignore it.
if (pos === null) return; if (position === null) return;
// Create a break point object and set the break point. // Create a break point object and set the break point.
break_point = MakeBreakPoint(pos, this.line(), this.column(), this); break_point = MakeBreakPoint(position, this.line(), this.column(), this);
break_point.setIgnoreCount(this.ignoreCount()); break_point.setIgnoreCount(this.ignoreCount());
pos = %SetScriptBreakPoint(script, pos, break_point); var actual_position = %SetScriptBreakPoint(script, position, break_point);
if (!IS_UNDEFINED(pos)) { if (IS_UNDEFINED(actual_position)) {
this.actual_location = script.locationFromPosition(pos); actual_position = position;
} }
var actual_location = script.locationFromPosition(actual_position, true);
break_point.actual_location = { line: actual_location.line,
column: actual_location.column };
this.break_points_.push(break_point);
return break_point; return break_point;
}; };
@ -409,6 +420,7 @@ ScriptBreakPoint.prototype.clear = function () {
} }
} }
break_points = remaining_break_points; break_points = remaining_break_points;
this.break_points_ = [];
}; };
@ -554,6 +566,19 @@ Debug.findBreakPoint = function(break_point_number, remove) {
} }
}; };
Debug.findBreakPointActualLocations = function(break_point_number) {
for (var i = 0; i < script_break_points.length; i++) {
if (script_break_points[i].number() == break_point_number) {
return script_break_points[i].actual_locations();
}
}
for (var i = 0; i < break_points.length; i++) {
if (break_points[i].number() == break_point_number) {
return [break_points[i].actual_location];
}
}
return [];
}
Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) { Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) {
if (!IS_FUNCTION(func)) throw new Error('Parameters have wrong types.'); if (!IS_FUNCTION(func)) throw new Error('Parameters have wrong types.');
@ -585,7 +610,12 @@ Debug.setBreakPoint = function(func, opt_line, opt_column, opt_condition) {
} else { } else {
// Set a break point directly on the function. // Set a break point directly on the function.
var break_point = MakeBreakPoint(source_position, opt_line, opt_column); var break_point = MakeBreakPoint(source_position, opt_line, opt_column);
var actual_position =
%SetFunctionBreakPoint(func, source_position, break_point); %SetFunctionBreakPoint(func, source_position, break_point);
actual_position += this.sourcePosition(func);
var actual_location = script.locationFromPosition(actual_position, true);
break_point.actual_location = { line: actual_location.line,
column: actual_location.column };
break_point.setCondition(opt_condition); break_point.setCondition(opt_condition);
return break_point.number(); return break_point.number();
} }
@ -1482,8 +1512,10 @@ DebugCommandProcessor.prototype.setBreakPointRequest_ =
} }
response.body.line = break_point.line(); response.body.line = break_point.line();
response.body.column = break_point.column(); response.body.column = break_point.column();
response.body.actual_locations = break_point.actual_locations();
} else { } else {
response.body.type = 'function'; response.body.type = 'function';
response.body.actual_locations = [break_point.actual_location];
} }
}; };
@ -1598,7 +1630,8 @@ DebugCommandProcessor.prototype.listBreakpointsRequest_ = function(request, resp
hit_count: break_point.hit_count(), hit_count: break_point.hit_count(),
active: break_point.active(), active: break_point.active(),
condition: break_point.condition(), condition: break_point.condition(),
ignoreCount: break_point.ignoreCount() ignoreCount: break_point.ignoreCount(),
actual_locations: break_point.actual_locations()
} }
if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) { if (break_point.type() == Debug.ScriptBreakPointType.ScriptId) {

10
deps/v8/src/handles.cc

@ -197,7 +197,17 @@ void TransformToFastProperties(Handle<JSObject> object,
void FlattenString(Handle<String> string) { void FlattenString(Handle<String> string) {
CALL_HEAP_FUNCTION_VOID(string->TryFlatten()); CALL_HEAP_FUNCTION_VOID(string->TryFlatten());
}
Handle<String> FlattenGetString(Handle<String> string) {
Handle<String> result;
CALL_AND_RETRY(string->TryFlatten(),
{ result = Handle<String>(String::cast(__object__));
break; },
return Handle<String>());
ASSERT(string->IsFlat()); ASSERT(string->IsFlat());
return result;
} }

6
deps/v8/src/handles.h

@ -193,8 +193,14 @@ void NormalizeProperties(Handle<JSObject> object,
void NormalizeElements(Handle<JSObject> object); void NormalizeElements(Handle<JSObject> object);
void TransformToFastProperties(Handle<JSObject> object, void TransformToFastProperties(Handle<JSObject> object,
int unused_property_fields); int unused_property_fields);
// Flattens a string.
void FlattenString(Handle<String> str); void FlattenString(Handle<String> str);
// Flattens a string and returns the underlying external or sequential
// string.
Handle<String> FlattenGetString(Handle<String> str);
Handle<Object> SetProperty(Handle<JSObject> object, Handle<Object> SetProperty(Handle<JSObject> object,
Handle<String> key, Handle<String> key,
Handle<Object> value, Handle<Object> value,

10
deps/v8/src/ia32/codegen-ia32.cc

@ -11686,16 +11686,18 @@ void CompareStub::Generate(MacroAssembler* masm) {
__ Set(eax, Immediate(Smi::FromInt(EQUAL))); __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0); __ ret(0);
} else { } else {
Label return_equal;
Label heap_number; Label heap_number;
// If it's not a heap number, then return equal.
__ cmp(FieldOperand(edx, HeapObject::kMapOffset), __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
Immediate(Factory::heap_number_map())); Immediate(Factory::heap_number_map()));
if (cc_ == equal) {
__ j(equal, &heap_number); __ j(equal, &heap_number);
__ bind(&return_equal); // Identical objects are equal for operators ==, !=, and ===.
__ Set(eax, Immediate(Smi::FromInt(EQUAL))); __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
__ ret(0); __ ret(0);
} else {
// Identical objects must call ToPrimitive for <, <=, >, and >=.
__ j(not_equal, &not_identical);
}
__ bind(&heap_number); __ bind(&heap_number);
// It is a heap number, so return non-equal if it's NaN and equal if // It is a heap number, so return non-equal if it's NaN and equal if
// it's not NaN. // it's not NaN.

2
deps/v8/src/json.js

@ -241,7 +241,7 @@ function JSONStringify(value, replacer, space) {
} }
var gap; var gap;
if (IS_NUMBER(space)) { if (IS_NUMBER(space)) {
space = $Math.min(space, 10); space = $Math.min(ToInteger(space), 10);
gap = ""; gap = "";
for (var i = 0; i < space; i++) { for (var i = 0; i < space; i++) {
gap += " "; gap += " ";

18
deps/v8/src/jsregexp.cc

@ -356,7 +356,16 @@ int RegExpImpl::IrregexpPrepare(Handle<JSRegExp> regexp,
if (!subject->IsFlat()) { if (!subject->IsFlat()) {
FlattenString(subject); FlattenString(subject);
} }
bool is_ascii = subject->IsAsciiRepresentation(); // Check the asciiness of the underlying storage.
bool is_ascii;
{
AssertNoAllocation no_gc;
String* sequential_string = *subject;
if (subject->IsConsString()) {
sequential_string = ConsString::cast(*subject)->first();
}
is_ascii = sequential_string->IsAsciiRepresentation();
}
if (!EnsureCompiledIrregexp(regexp, is_ascii)) { if (!EnsureCompiledIrregexp(regexp, is_ascii)) {
return -1; return -1;
} }
@ -381,6 +390,11 @@ RegExpImpl::IrregexpResult RegExpImpl::IrregexpExecOnce(Handle<JSRegExp> regexp,
ASSERT(index <= subject->length()); ASSERT(index <= subject->length());
ASSERT(subject->IsFlat()); ASSERT(subject->IsFlat());
// A flat ASCII string might have a two-byte first part.
if (subject->IsConsString()) {
subject = Handle<String>(ConsString::cast(*subject)->first());
}
#ifndef V8_INTERPRETED_REGEXP #ifndef V8_INTERPRETED_REGEXP
ASSERT(output.length() >= ASSERT(output.length() >=
(IrregexpNumberOfCaptures(*irregexp) + 1) * 2); (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
@ -407,7 +421,7 @@ RegExpImpl::IrregexpResult RegExpImpl::IrregexpExecOnce(Handle<JSRegExp> regexp,
// If result is RETRY, the string has changed representation, and we // If result is RETRY, the string has changed representation, and we
// must restart from scratch. // must restart from scratch.
// In this case, it means we must make sure we are prepared to handle // In this case, it means we must make sure we are prepared to handle
// the, potentially, differen subject (the string can switch between // the, potentially, different subject (the string can switch between
// being internal and external, and even between being ASCII and UC16, // being internal and external, and even between being ASCII and UC16,
// but the characters are always the same). // but the characters are always the same).
IrregexpPrepare(regexp, subject); IrregexpPrepare(regexp, subject);

2
deps/v8/src/objects.cc

@ -678,7 +678,7 @@ Object* String::SlowTryFlatten(PretenureFlag pretenure) {
bool String::MakeExternal(v8::String::ExternalStringResource* resource) { bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// Externalizing twice leaks the external resouce, so it's // Externalizing twice leaks the external resource, so it's
// prohibited by the API. // prohibited by the API.
ASSERT(!this->IsExternalString()); ASSERT(!this->IsExternalString());
#ifdef DEBUG #ifdef DEBUG

4
deps/v8/src/regexp-macro-assembler.cc

@ -120,8 +120,6 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
int start_offset = previous_index; int start_offset = previous_index;
int end_offset = subject_ptr->length(); int end_offset = subject_ptr->length();
bool is_ascii = subject->IsAsciiRepresentation();
// The string has been flattened, so it it is a cons string it contains the // The string has been flattened, so it it is a cons string it contains the
// full string in the first part. // full string in the first part.
if (StringShape(subject_ptr).IsCons()) { if (StringShape(subject_ptr).IsCons()) {
@ -129,7 +127,7 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
subject_ptr = ConsString::cast(subject_ptr)->first(); subject_ptr = ConsString::cast(subject_ptr)->first();
} }
// Ensure that an underlying string has the same ascii-ness. // Ensure that an underlying string has the same ascii-ness.
ASSERT(subject_ptr->IsAsciiRepresentation() == is_ascii); bool is_ascii = subject_ptr->IsAsciiRepresentation();
ASSERT(subject_ptr->IsExternalString() || subject_ptr->IsSeqString()); ASSERT(subject_ptr->IsExternalString() || subject_ptr->IsSeqString());
// String is now either Sequential or External // String is now either Sequential or External
int char_size_shift = is_ascii ? 0 : 1; int char_size_shift = is_ascii ? 0 : 1;

42
deps/v8/src/runtime.cc

@ -2782,13 +2782,17 @@ int Runtime::StringMatch(Handle<String> sub,
// algorithm is unnecessary overhead. // algorithm is unnecessary overhead.
if (pattern_length == 1) { if (pattern_length == 1) {
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
if (sub->IsAsciiRepresentation()) { String* seq_sub = *sub;
if (seq_sub->IsConsString()) {
seq_sub = ConsString::cast(seq_sub)->first();
}
if (seq_sub->IsAsciiRepresentation()) {
uc16 pchar = pat->Get(0); uc16 pchar = pat->Get(0);
if (pchar > String::kMaxAsciiCharCode) { if (pchar > String::kMaxAsciiCharCode) {
return -1; return -1;
} }
Vector<const char> ascii_vector = Vector<const char> ascii_vector =
sub->ToAsciiVector().SubVector(start_index, subject_length); seq_sub->ToAsciiVector().SubVector(start_index, subject_length);
const void* pos = memchr(ascii_vector.start(), const void* pos = memchr(ascii_vector.start(),
static_cast<const char>(pchar), static_cast<const char>(pchar),
static_cast<size_t>(ascii_vector.length())); static_cast<size_t>(ascii_vector.length()));
@ -2798,7 +2802,9 @@ int Runtime::StringMatch(Handle<String> sub,
return static_cast<int>(reinterpret_cast<const char*>(pos) return static_cast<int>(reinterpret_cast<const char*>(pos)
- ascii_vector.start() + start_index); - ascii_vector.start() + start_index);
} }
return SingleCharIndexOf(sub->ToUC16Vector(), pat->Get(0), start_index); return SingleCharIndexOf(seq_sub->ToUC16Vector(),
pat->Get(0),
start_index);
} }
if (!pat->IsFlat()) { if (!pat->IsFlat()) {
@ -2806,19 +2812,29 @@ int Runtime::StringMatch(Handle<String> sub,
} }
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
// Extract flattened substrings of cons strings before determining asciiness.
String* seq_sub = *sub;
if (seq_sub->IsConsString()) {
seq_sub = ConsString::cast(seq_sub)->first();
}
String* seq_pat = *pat;
if (seq_pat->IsConsString()) {
seq_pat = ConsString::cast(seq_pat)->first();
}
// dispatch on type of strings // dispatch on type of strings
if (pat->IsAsciiRepresentation()) { if (seq_pat->IsAsciiRepresentation()) {
Vector<const char> pat_vector = pat->ToAsciiVector(); Vector<const char> pat_vector = seq_pat->ToAsciiVector();
if (sub->IsAsciiRepresentation()) { if (seq_sub->IsAsciiRepresentation()) {
return StringSearch(sub->ToAsciiVector(), pat_vector, start_index); return StringSearch(seq_sub->ToAsciiVector(), pat_vector, start_index);
} }
return StringSearch(sub->ToUC16Vector(), pat_vector, start_index); return StringSearch(seq_sub->ToUC16Vector(), pat_vector, start_index);
} }
Vector<const uc16> pat_vector = pat->ToUC16Vector(); Vector<const uc16> pat_vector = seq_pat->ToUC16Vector();
if (sub->IsAsciiRepresentation()) { if (seq_sub->IsAsciiRepresentation()) {
return StringSearch(sub->ToAsciiVector(), pat_vector, start_index); return StringSearch(seq_sub->ToAsciiVector(), pat_vector, start_index);
} }
return StringSearch(sub->ToUC16Vector(), pat_vector, start_index); return StringSearch(seq_sub->ToUC16Vector(), pat_vector, start_index);
} }
@ -9063,7 +9079,7 @@ static Object* Runtime_SetFunctionBreakPoint(Arguments args) {
// Set break point. // Set break point.
Debug::SetBreakPoint(shared, break_point_object_arg, &source_position); Debug::SetBreakPoint(shared, break_point_object_arg, &source_position);
return Heap::undefined_value(); return Smi::FromInt(source_position);
} }

12
deps/v8/src/runtime.js

@ -112,7 +112,7 @@ function STRICT_EQUALS(x) {
// the result when either (or both) the operands are NaN. // the result when either (or both) the operands are NaN.
function COMPARE(x, ncr) { function COMPARE(x, ncr) {
var left; var left;
var right;
// Fast cases for string, numbers and undefined compares. // Fast cases for string, numbers and undefined compares.
if (IS_STRING(this)) { if (IS_STRING(this)) {
if (IS_STRING(x)) return %_StringCompare(this, x); if (IS_STRING(x)) return %_StringCompare(this, x);
@ -123,14 +123,18 @@ function COMPARE(x, ncr) {
if (IS_UNDEFINED(x)) return ncr; if (IS_UNDEFINED(x)) return ncr;
left = this; left = this;
} else if (IS_UNDEFINED(this)) { } else if (IS_UNDEFINED(this)) {
if (!IS_UNDEFINED(x)) {
%ToPrimitive(x, NUMBER_HINT);
}
return ncr;
} else if (IS_UNDEFINED(x)) {
%ToPrimitive(this, NUMBER_HINT);
return ncr; return ncr;
} else { } else {
if (IS_UNDEFINED(x)) return ncr;
left = %ToPrimitive(this, NUMBER_HINT); left = %ToPrimitive(this, NUMBER_HINT);
} }
// Default implementation. right = %ToPrimitive(x, NUMBER_HINT);
var right = %ToPrimitive(x, NUMBER_HINT);
if (IS_STRING(left) && IS_STRING(right)) { if (IS_STRING(left) && IS_STRING(right)) {
return %_StringCompare(left, right); return %_StringCompare(left, right);
} else { } else {

2
deps/v8/src/type-info.h

@ -79,7 +79,7 @@ class TypeInfo {
// Decode compact representation. Very sensitive to enum values below! // Decode compact representation. Very sensitive to enum values below!
static TypeInfo ExpandedRepresentation(int three_bit_representation) { static TypeInfo ExpandedRepresentation(int three_bit_representation) {
Type t = static_cast<Type>(three_bit_representation >= 6 ? Type t = static_cast<Type>(three_bit_representation > 4 ?
three_bit_representation + 2 : three_bit_representation + 2 :
three_bit_representation); three_bit_representation);
t = (t == kUnknownType) ? t : static_cast<Type>(t | kPrimitiveType); t = (t == kUnknownType) ? t : static_cast<Type>(t | kPrimitiveType);

2
deps/v8/src/version.cc

@ -34,7 +34,7 @@
// cannot be changed without changing the SCons build script. // cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 2 #define MAJOR_VERSION 2
#define MINOR_VERSION 2 #define MINOR_VERSION 2
#define BUILD_NUMBER 20 #define BUILD_NUMBER 21
#define PATCH_LEVEL 0 #define PATCH_LEVEL 0
#define CANDIDATE_VERSION false #define CANDIDATE_VERSION false

6
deps/v8/src/x64/assembler-x64.cc

@ -1563,7 +1563,7 @@ void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
void Assembler::movsxbq(Register dst, const Operand& src) { void Assembler::movsxbq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
emit_rex_32(dst, src); emit_rex_64(dst, src);
emit(0x0F); emit(0x0F);
emit(0xBE); emit(0xBE);
emit_operand(dst, src); emit_operand(dst, src);
@ -1601,7 +1601,7 @@ void Assembler::movsxlq(Register dst, const Operand& src) {
void Assembler::movzxbq(Register dst, const Operand& src) { void Assembler::movzxbq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
emit_rex_64(dst, src); emit_optional_rex_32(dst, src);
emit(0x0F); emit(0x0F);
emit(0xB6); emit(0xB6);
emit_operand(dst, src); emit_operand(dst, src);
@ -1621,7 +1621,7 @@ void Assembler::movzxbl(Register dst, const Operand& src) {
void Assembler::movzxwq(Register dst, const Operand& src) { void Assembler::movzxwq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
emit_rex_64(dst, src); emit_optional_rex_32(dst, src);
emit(0x0F); emit(0x0F);
emit(0xB7); emit(0xB7);
emit_operand(dst, src); emit_operand(dst, src);

32
deps/v8/src/x64/codegen-x64.cc

@ -856,7 +856,7 @@ void CodeGenerator::CallApplyLazy(Expression* applicand,
__ j(equal, &adapted); __ j(equal, &adapted);
// No arguments adaptor frame. Copy fixed number of arguments. // No arguments adaptor frame. Copy fixed number of arguments.
__ movq(rax, Immediate(scope()->num_parameters())); __ Set(rax, scope()->num_parameters());
for (int i = 0; i < scope()->num_parameters(); i++) { for (int i = 0; i < scope()->num_parameters(); i++) {
__ push(frame_->ParameterAt(i)); __ push(frame_->ParameterAt(i));
} }
@ -5342,6 +5342,10 @@ void CodeGenerator::ToBoolean(ControlDestination* dest) {
} }
// Smi => false iff zero. // Smi => false iff zero.
__ SmiCompare(value.reg(), Smi::FromInt(0)); __ SmiCompare(value.reg(), Smi::FromInt(0));
if (value.is_smi()) {
value.Unuse();
dest->Split(not_zero);
} else {
dest->false_target()->Branch(equal); dest->false_target()->Branch(equal);
Condition is_smi = masm_->CheckSmi(value.reg()); Condition is_smi = masm_->CheckSmi(value.reg());
dest->true_target()->Branch(is_smi); dest->true_target()->Branch(is_smi);
@ -5349,6 +5353,7 @@ void CodeGenerator::ToBoolean(ControlDestination* dest) {
__ ucomisd(xmm0, FieldOperand(value.reg(), HeapNumber::kValueOffset)); __ ucomisd(xmm0, FieldOperand(value.reg(), HeapNumber::kValueOffset));
value.Unuse(); value.Unuse();
dest->Split(not_zero); dest->Split(not_zero);
}
} else { } else {
// Fast case checks. // Fast case checks.
// 'false' => false. // 'false' => false.
@ -8959,23 +8964,32 @@ void CompareStub::Generate(MacroAssembler* masm) {
// Test for NaN. Sadly, we can't just compare to Factory::nan_value(), // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
// so we do the second best thing - test it ourselves. // so we do the second best thing - test it ourselves.
// Note: if cc_ != equal, never_nan_nan_ is not used. // Note: if cc_ != equal, never_nan_nan_ is not used.
__ Set(rax, EQUAL); // We cannot set rax to EQUAL until just before return because
// rax must be unchanged on jump to not_identical.
if (never_nan_nan_ && (cc_ == equal)) { if (never_nan_nan_ && (cc_ == equal)) {
__ Set(rax, EQUAL);
__ ret(0); __ ret(0);
} else { } else {
Label heap_number; Label heap_number;
// If it's not a heap number, then return equal. // If it's not a heap number, then return equal for (in)equality operator.
__ Cmp(FieldOperand(rdx, HeapObject::kMapOffset), __ Cmp(FieldOperand(rdx, HeapObject::kMapOffset),
Factory::heap_number_map()); Factory::heap_number_map());
if (cc_ == equal) {
__ j(equal, &heap_number); __ j(equal, &heap_number);
__ Set(rax, EQUAL);
__ ret(0); __ ret(0);
} else {
// Identical objects must still be converted to primitive for < and >.
__ j(not_equal, &not_identical);
}
__ bind(&heap_number); __ bind(&heap_number);
// It is a heap number, so return equal if it's not NaN. // It is a heap number, so return equal if it's not NaN.
// For NaN, return 1 for every condition except greater and // For NaN, return 1 for every condition except greater and
// greater-equal. Return -1 for them, so the comparison yields // greater-equal. Return -1 for them, so the comparison yields
// false for all conditions except not-equal. // false for all conditions except not-equal.
__ Set(rax, EQUAL);
__ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); __ movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset));
__ ucomisd(xmm0, xmm0); __ ucomisd(xmm0, xmm0);
__ setcc(parity_even, rax); __ setcc(parity_even, rax);
@ -9058,16 +9072,16 @@ void CompareStub::Generate(MacroAssembler* masm) {
Label non_number_comparison; Label non_number_comparison;
Label unordered; Label unordered;
FloatingPointHelper::LoadSSE2UnknownOperands(masm, &non_number_comparison); FloatingPointHelper::LoadSSE2UnknownOperands(masm, &non_number_comparison);
__ xorl(rax, rax);
__ xorl(rcx, rcx);
__ ucomisd(xmm0, xmm1); __ ucomisd(xmm0, xmm1);
// Don't base result on EFLAGS when a NaN is involved. // Don't base result on EFLAGS when a NaN is involved.
__ j(parity_even, &unordered); __ j(parity_even, &unordered);
// Return a result of -1, 0, or 1, based on EFLAGS. // Return a result of -1, 0, or 1, based on EFLAGS.
__ movq(rax, Immediate(0)); // equal __ setcc(above, rax);
__ movq(rcx, Immediate(1)); __ setcc(below, rcx);
__ cmovq(above, rax, rcx); __ subq(rax, rcx);
__ movq(rcx, Immediate(-1));
__ cmovq(below, rax, rcx);
__ ret(2 * kPointerSize); // rax, rdx were pushed __ ret(2 * kPointerSize); // rax, rdx were pushed
// If one of the numbers was NaN, then the result is always false. // If one of the numbers was NaN, then the result is always false.

26
deps/v8/src/x64/disasm-x64.cc

@ -468,20 +468,20 @@ int DisassemblerX64::PrintRightOperandHelper(
if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
// index == rsp means no index. Only use sib byte with no index for // index == rsp means no index. Only use sib byte with no index for
// rsp and r12 base. // rsp and r12 base.
AppendToBuffer("[%s]", (this->*register_name)(base)); AppendToBuffer("[%s]", NameOfCPURegister(base));
return 2; return 2;
} else if (base == 5) { } else if (base == 5) {
// base == rbp means no base register (when mod == 0). // base == rbp means no base register (when mod == 0).
int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2); int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
AppendToBuffer("[%s*%d+0x%x]", AppendToBuffer("[%s*%d+0x%x]",
(this->*register_name)(index), NameOfCPURegister(index),
1 << scale, disp); 1 << scale, disp);
return 6; return 6;
} else if (index != 4 && base != 5) { } else if (index != 4 && base != 5) {
// [base+index*scale] // [base+index*scale]
AppendToBuffer("[%s+%s*%d]", AppendToBuffer("[%s+%s*%d]",
(this->*register_name)(base), NameOfCPURegister(base),
(this->*register_name)(index), NameOfCPURegister(index),
1 << scale); 1 << scale);
return 2; return 2;
} else { } else {
@ -489,7 +489,7 @@ int DisassemblerX64::PrintRightOperandHelper(
return 1; return 1;
} }
} else { } else {
AppendToBuffer("[%s]", (this->*register_name)(rm)); AppendToBuffer("[%s]", NameOfCPURegister(rm));
return 1; return 1;
} }
break; break;
@ -503,21 +503,21 @@ int DisassemblerX64::PrintRightOperandHelper(
: *reinterpret_cast<char*>(modrmp + 2); : *reinterpret_cast<char*>(modrmp + 2);
if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) { if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
if (-disp > 0) { if (-disp > 0) {
AppendToBuffer("[%s-0x%x]", (this->*register_name)(base), -disp); AppendToBuffer("[%s-0x%x]", NameOfCPURegister(base), -disp);
} else { } else {
AppendToBuffer("[%s+0x%x]", (this->*register_name)(base), disp); AppendToBuffer("[%s+0x%x]", NameOfCPURegister(base), disp);
} }
} else { } else {
if (-disp > 0) { if (-disp > 0) {
AppendToBuffer("[%s+%s*%d-0x%x]", AppendToBuffer("[%s+%s*%d-0x%x]",
(this->*register_name)(base), NameOfCPURegister(base),
(this->*register_name)(index), NameOfCPURegister(index),
1 << scale, 1 << scale,
-disp); -disp);
} else { } else {
AppendToBuffer("[%s+%s*%d+0x%x]", AppendToBuffer("[%s+%s*%d+0x%x]",
(this->*register_name)(base), NameOfCPURegister(base),
(this->*register_name)(index), NameOfCPURegister(index),
1 << scale, 1 << scale,
disp); disp);
} }
@ -528,9 +528,9 @@ int DisassemblerX64::PrintRightOperandHelper(
int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1) int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1)
: *reinterpret_cast<char*>(modrmp + 1); : *reinterpret_cast<char*>(modrmp + 1);
if (-disp > 0) { if (-disp > 0) {
AppendToBuffer("[%s-0x%x]", (this->*register_name)(rm), -disp); AppendToBuffer("[%s-0x%x]", NameOfCPURegister(rm), -disp);
} else { } else {
AppendToBuffer("[%s+0x%x]", (this->*register_name)(rm), disp); AppendToBuffer("[%s+0x%x]", NameOfCPURegister(rm), disp);
} }
return (mod == 2) ? 5 : 2; return (mod == 2) ? 5 : 2;
} }

18
deps/v8/src/x64/macro-assembler-x64.cc

@ -351,7 +351,7 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
// arguments passed in because it is constant. At some point we // arguments passed in because it is constant. At some point we
// should remove this need and make the runtime routine entry code // should remove this need and make the runtime routine entry code
// smarter. // smarter.
movq(rax, Immediate(num_arguments)); Set(rax, num_arguments);
movq(rbx, ExternalReference(f)); movq(rbx, ExternalReference(f));
CEntryStub ces(f->result_size); CEntryStub ces(f->result_size);
CallStub(&ces); CallStub(&ces);
@ -360,7 +360,7 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
void MacroAssembler::CallExternalReference(const ExternalReference& ext, void MacroAssembler::CallExternalReference(const ExternalReference& ext,
int num_arguments) { int num_arguments) {
movq(rax, Immediate(num_arguments)); Set(rax, num_arguments);
movq(rbx, ext); movq(rbx, ext);
CEntryStub stub(1); CEntryStub stub(1);
@ -382,7 +382,7 @@ void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
// arguments passed in because it is constant. At some point we // arguments passed in because it is constant. At some point we
// should remove this need and make the runtime routine entry code // should remove this need and make the runtime routine entry code
// smarter. // smarter.
movq(rax, Immediate(num_arguments)); Set(rax, num_arguments);
JumpToExternalReference(ext, result_size); JumpToExternalReference(ext, result_size);
} }
@ -640,9 +640,9 @@ Condition MacroAssembler::CheckBothSmi(Register first, Register second) {
if (first.is(second)) { if (first.is(second)) {
return CheckSmi(first); return CheckSmi(first);
} }
movl(kScratchRegister, first); ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3);
orl(kScratchRegister, second); leal(kScratchRegister, Operand(first, second, times_1, 0));
testb(kScratchRegister, Immediate(kSmiTagMask)); testb(kScratchRegister, Immediate(0x03));
return zero; return zero;
} }
@ -1937,7 +1937,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
if (expected.immediate() == actual.immediate()) { if (expected.immediate() == actual.immediate()) {
definitely_matches = true; definitely_matches = true;
} else { } else {
movq(rax, Immediate(actual.immediate())); Set(rax, actual.immediate());
if (expected.immediate() == if (expected.immediate() ==
SharedFunctionInfo::kDontAdaptArgumentsSentinel) { SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
// Don't worry about adapting arguments for built-ins that // Don't worry about adapting arguments for built-ins that
@ -1946,7 +1946,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
// arguments. // arguments.
definitely_matches = true; definitely_matches = true;
} else { } else {
movq(rbx, Immediate(expected.immediate())); Set(rbx, expected.immediate());
} }
} }
} else { } else {
@ -1957,7 +1957,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected,
cmpq(expected.reg(), Immediate(actual.immediate())); cmpq(expected.reg(), Immediate(actual.immediate()));
j(equal, &invoke); j(equal, &invoke);
ASSERT(expected.reg().is(rbx)); ASSERT(expected.reg().is(rbx));
movq(rax, Immediate(actual.immediate())); Set(rax, actual.immediate());
} else if (!expected.reg().is(actual.reg())) { } else if (!expected.reg().is(actual.reg())) {
// Both expected and actual are in (different) registers. This // Both expected and actual are in (different) registers. This
// is the case when we invoke functions using call and apply. // is the case when we invoke functions using call and apply.

2
deps/v8/src/x64/virtual-frame-x64.cc

@ -1221,7 +1221,7 @@ Result VirtualFrame::CallConstructor(int arg_count) {
// call trampolines per different arguments counts encountered. // call trampolines per different arguments counts encountered.
Result num_args = cgen()->allocator()->Allocate(rax); Result num_args = cgen()->allocator()->Allocate(rax);
ASSERT(num_args.is_valid()); ASSERT(num_args.is_valid());
__ movq(num_args.reg(), Immediate(arg_count)); __ Set(num_args.reg(), arg_count);
function.Unuse(); function.Unuse();
num_args.Unuse(); num_args.Unuse();

3
deps/v8/test/cctest/SConscript

@ -69,8 +69,9 @@ SOURCES = {
'test-sockets.cc', 'test-sockets.cc',
'test-spaces.cc', 'test-spaces.cc',
'test-strings.cc', 'test-strings.cc',
'test-threads.cc',
'test-thread-termination.cc', 'test-thread-termination.cc',
'test-threads.cc',
'test-type-info.cc',
'test-unbound-queue.cc', 'test-unbound-queue.cc',
'test-utils.cc', 'test-utils.cc',
'test-version.cc' 'test-version.cc'

171
deps/v8/test/cctest/test-api.cc

@ -58,7 +58,7 @@ using ::v8::Function;
using ::v8::AccessorInfo; using ::v8::AccessorInfo;
using ::v8::Extension; using ::v8::Extension;
namespace i = ::v8::internal; namespace i = ::i;
static void ExpectString(const char* code, const char* expected) { static void ExpectString(const char* code, const char* expected) {
@ -381,11 +381,11 @@ THREADED_TEST(ScriptUsingStringResource) {
CHECK(source->IsExternal()); CHECK(source->IsExternal());
CHECK_EQ(resource, CHECK_EQ(resource,
static_cast<TestResource*>(source->GetExternalStringResource())); static_cast<TestResource*>(source->GetExternalStringResource()));
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(0, TestResource::dispose_count); CHECK_EQ(0, TestResource::dispose_count);
} }
v8::internal::CompilationCache::Clear(); i::CompilationCache::Clear();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(1, TestResource::dispose_count); CHECK_EQ(1, TestResource::dispose_count);
} }
@ -402,11 +402,11 @@ THREADED_TEST(ScriptUsingAsciiStringResource) {
Local<Value> value = script->Run(); Local<Value> value = script->Run();
CHECK(value->IsNumber()); CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value()); CHECK_EQ(7, value->Int32Value());
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count); CHECK_EQ(0, TestAsciiResource::dispose_count);
} }
v8::internal::CompilationCache::Clear(); i::CompilationCache::Clear();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResource::dispose_count); CHECK_EQ(1, TestAsciiResource::dispose_count);
} }
@ -427,11 +427,11 @@ THREADED_TEST(ScriptMakingExternalString) {
Local<Value> value = script->Run(); Local<Value> value = script->Run();
CHECK(value->IsNumber()); CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value()); CHECK_EQ(7, value->Int32Value());
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(0, TestResource::dispose_count); CHECK_EQ(0, TestResource::dispose_count);
} }
v8::internal::CompilationCache::Clear(); i::CompilationCache::Clear();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(1, TestResource::dispose_count); CHECK_EQ(1, TestResource::dispose_count);
} }
@ -453,11 +453,11 @@ THREADED_TEST(ScriptMakingExternalAsciiString) {
Local<Value> value = script->Run(); Local<Value> value = script->Run();
CHECK(value->IsNumber()); CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value()); CHECK_EQ(7, value->Int32Value());
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count); CHECK_EQ(0, TestAsciiResource::dispose_count);
} }
v8::internal::CompilationCache::Clear(); i::CompilationCache::Clear();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResource::dispose_count); CHECK_EQ(1, TestAsciiResource::dispose_count);
} }
@ -645,11 +645,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run(); Local<Value> value = script->Run();
CHECK(value->IsNumber()); CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value()); CHECK_EQ(7, value->Int32Value());
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count); CHECK_EQ(0, TestAsciiResource::dispose_count);
} }
v8::internal::CompilationCache::Clear(); i::CompilationCache::Clear();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
CHECK_EQ(0, TestAsciiResource::dispose_count); CHECK_EQ(0, TestAsciiResource::dispose_count);
@ -666,11 +666,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run(); Local<Value> value = script->Run();
CHECK(value->IsNumber()); CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value()); CHECK_EQ(7, value->Int32Value());
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(0, TestAsciiResource::dispose_count); CHECK_EQ(0, TestAsciiResource::dispose_count);
} }
v8::internal::CompilationCache::Clear(); i::CompilationCache::Clear();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
CHECK_EQ(1, TestAsciiResource::dispose_count); CHECK_EQ(1, TestAsciiResource::dispose_count);
} }
@ -708,7 +708,7 @@ THREADED_TEST(StringConcat) {
CHECK(value->IsNumber()); CHECK(value->IsNumber());
CHECK_EQ(68, value->Int32Value()); CHECK_EQ(68, value->Int32Value());
} }
v8::internal::CompilationCache::Clear(); i::CompilationCache::Clear();
i::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
i::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
} }
@ -1881,7 +1881,7 @@ static const char* js_code_causing_out_of_memory =
// that come after them so they cannot run in parallel. // that come after them so they cannot run in parallel.
TEST(OutOfMemory) { TEST(OutOfMemory) {
// It's not possible to read a snapshot into a heap with different dimensions. // It's not possible to read a snapshot into a heap with different dimensions.
if (v8::internal::Snapshot::IsEnabled()) return; if (i::Snapshot::IsEnabled()) return;
// Set heap limits. // Set heap limits.
static const int K = 1024; static const int K = 1024;
v8::ResourceConstraints constraints; v8::ResourceConstraints constraints;
@ -1922,7 +1922,7 @@ v8::Handle<Value> ProvokeOutOfMemory(const v8::Arguments& args) {
TEST(OutOfMemoryNested) { TEST(OutOfMemoryNested) {
// It's not possible to read a snapshot into a heap with different dimensions. // It's not possible to read a snapshot into a heap with different dimensions.
if (v8::internal::Snapshot::IsEnabled()) return; if (i::Snapshot::IsEnabled()) return;
// Set heap limits. // Set heap limits.
static const int K = 1024; static const int K = 1024;
v8::ResourceConstraints constraints; v8::ResourceConstraints constraints;
@ -1951,7 +1951,7 @@ TEST(OutOfMemoryNested) {
TEST(HugeConsStringOutOfMemory) { TEST(HugeConsStringOutOfMemory) {
// It's not possible to read a snapshot into a heap with different dimensions. // It's not possible to read a snapshot into a heap with different dimensions.
if (v8::internal::Snapshot::IsEnabled()) return; if (i::Snapshot::IsEnabled()) return;
v8::HandleScope scope; v8::HandleScope scope;
LocalContext context; LocalContext context;
// Set heap limits. // Set heap limits.
@ -6811,7 +6811,7 @@ static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
++(*call_count); ++(*call_count);
if ((*call_count) % 20 == 0) { if ((*call_count) % 20 == 0) {
v8::internal::Heap::CollectAllGarbage(true); i::Heap::CollectAllGarbage(true);
} }
return v8::Handle<Value>(); return v8::Handle<Value>();
} }
@ -7620,8 +7620,8 @@ THREADED_TEST(ObjectProtoToString) {
bool ApiTestFuzzer::fuzzing_ = false; bool ApiTestFuzzer::fuzzing_ = false;
v8::internal::Semaphore* ApiTestFuzzer::all_tests_done_= i::Semaphore* ApiTestFuzzer::all_tests_done_=
v8::internal::OS::CreateSemaphore(0); i::OS::CreateSemaphore(0);
int ApiTestFuzzer::active_tests_; int ApiTestFuzzer::active_tests_;
int ApiTestFuzzer::tests_being_run_; int ApiTestFuzzer::tests_being_run_;
int ApiTestFuzzer::current_; int ApiTestFuzzer::current_;
@ -7899,7 +7899,7 @@ THREADED_TEST(LockUnlockLock) {
static int GetGlobalObjectsCount() { static int GetGlobalObjectsCount() {
int count = 0; int count = 0;
v8::internal::HeapIterator it; i::HeapIterator it;
for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
if (object->IsJSGlobalObject()) count++; if (object->IsJSGlobalObject()) count++;
return count; return count;
@ -7912,11 +7912,11 @@ static int GetSurvivingGlobalObjectsCount() {
// the first garbage collection but some of the maps have already // the first garbage collection but some of the maps have already
// been marked at that point. Therefore some of the maps are not // been marked at that point. Therefore some of the maps are not
// collected until the second garbage collection. // collected until the second garbage collection.
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
int count = GetGlobalObjectsCount(); int count = GetGlobalObjectsCount();
#ifdef DEBUG #ifdef DEBUG
if (count > 0) v8::internal::Heap::TracePathToGlobal(); if (count > 0) i::Heap::TracePathToGlobal();
#endif #endif
return count; return count;
} }
@ -10021,7 +10021,7 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
THREADED_TEST(ExternalByteArray) { THREADED_TEST(ExternalByteArray) {
ExternalArrayTestHelper<v8::internal::ExternalByteArray, int8_t>( ExternalArrayTestHelper<i::ExternalByteArray, int8_t>(
v8::kExternalByteArray, v8::kExternalByteArray,
-128, -128,
127); 127);
@ -10029,7 +10029,7 @@ THREADED_TEST(ExternalByteArray) {
THREADED_TEST(ExternalUnsignedByteArray) { THREADED_TEST(ExternalUnsignedByteArray) {
ExternalArrayTestHelper<v8::internal::ExternalUnsignedByteArray, uint8_t>( ExternalArrayTestHelper<i::ExternalUnsignedByteArray, uint8_t>(
v8::kExternalUnsignedByteArray, v8::kExternalUnsignedByteArray,
0, 0,
255); 255);
@ -10037,7 +10037,7 @@ THREADED_TEST(ExternalUnsignedByteArray) {
THREADED_TEST(ExternalShortArray) { THREADED_TEST(ExternalShortArray) {
ExternalArrayTestHelper<v8::internal::ExternalShortArray, int16_t>( ExternalArrayTestHelper<i::ExternalShortArray, int16_t>(
v8::kExternalShortArray, v8::kExternalShortArray,
-32768, -32768,
32767); 32767);
@ -10045,7 +10045,7 @@ THREADED_TEST(ExternalShortArray) {
THREADED_TEST(ExternalUnsignedShortArray) { THREADED_TEST(ExternalUnsignedShortArray) {
ExternalArrayTestHelper<v8::internal::ExternalUnsignedShortArray, uint16_t>( ExternalArrayTestHelper<i::ExternalUnsignedShortArray, uint16_t>(
v8::kExternalUnsignedShortArray, v8::kExternalUnsignedShortArray,
0, 0,
65535); 65535);
@ -10053,7 +10053,7 @@ THREADED_TEST(ExternalUnsignedShortArray) {
THREADED_TEST(ExternalIntArray) { THREADED_TEST(ExternalIntArray) {
ExternalArrayTestHelper<v8::internal::ExternalIntArray, int32_t>( ExternalArrayTestHelper<i::ExternalIntArray, int32_t>(
v8::kExternalIntArray, v8::kExternalIntArray,
INT_MIN, // -2147483648 INT_MIN, // -2147483648
INT_MAX); // 2147483647 INT_MAX); // 2147483647
@ -10061,7 +10061,7 @@ THREADED_TEST(ExternalIntArray) {
THREADED_TEST(ExternalUnsignedIntArray) { THREADED_TEST(ExternalUnsignedIntArray) {
ExternalArrayTestHelper<v8::internal::ExternalUnsignedIntArray, uint32_t>( ExternalArrayTestHelper<i::ExternalUnsignedIntArray, uint32_t>(
v8::kExternalUnsignedIntArray, v8::kExternalUnsignedIntArray,
0, 0,
UINT_MAX); // 4294967295 UINT_MAX); // 4294967295
@ -10069,7 +10069,7 @@ THREADED_TEST(ExternalUnsignedIntArray) {
THREADED_TEST(ExternalFloatArray) { THREADED_TEST(ExternalFloatArray) {
ExternalArrayTestHelper<v8::internal::ExternalFloatArray, float>( ExternalArrayTestHelper<i::ExternalFloatArray, float>(
v8::kExternalFloatArray, v8::kExternalFloatArray,
-500, -500,
500); 500);
@ -10547,7 +10547,7 @@ TEST(Regress528) {
other_context->Enter(); other_context->Enter();
CompileRun(source_simple); CompileRun(source_simple);
other_context->Exit(); other_context->Exit();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
if (GetGlobalObjectsCount() == 1) break; if (GetGlobalObjectsCount() == 1) break;
} }
CHECK_GE(2, gc_count); CHECK_GE(2, gc_count);
@ -10569,7 +10569,7 @@ TEST(Regress528) {
other_context->Enter(); other_context->Enter();
CompileRun(source_eval); CompileRun(source_eval);
other_context->Exit(); other_context->Exit();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
if (GetGlobalObjectsCount() == 1) break; if (GetGlobalObjectsCount() == 1) break;
} }
CHECK_GE(2, gc_count); CHECK_GE(2, gc_count);
@ -10596,7 +10596,7 @@ TEST(Regress528) {
other_context->Enter(); other_context->Enter();
CompileRun(source_exception); CompileRun(source_exception);
other_context->Exit(); other_context->Exit();
v8::internal::Heap::CollectAllGarbage(false); i::Heap::CollectAllGarbage(false);
if (GetGlobalObjectsCount() == 1) break; if (GetGlobalObjectsCount() == 1) break;
} }
CHECK_GE(2, gc_count); CHECK_GE(2, gc_count);
@ -10859,7 +10859,7 @@ THREADED_TEST(AddToJSFunctionResultCache) {
" return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;"
" return 'PASSED';" " return 'PASSED';"
"})()"; "})()";
v8::internal::Heap::ClearJSFunctionResultCaches(); i::Heap::ClearJSFunctionResultCaches();
ExpectString(code, "PASSED"); ExpectString(code, "PASSED");
} }
@ -10883,7 +10883,7 @@ THREADED_TEST(FillJSFunctionResultCache) {
" return 'FAILED: k0CacheSize is too small';" " return 'FAILED: k0CacheSize is too small';"
" return 'PASSED';" " return 'PASSED';"
"})()"; "})()";
v8::internal::Heap::ClearJSFunctionResultCaches(); i::Heap::ClearJSFunctionResultCaches();
ExpectString(code, "PASSED"); ExpectString(code, "PASSED");
} }
@ -10908,7 +10908,7 @@ THREADED_TEST(RoundRobinGetFromCache) {
" };" " };"
" return 'PASSED';" " return 'PASSED';"
"})()"; "})()";
v8::internal::Heap::ClearJSFunctionResultCaches(); i::Heap::ClearJSFunctionResultCaches();
ExpectString(code, "PASSED"); ExpectString(code, "PASSED");
} }
@ -10933,7 +10933,7 @@ THREADED_TEST(ReverseGetFromCache) {
" };" " };"
" return 'PASSED';" " return 'PASSED';"
"})()"; "})()";
v8::internal::Heap::ClearJSFunctionResultCaches(); i::Heap::ClearJSFunctionResultCaches();
ExpectString(code, "PASSED"); ExpectString(code, "PASSED");
} }
@ -10951,6 +10951,87 @@ THREADED_TEST(TestEviction) {
" };" " };"
" return 'PASSED';" " return 'PASSED';"
"})()"; "})()";
v8::internal::Heap::ClearJSFunctionResultCaches(); i::Heap::ClearJSFunctionResultCaches();
ExpectString(code, "PASSED"); ExpectString(code, "PASSED");
} }
THREADED_TEST(TwoByteStringInAsciiCons) {
// See Chromium issue 47824.
v8::HandleScope scope;
LocalContext context;
const char* init_code =
"var str1 = 'abelspendabel';"
"var str2 = str1 + str1 + str1;"
"str2;";
Local<Value> result = CompileRun(init_code);
CHECK(result->IsString());
i::Handle<i::String> string = v8::Utils::OpenHandle(String::Cast(*result));
int length = string->length();
CHECK(string->IsAsciiRepresentation());
FlattenString(string);
i::Handle<i::String> flat_string = FlattenGetString(string);
CHECK(string->IsAsciiRepresentation());
CHECK(flat_string->IsAsciiRepresentation());
// Create external resource.
uint16_t* uc16_buffer = new uint16_t[length + 1];
i::String::WriteToFlat(*flat_string, uc16_buffer, 0, length);
uc16_buffer[length] = 0;
TestResource resource(uc16_buffer);
flat_string->MakeExternal(&resource);
CHECK(flat_string->IsTwoByteRepresentation());
// At this point, we should have a Cons string which is flat and ASCII,
// with a first half that is a two-byte string (although it only contains
// ASCII characters). This is a valid sequence of steps, and it can happen
// in real pages.
CHECK(string->IsAsciiRepresentation());
i::ConsString* cons = i::ConsString::cast(*string);
CHECK_EQ(0, cons->second()->length());
CHECK(cons->first()->IsTwoByteRepresentation());
// Check that some string operations work.
// Atom RegExp.
Local<Value> reresult = CompileRun("str2.match(/abel/g).length;");
CHECK_EQ(6, reresult->Int32Value());
// Nonatom RegExp.
reresult = CompileRun("str2.match(/abe./g).length;");
CHECK_EQ(6, reresult->Int32Value());
reresult = CompileRun("str2.search(/bel/g);");
CHECK_EQ(1, reresult->Int32Value());
reresult = CompileRun("str2.search(/be./g);");
CHECK_EQ(1, reresult->Int32Value());
ExpectTrue("/bel/g.test(str2);");
ExpectTrue("/be./g.test(str2);");
reresult = CompileRun("/bel/g.exec(str2);");
CHECK(!reresult->IsNull());
reresult = CompileRun("/be./g.exec(str2);");
CHECK(!reresult->IsNull());
ExpectString("str2.substring(2, 10);", "elspenda");
ExpectString("str2.substring(2, 20);", "elspendabelabelspe");
ExpectString("str2.charAt(2);", "e");
reresult = CompileRun("str2.charCodeAt(2);");
CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value());
}

35
deps/v8/test/cctest/test-disasm-arm.cc

@ -401,3 +401,38 @@ TEST(Type3) {
VERIFY_RUN(); VERIFY_RUN();
} }
TEST(Vfp) {
SETUP();
if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
COMPARE(vadd(d0, d1, d2),
"ee310b02 vadd.f64 d0, d1, d2");
COMPARE(vadd(d3, d4, d5, mi),
"4e343b05 vadd.f64mi d3, d4, d5");
COMPARE(vsub(d0, d1, d2),
"ee310b42 vsub.f64 d0, d1, d2");
COMPARE(vsub(d3, d4, d5, ne),
"1e343b45 vsub.f64ne d3, d4, d5");
COMPARE(vmul(d2, d1, d0),
"ee212b00 vmul.f64 d2, d1, d0");
COMPARE(vmul(d6, d4, d5, cc),
"3e246b05 vmul.f64cc d6, d4, d5");
COMPARE(vdiv(d2, d2, d2),
"ee822b02 vdiv.f64 d2, d2, d2");
COMPARE(vdiv(d6, d7, d7, hi),
"8e876b07 vdiv.f64hi d6, d7, d7");
COMPARE(vsqrt(d0, d0),
"eeb10bc0 vsqrt.f64 d0, d0");
COMPARE(vsqrt(d2, d3, ne),
"1eb12bc3 vsqrt.f64ne d2, d3");
}
VERIFY_RUN();
}

56
deps/v8/test/cctest/test-type-info.cc

@ -0,0 +1,56 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "cctest.h"
#include "type-info.h"
namespace v8 {
namespace internal {
TEST(ThreeBitRepresentation) {
// Numeric types and unknown should fit into the short
// representation.
CHECK(TypeInfo::ExpandedRepresentation(
TypeInfo::Unknown().ThreeBitRepresentation()).IsUnknown());
CHECK(TypeInfo::ExpandedRepresentation(
TypeInfo::Number().ThreeBitRepresentation()).IsNumber());
CHECK(TypeInfo::ExpandedRepresentation(
TypeInfo::Integer32().ThreeBitRepresentation()).IsInteger32());
CHECK(TypeInfo::ExpandedRepresentation(
TypeInfo::Smi().ThreeBitRepresentation()).IsSmi());
CHECK(TypeInfo::ExpandedRepresentation(
TypeInfo::Double().ThreeBitRepresentation()).IsDouble());
// Other types should map to unknown.
CHECK(TypeInfo::ExpandedRepresentation(
TypeInfo::Primitive().ThreeBitRepresentation()).IsUnknown());
CHECK(TypeInfo::ExpandedRepresentation(
TypeInfo::String().ThreeBitRepresentation()).IsUnknown());
}
} } // namespace v8::internal

2
deps/v8/test/es5conform/README

@ -4,7 +4,7 @@ tests from
https://es5conform.svn.codeplex.com/svn https://es5conform.svn.codeplex.com/svn
in revision 62998 as 'data' in this directory. Using later version in revision 71525 as 'data' in this directory. Using later version
may be possible but the tests are only known to pass (and indeed run) may be possible but the tests are only known to pass (and indeed run)
with that revision. with that revision.

217
deps/v8/test/es5conform/es5conform.status

@ -29,91 +29,107 @@ prefix es5conform
def UNIMPLEMENTED = PASS || FAIL def UNIMPLEMENTED = PASS || FAIL
def FAIL_OK = FAIL, OKAY def FAIL_OK = FAIL, OKAY
chapter07: UNIMPLEMENTED # Non UTF8 characters in test files.
chapter08: UNIMPLEMENTED chapter10/10.4/10.4.2/10.4.2-3-c-2-s: FAIL_OK
chapter10: UNIMPLEMENTED chapter10/10.4/10.4.2/10.4.2-3-c-1-s: FAIL_OK
chapter11: UNIMPLEMENTED chapter10/10.4/10.4.2/10.4.2-2-c-1: FAIL_OK
chapter12: UNIMPLEMENTED
chapter13: UNIMPLEMENTED # We do not implement the error chekcs specified in the production rules
chapter14: UNIMPLEMENTED # of 11.1.5 (Object initializer).
chapter15/15.1: UNIMPLEMENTED # We are compatible with Safari and Firefox.
chapter15/15.2/15.2.3/15.2.3.1: UNIMPLEMENTED chapter11/11.1/11.1.5: UNIMPLEMENTED
# Delete returns true in eval even when it should return false.
# Please see http://code.google.com/p/v8/issues/detail?id=759
chapter11/11.4/11.4.1//11.4.1-4.a-5: FAIL
chapter11/11.4/11.4.1//11.4.1-4.a-7: FAIL
# We do not have a global object called 'global' as required by tests.
chapter15/15.1: FAIL_OK
# NOT IMPLEMENTED: seal
chapter15/15.2/15.2.3/15.2.3.8: UNIMPLEMENTED chapter15/15.2/15.2.3/15.2.3.8: UNIMPLEMENTED
# NOT IMPLEMENTED: freeze
chapter15/15.2/15.2.3/15.2.3.9: UNIMPLEMENTED chapter15/15.2/15.2.3/15.2.3.9: UNIMPLEMENTED
# NOT IMPLEMENTED: preventExtensions
chapter15/15.2/15.2.3/15.2.3.10: UNIMPLEMENTED chapter15/15.2/15.2.3/15.2.3.10: UNIMPLEMENTED
# NOT IMPLEMENTED: isSealed
chapter15/15.2/15.2.3/15.2.3.11: UNIMPLEMENTED chapter15/15.2/15.2.3/15.2.3.11: UNIMPLEMENTED
# NOT IMPLEMENTED: isFrozen
chapter15/15.2/15.2.3/15.2.3.12: UNIMPLEMENTED chapter15/15.2/15.2.3/15.2.3.12: UNIMPLEMENTED
# NOT IMPLEMENTED: isExtensible
chapter15/15.2/15.2.3/15.2.3.13: UNIMPLEMENTED chapter15/15.2/15.2.3/15.2.3.13: UNIMPLEMENTED
# NOT IMPLEMENTED: seal # NOT IMPLEMENTED: seal
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-20: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-20: UNIMPLEMENTED
# NOT IMPLEMENTED: freeze # NOT IMPLEMENTED: freeze
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-21: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-21: UNIMPLEMENTED
# NOT IMPLEMENTED: preventExtensions # NOT IMPLEMENTED: preventExtensions
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-22: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-22: UNIMPLEMENTED
# NOT IMPLEMENTED: isSealed # NOT IMPLEMENTED: isSealed
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-23: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-23: UNIMPLEMENTED
# NOT IMPLEMENTED: isFrozen # NOT IMPLEMENTED: isFrozen
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-24: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-24: UNIMPLEMENTED
# NOT IMPLEMENTED: isExtensible # NOT IMPLEMENTED: isExtensible
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-25: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-25: UNIMPLEMENTED
# NOT IMPLEMENTED: bind # NOT IMPLEMENTED: bind
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-38: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-38: UNIMPLEMENTED
# NaN is writable # NaN is writable. We are compatible with JSC.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-178: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-178: FAIL_OK
# Infinity is writable # Infinity is writable. We are compatible with JSC.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-179: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-179: FAIL_OK
# undefined is writable # undefined is writable. We are compatible with JSC.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-180: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-180: FAIL_OK
# Our Function object has a "arguments" property which is used as a non # Our Function object has an "arguments" property which is used as a
# property in in the test # non-property in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK
# Our Function object has a "caller" property which is used as a non # Our Function object has a "caller" property which is used as a
# property in in the test # non-property in in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-184: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-184: FAIL_OK
# Our function object has a name property which is used as a non # Our function object has a name property which is used as a
# property in the test # non-property in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-188: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-188: FAIL_OK
# NOT IMPLEMENTED: RegExp.prototype.source # NOT IMPLEMENTED: RegExp.prototype.source
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-212: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-212: UNIMPLEMENTED
# NOT IMPLEMENTED: RegExp.prototype.global # NOT IMPLEMENTED: RegExp.prototype.global
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-213: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-213: UNIMPLEMENTED
# NOT IMPLEMENTED: RegExp.prototype.ignoreCase # NOT IMPLEMENTED: RegExp.prototype.ignoreCase
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-214: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-214: UNIMPLEMENTED
# NOT IMPLEMENTED: RegExp.prototype.multiline # NOT IMPLEMENTED: RegExp.prototype.multiline
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-215: FAIL_OK chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-215: UNIMPLEMENTED
# All of the tests below marked SUBSETFAIL (in 15.2.3.4) fail because # All of the tests below marked SUBSETFAIL (in 15.2.3.4) fail because
# the tests assumes that objects can not have more properties # the tests assumes that objects can not have more properties
# than those described in the spec - but according to spec they can # than those described in the spec - but according to spec they can
# have additional properties. # have additional properties.
# All compareArray calls in these tests could be exchanged with a # All compareArray calls in these tests could be exchanged with a
# isSubsetOfArray call (I will upload a path to the es5conform site) # isSubsetOfArray call (I will upload a path to the es5conform site).
# SUBSETFAIL # SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-1: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-1: FAIL_OK
# SUBSETFAIL + we do not implement all methods on Object # SUBSETFAIL + we do not implement all methods on Object.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-2: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-2: FAIL_OK
# SUBSETFAIL # SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-3: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-3: FAIL_OK
# SUBSETFAIL + we do not implement Function.prototype.bind # SUBSETFAIL + we do not implement Function.prototype.bind.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-4: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-4: FAIL_OK
# SUBSETFAIL # SUBSETFAIL
@ -134,29 +150,29 @@ chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-9: FAIL_OK
# SUBSETFAIL # SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-11: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-11: FAIL_OK
# We do not implement all methods on RegExp # We do not implement all methods on RegExp.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-13: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-13: FAIL
# SUBSETFAIL # SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-14: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-14: FAIL_OK
# EvalError.prototype does not have message property # EvalError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-15: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-15: FAIL
# Rangeerror.prototype does not have message property # Rangeerror.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-16: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-16: FAIL
# ReferenceError.prototype does not have message property # ReferenceError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-17: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-17: FAIL
# SyntaxError.prototype does not have message property # SyntaxError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-18: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-18: FAIL
# TypeError.prototype does not have message property # TypeError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-19: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-19: FAIL
# URIError.prototype does not have message property # URIError.prototype does not have message property.
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-20: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-20: FAIL
# SUBSETFAIL # SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-22: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-22: FAIL_OK
@ -200,68 +216,65 @@ chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-34: FAIL_OK
# SUBSETFAIL # SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-35: FAIL_OK chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-35: FAIL_OK
# NOT IMPLEMENTED: bind on Function.prototype.
chapter15/15.3/15.3.4/15.3.4.5/15.3.4.5-0-1: UNIMPLEMENTED
# We fail this because Object.keys returns numbers for element indices # Bad test - the spec does not say anything about throwing errors
# rather than strings. # on calling Array.prototype.indexOf with undefined as argument.
#chapter15/15.2/15.2.3/15.2.3.14/15.2.3.14-3-3: FAIL_OK chapter15/15.4/15.4.4/15.4.4.14/15.4.4.14-1-1: FAIL_OK
chapter15/15.3: UNIMPLEMENTED
chapter15/15.4/15.4.4/15.4.4.14: UNIMPLEMENTED
chapter15/15.4/15.4.4/15.4.4.15: UNIMPLEMENTED
chapter15/15.4/15.4.4/15.4.4.20: UNIMPLEMENTED
chapter15/15.4/15.4.4/15.4.4.21: UNIMPLEMENTED
chapter15/15.4/15.4.4/15.4.4.22: UNIMPLEMENTED
# Wrong test - because this is not given as argument to arr.every # Bad test - the spec does not say anything about throwing errors
# this._15_4_4_16_5_1 evaluates to undefined # on calling Array.prototype.indexOf with null as argument.
chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-5-1: FAIL_OK chapter15/15.4/15.4.4/15.4.4.14/15.4.4.14-1-2: FAIL_OK
# In test case the element is not appended - it is added in the middle of # Bad test - the test at the end should be "i === true".
# the array
chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-7-1: FAIL_OK
# We fail because the test assumes that if the reference to array is deleted it
# is not longer traversed
chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-7-7: FAIL_OK
# if (val>1) in test should be if (val>2)
chapter15/15.4/15.4.4/15.4.4.16/15.4.4.16-8-10: FAIL_OK
# Wrong assumption - according to spec some returns a Boolean, not a number
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-4-9: FAIL_OK
# Same as 15.4.4.16-5-1
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-5-1: FAIL_OK
# Same as 15.4.4.16-7-1
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-7-1: FAIL_OK
# Same as 15.4.4.16-7-7
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-7-7: FAIL_OK
# Same as 15.4.4.16-10-8
chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-8-10: FAIL_OK chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-8-10: FAIL_OK
# Same as 15.4.4.16-5-1 # Bad test - according to spec some returns a Boolean, not a number.
chapter15/15.4/15.4.4/15.4.4.18/15.4.4.18-5-1: FAIL_OK chapter15/15.4/15.4.4/15.4.4.17/15.4.4.17-4-9: FAIL_OK
# Same as 15.4.4.16-7-7
chapter15/15.4/15.4.4/15.4.4.18/15.4.4.18-7-6: FAIL_OK
# Same as 15.4.4.16-5-1
chapter15/15.4/15.4.4/15.4.4.19/15.4.4.19-5-1: FAIL_OK
# Same as 15.4.4.16-7-7
chapter15/15.4/15.4.4/15.4.4.19/15.4.4.19-8-7: FAIL_OK
chapter15/15.5: UNIMPLEMENTED # Bad test - uses unitialized variable a in precondition check.
chapter15/15.6: UNIMPLEMENTED chapter15/15.4/15.4.4/15.4.4.19/15.4.4.19-9-3: FAIL_OK
chapter15/15.7: UNIMPLEMENTED
chapter15/15.9: UNIMPLEMENTED # We do not implement Array mapping functions correctly if array
chapter15/15.10: UNIMPLEMENTED # entries are added for nonexistent entries smaller than length by
chapter15/15.12: UNIMPLEMENTED # the callback function. We are compatible with JSC.
# See http://code.google.com/p/v8/issues/detail?id=755
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-1: FAIL_OK
# Bad tests, path in test file is wrong. This will crash the test
# script so we mark it SKIP.
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-c-ii-4: SKIP
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-c-ii-4-s: SKIP
# Bad test - deleting the property on o in callbackfn will
# have no effect on the actual array on which reduceRight is called.
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-7: FAIL_OK
# We do not implement trim correctly on null and undefined.
chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-1-1: FAIL
chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-1-2: FAIL
# We do not correctly recognize \uFEFF as whitespace
chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-10: FAIL
chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-18: FAIL
chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-34: FAIL
# RegExp.prototype is not of type RegExp - we are bug compatible with JSC.
chapter15/15.10/15.10.6/15.10.6: FAIL_OK
# We do not have the properties of a RegExp instance on RegExp.prototype.
# The spec says we should - but we are currently bug compatible with JSC.
chapter15/15.10/15.10.7/15.10.7.1/15.10.7.1-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.1/15.10.7.1-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.2/15.10.7.2-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.2/15.10.7.2-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.3/15.10.7.3-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.3/15.10.7.3-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.4/15.10.7.4-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.4/15.10.7.4-2: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.5/15.10.7.5-1: FAIL_OK
chapter15/15.10/15.10.7/15.10.7.5/15.10.7.5-2: FAIL_OK
[ $arch == mips ] [ $arch == mips ]

12
deps/v8/test/mjsunit/debug-setbreakpoint.js

@ -63,6 +63,7 @@ function testArguments(dcp, arguments, success, is_script) {
} else { } else {
assertFalse(response.success, request + ' -> ' + json_response); assertFalse(response.success, request + ' -> ' + json_response);
} }
return response;
} }
function listener(event, exec_state, event_data, data) { function listener(event, exec_state, event_data, data) {
@ -118,6 +119,12 @@ function listener(event, exec_state, event_data, data) {
testArguments(dcp, '{"type":"script","target":"sourceUrlScript","line":0}', true, true); testArguments(dcp, '{"type":"script","target":"sourceUrlScript","line":0}', true, true);
// Set a break point on a line with the comment, and check that actual position
// is the next line after the comment.
request = '{"type":"scriptId","target":' + g_script_id + ',"line":' + (g_line + 1) + '}';
response = testArguments(dcp, request, true, false);
assertEquals(g_line + 2, response.body.actual_locations[0].line);
// Indicate that all was processed. // Indicate that all was processed.
listenerComplete = true; listenerComplete = true;
} }
@ -185,8 +192,3 @@ Debug.setListener(breakListener);
sourceUrlFunc(); sourceUrlFunc();
assertTrue(breakListenerCalled, "Break listener not called on breakpoint set by sourceURL"); assertTrue(breakListenerCalled, "Break listener not called on breakpoint set by sourceURL");
// Set a break point on a line with the comment, and check that actual position
// is the next line after the comment.
var number = Debug.setScriptBreakPointById(g_script_id, g_line + 1);
assertEquals(g_line + 2, Debug.findBreakPoint(number).actual_location.line);

25
deps/v8/test/mjsunit/math-sqrt.js

@ -27,18 +27,23 @@
// Tests the special cases specified by ES 15.8.2.17 // Tests the special cases specified by ES 15.8.2.17
function test(expected_sqrt, value) {
assertEquals(expected_sqrt, Math.sqrt(value));
if (isFinite(value)) {
assertEquals(expected_sqrt, Math.pow(value, 0.5));
}
}
// Simple sanity check // Simple sanity check
assertEquals(2, Math.sqrt(4)); test(2, 4);
assertEquals(0.1, Math.sqrt(0.01)); test(0.1, 0.01);
// Spec tests // Spec tests
assertEquals(NaN, Math.sqrt(NaN)); test(NaN, NaN);
assertEquals(NaN, Math.sqrt(-1)); test(NaN, -1);
assertEquals(+0, Math.sqrt(+0)); test(+0, +0);
assertEquals(-0, Math.sqrt(-0)); test(-0, -0);
assertEquals(Infinity, Math.sqrt(Infinity)); test(Infinity, Infinity);
// -Infinity is smaller than 0 so it should return NaN // -Infinity is smaller than 0 so it should return NaN
assertEquals(NaN, Math.sqrt(-Infinity)); test(NaN, -Infinity);

53
deps/v8/test/mjsunit/mod.js

@ -0,0 +1,53 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
function foo() {
for (var i = 1; i < 100; i++) {
var answer = 1;
for (var j = 1; j < 100; j++) {
if (answer == i) answer = 0;
// Positive case.
print(j + " % " + i + " = " + answer);
m = j % i;
assertEquals(answer, m, j + " % " + i);
m = j % (-i);
assertEquals(answer, m, j + " % -" + i);
// Negative case.
m = (-j) % i;
assertEquals(-answer, m, j + " % " + i);
// Check for negative zero.
if (answer == 0) assertEquals(-Infinity, 1/m);
m = (-j) % (-i);
assertEquals(-answer, m, j + " % -" + i);
// Check for negative zero.
if (answer == 0) assertEquals(-Infinity, 1/m);
answer++;
}
}
}
foo();

36
deps/v8/test/mjsunit/regress/regress-753.js

@ -0,0 +1,36 @@
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Test that JSON.stringify correctly truncates floating point numbers.
// This test is based on chapter15/15.12/15.12.3/15.12.3-6-a-2.js in the
// ES5 conformance tests.
// See: http://code.google.com/p/v8/issues/detail?id=753
var obj = {a1: {b1: [1,2,3,4], b2: {c1: 1, c2: 2}},a2: 'a2'};
assertEquals(JSON.stringify(obj,null, 5.99999), JSON.stringify(obj,null, 5));

86
deps/v8/test/mjsunit/to_number_order.js

@ -39,6 +39,14 @@ x = "";
assertEquals(2, Math.max(v,w)); assertEquals(2, Math.max(v,w));
assertEquals("hestfisk", x, "max"); assertEquals("hestfisk", x, "max");
x = "";
assertEquals(1, Math.max(v,v));
assertEquals("hesthest", x, "max_identical");
x = "";
assertEquals(2, Math.min(w,w));
assertEquals("fiskfisk", x, "max");
x = ""; x = "";
assertEquals(Math.atan2(1, 2), Math.atan2(v, w)); assertEquals(Math.atan2(1, 2), Math.atan2(v, w));
// JSC says fiskhest. // JSC says fiskhest.
@ -122,8 +130,86 @@ x = "";
new Date().setUTCFullYear(year, month, date, hours, minutes, seconds, ms); new Date().setUTCFullYear(year, month, date, hours, minutes, seconds, ms);
assertEquals("123", x, "Date.setUTCFullYear"); assertEquals("123", x, "Date.setUTCFullYear");
x = "";
var a = { valueOf: function() { x += "hest"; return 97; } }; var a = { valueOf: function() { x += "hest"; return 97; } };
var b = { valueOf: function() { x += "fisk"; return 98; } }; var b = { valueOf: function() { x += "fisk"; return 98; } };
assertEquals("ab", String.fromCharCode(a, b), "String.fromCharCode"); assertEquals("ab", String.fromCharCode(a, b), "String.fromCharCode");
assertEquals("hestfisk", x, "String.fromCharCode valueOf order");
// Test whether valueOf is called when comparing identical objects
x = "";
assertTrue(a < b, "Compare objects a < b");
assertEquals("hestfisk", x, "Compare objects a < b valueOf order");
x = "";
assertFalse(a < a, "Compare objects a < a");
// assertEquals("hesthest", x, "Compare objects a < a valueOf order");
x = "";
assertTrue(a == a, "Compare objects a == a");
assertEquals("", x, "Compare objects a == a valueOf not called");
x = "";
assertFalse(b > b, "Compare objects b > b");
assertEquals("fiskfisk", x, "Compare objects b > b valueOf order");
x = "";
assertTrue(b >= b, "Compare objects b >= b");
assertEquals("fiskfisk", x, "Compare objects b >= b valueOf order");
x = "";
assertFalse(a > b, "Compare objects a > b");
assertEquals("fiskhest", x, "Compare objects a > b valueOf order");
x = "";
assertFalse(a > void(0), "Compare objects a > undefined");
assertEquals("hest", x, "Compare objects a > undefined valueOf order");
x = "";
assertFalse(void(0) > b, "Compare objects undefined > b");
assertEquals("fisk", x, "Compare objects undefined > b valueOf order");
function identical_object_comparison() {
x = "";
assertTrue(a < b, "Compare objects a < b");
assertEquals("hestfisk", x, "Compare objects a < b valueOf order");
x = "";
assertFalse(a < a, "Compare objects a < a");
// assertEquals("hesthest", x, "Compare objects a < a valueOf order");
x = "";
assertTrue(a == a, "Compare objects a == a");
assertEquals("", x, "Compare objects a == a valueOf not called");
x = "";
assertFalse(b > b, "Compare objects b > b");
assertEquals("fiskfisk", x, "Compare objects b > b valueOf order");
x = "";
assertTrue(b >= b, "Compare objects b >= b");
assertEquals("fiskfisk", x, "Compare objects b >= b valueOf order");
x = "";
assertFalse(a > b, "Compare objects a > b");
assertEquals("fiskhest", x, "Compare objects a > b valueOf order");
x = "";
assertFalse(a > void(0), "Compare objects a > undefined");
assertEquals("hest", x, "Compare objects a > undefined valueOf order");
x = "";
assertFalse(void(0) > b, "Compare objects undefined > b");
assertEquals("fisk", x, "Compare objects undefined > b valueOf order");
}
// Call inside loop to test optimization and possible caching.
for (i = 0; i < 3; ++i) {
identical_object_comparison();
}
print("ok"); print("ok");

52
deps/v8/test/mozilla/mozilla.status

@ -26,13 +26,13 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This file is up to date with respect to Mozilla's CVS repository as of # This file is up to date with respect to Mozilla's CVS repository as of
# 2008-09-02. If new tests are added to Mozilla's CVS it may need to be # 2010-06-29. If new tests are added to Mozilla's CVS it may need to be
# updated. # updated.
# To get the mozilla tests: # To get the mozilla tests:
# cd /path/to/checkout/test/mozilla # cd /path/to/checkout/test/mozilla
# rm -rf data # rm -rf data
# cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -D 2008-09-02 mozilla/js/tests # cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -D 2010-06-29 mozilla/js/tests
# mv mozilla/js/tests data # mv mozilla/js/tests data
# rm -rf mozilla # rm -rf mozilla
@ -53,6 +53,10 @@ def FAIL_OK = FAIL, OKAY
js1_5/Regress/regress-271716-n: SKIP js1_5/Regress/regress-271716-n: SKIP
# This test uses a unitialized variable. A Bug has been filed:
# https://bugzilla.mozilla.org/show_bug.cgi?id=575575
js1_5/Array/regress-465980-02: SKIP
# These tests are simply wrong (i.e., they do not test what they intend # These tests are simply wrong (i.e., they do not test what they intend
# to test). # to test).
# In particular, these two compare numbers to NaN with != in the current # In particular, these two compare numbers to NaN with != in the current
@ -226,6 +230,10 @@ ecma_3/Function/regress-313570: FAIL_OK
# toPrecision argument restricted to range 1..21 in JSC/V8 # toPrecision argument restricted to range 1..21 in JSC/V8
js1_5/Regress/regress-452346: FAIL_OK js1_5/Regress/regress-452346: FAIL_OK
ecma_3/Number/15.7.4.7-1: FAIL_OK
# toExponential argument restricted to range 0..20 in JSC/V8
ecma_3/Number/15.7.4.6-1: FAIL_OK
# Array.prototype.slice with zero arguments return undefined in JSC/V8, # Array.prototype.slice with zero arguments return undefined in JSC/V8,
# empty array in Spider/TraceMonkey. # empty array in Spider/TraceMonkey.
@ -234,8 +242,9 @@ js1_5/Array/regress-451483: FAIL_OK
#:=== RegExp:=== #:=== RegExp:===
# To be compatible with JSC we silently ignore flags that do not make # To be compatible with JSC we silently ignore flags that do not make
# sense. This test expects us to throw exceptions. # sense. These tests expects us to throw exceptions.
ecma_3/RegExp/regress-57631: FAIL_OK ecma_3/RegExp/regress-57631: FAIL_OK
ecma_3/RegExp/15.10.4.1-6: FAIL_OK
# PCRE doesn't allow subpattern nesting deeper than 200, this tests # PCRE doesn't allow subpattern nesting deeper than 200, this tests
# depth 500. JSC detects the case, and return null from the match, # depth 500. JSC detects the case, and return null from the match,
@ -315,6 +324,11 @@ js1_5/Regress/regress-234389: FAIL_OK
js1_5/Regress/regress-320119: FAIL_OK js1_5/Regress/regress-320119: FAIL_OK
# We do not recognize a multiline comment as newline character.
# We are compatible with JSC.
ecma_3/LexicalConventions/7.4-01: FAIL_OK
# No support for toSource(). # No support for toSource().
js1_5/Regress/regress-248444: FAIL_OK js1_5/Regress/regress-248444: FAIL_OK
js1_5/Regress/regress-313967-01: FAIL_OK js1_5/Regress/regress-313967-01: FAIL_OK
@ -347,6 +361,7 @@ ecma/GlobalObject/15.1.2.7: FAIL_OK
# print strings for errors. Non-ECMA behavior. # print strings for errors. Non-ECMA behavior.
js1_2/function/tostring-2: FAIL_OK js1_2/function/tostring-2: FAIL_OK
js1_2/Objects/toString-001: FAIL_OK js1_2/Objects/toString-001: FAIL_OK
js1_5/LexicalConventions/regress-469940: FAIL_OK
js1_5/Exceptions/regress-332472: FAIL_OK js1_5/Exceptions/regress-332472: FAIL_OK
js1_5/Regress/regress-173067: FAIL_OK js1_5/Regress/regress-173067: FAIL_OK
js1_5/Regress/regress-355556: FAIL_OK js1_5/Regress/regress-355556: FAIL_OK
@ -386,11 +401,7 @@ js1_5/decompilation/regress-461110: FAIL_OK
# Tests that use uneval. Non-ECMA. # Tests that use uneval. Non-ECMA.
js1_5/GC/regress-418128: FAIL_OK js1_5/GC/regress-418128: FAIL_OK
js1_5/extensions/regress-465276: FAIL_OK js1_5/extensions/regress-465276: FAIL_OK
js1_5/Error/regress-465377: FAIL_OK
# Tests that use __count__. Non-ECMA.
js1_5/extensions/regress-434837-01: FAIL_OK
# Tests that use the watch method. Non-ECMA. # Tests that use the watch method. Non-ECMA.
js1_5/extensions/regress-435345-01: FAIL_OK js1_5/extensions/regress-435345-01: FAIL_OK
@ -432,6 +443,7 @@ js1_5/Object/regress-362872-01: FAIL_OK
js1_5/Object/regress-362872-02: FAIL_OK js1_5/Object/regress-362872-02: FAIL_OK
js1_5/Regress/regress-361467: FAIL_OK js1_5/Regress/regress-361467: FAIL_OK
js1_5/Regress/regress-385393-06: FAIL_OK js1_5/Regress/regress-385393-06: FAIL_OK
js1_5/Regress/regress-506567: FAIL_OK
# Use special Mozilla getter/setter syntax # Use special Mozilla getter/setter syntax
@ -484,6 +496,11 @@ js1_2/Array/array_split_1: FAIL_OK
# The concat() method is defined in Array.prototype; not Array. # The concat() method is defined in Array.prototype; not Array.
js1_5/Array/regress-313153: FAIL_OK js1_5/Array/regress-313153: FAIL_OK
# The join() method is defined on Array.prototype; not Array.
js1_5/Array/regress-474529: FAIL_OK
# The lastIndexOf() method is defined on Array.prototype, not Array.
ecma_3/Array/15.5.4.8-01: FAIL_OK
# Properties fileName, and lineNumber of Error instances are # Properties fileName, and lineNumber of Error instances are
# not supported. Mozilla specific extension. # not supported. Mozilla specific extension.
@ -552,6 +569,10 @@ js1_5/Regress/regress-352604: FAIL_OK
js1_5/Regress/regress-417893: FAIL_OK js1_5/Regress/regress-417893: FAIL_OK
# Unsupported use of "[]" as function parameter. We match JSC.
js1_5/Regress/regress-416737-01: FAIL_OK
js1_5/Regress/regress-416737-02: FAIL_OK
##################### FAILING TESTS ##################### ##################### FAILING TESTS #####################
@ -596,6 +617,11 @@ ecma_3/String/15.5.4.11: FAIL
# Marked as: Will not fix. V8 throws an acceptable RangeError. # Marked as: Will not fix. V8 throws an acceptable RangeError.
js1_5/Expressions/regress-394673: FAIL js1_5/Expressions/regress-394673: FAIL
# Bug 762: http://code.google.com/p/v8/issues/detail?id=762
# We do not correctly handle assignments within "with"
/ecma_3/Statements/12.10-01: FAIL
##################### MOZILLA EXTENSION TESTS ##################### ##################### MOZILLA EXTENSION TESTS #####################
ecma/extensions/15.1.2.1-1: FAIL_OK ecma/extensions/15.1.2.1-1: FAIL_OK
@ -674,6 +700,9 @@ js1_5/extensions/regress-365869: FAIL_OK
js1_5/extensions/regress-367630: FAIL_OK js1_5/extensions/regress-367630: FAIL_OK
js1_5/extensions/regress-367923: FAIL_OK js1_5/extensions/regress-367923: FAIL_OK
js1_5/extensions/regress-368859: FAIL_OK js1_5/extensions/regress-368859: FAIL_OK
js1_5/extensions/regress-369696-01: FAIL_OK
js1_5/extensions/regress-369696-02: FAIL_OK
js1_5/extensions/regress-369696-03: FAIL_OK
js1_5/extensions/regress-374589: FAIL_OK js1_5/extensions/regress-374589: FAIL_OK
js1_5/extensions/regress-375801: FAIL_OK js1_5/extensions/regress-375801: FAIL_OK
js1_5/extensions/regress-376052: FAIL_OK js1_5/extensions/regress-376052: FAIL_OK
@ -693,6 +722,11 @@ js1_5/extensions/regress-420612: FAIL_OK
js1_5/extensions/regress-420869-01: FAIL_OK js1_5/extensions/regress-420869-01: FAIL_OK
js1_5/extensions/regress-424257: FAIL_OK js1_5/extensions/regress-424257: FAIL_OK
js1_5/extensions/regress-424683-01: FAIL_OK js1_5/extensions/regress-424683-01: FAIL_OK
js1_5/extensions/regress-429739: FAIL_OK
js1_5/extensions/regress-454142: FAIL_OK
js1_5/extensions/regress-465145: FAIL_OK
js1_5/extensions/regress-469625: FAIL_OK
js1_5/extensions/regress-472787: FAIL_OK
js1_5/extensions/regress-44009: FAIL_OK js1_5/extensions/regress-44009: FAIL_OK
js1_5/extensions/regress-50447-1: FAIL_OK js1_5/extensions/regress-50447-1: FAIL_OK
js1_5/extensions/regress-50447: FAIL_OK js1_5/extensions/regress-50447: FAIL_OK
@ -771,7 +805,7 @@ js1_5/decompilation/regress-375882: PASS || FAIL
js1_5/decompilation/regress-376564: PASS || FAIL js1_5/decompilation/regress-376564: PASS || FAIL
js1_5/decompilation/regress-383721: PASS || FAIL js1_5/decompilation/regress-383721: PASS || FAIL
js1_5/decompilation/regress-406555: PASS || FAIL js1_5/decompilation/regress-406555: PASS || FAIL
js1_5/decompilation/regress-460870: PASS || FAIL
# These tests take an unreasonable amount of time so we skip them # These tests take an unreasonable amount of time so we skip them
# in fast mode. # in fast mode.

26
deps/v8/tools/stats-viewer.py

@ -34,8 +34,8 @@ The stats viewer reads counters from a binary file and displays them
in a window, re-reading and re-displaying with regular intervals. in a window, re-reading and re-displaying with regular intervals.
""" """
import mmap import mmap
import optparse
import os import os
import re import re
import struct import struct
@ -60,13 +60,15 @@ CHROME_COUNTERS_FILE_MAGIC_NUMBER = 0x13131313
class StatsViewer(object): class StatsViewer(object):
"""The main class that keeps the data used by the stats viewer.""" """The main class that keeps the data used by the stats viewer."""
def __init__(self, data_name): def __init__(self, data_name, name_filter):
"""Creates a new instance. """Creates a new instance.
Args: Args:
data_name: the name of the file containing the counters. data_name: the name of the file containing the counters.
name_filter: The regexp filter to apply to counter names.
""" """
self.data_name = data_name self.data_name = data_name
self.name_filter = name_filter
# The handle created by mmap.mmap to the counters file. We need # The handle created by mmap.mmap to the counters file. We need
# this to clean it up on exit. # this to clean it up on exit.
@ -224,6 +226,7 @@ class StatsViewer(object):
sorted_groups.sort() sorted_groups.sort()
for counter_name in sorted_groups: for counter_name in sorted_groups:
counter_objs = groups[counter_name] counter_objs = groups[counter_name]
if self.name_filter.match(counter_name):
name = Tkinter.Label(self.root, width=50, anchor=Tkinter.W, name = Tkinter.Label(self.root, width=50, anchor=Tkinter.W,
text=counter_name) text=counter_name)
name.grid(row=index, column=0, padx=1, pady=1) name.grid(row=index, column=0, padx=1, pady=1)
@ -232,6 +235,7 @@ class StatsViewer(object):
counter = counter_objs[i] counter = counter_objs[i]
name = counter.Name() name = counter.Name()
var = Tkinter.StringVar() var = Tkinter.StringVar()
if self.name_filter.match(name):
value = Tkinter.Label(self.root, width=15, anchor=Tkinter.W, value = Tkinter.Label(self.root, width=15, anchor=Tkinter.W,
textvariable=var) textvariable=var)
value.grid(row=index, column=(1 + i), padx=1, pady=1) value.grid(row=index, column=(1 + i), padx=1, pady=1)
@ -440,17 +444,25 @@ class ChromeCounterCollection(object):
self.counter_values_offset + i * self.max_threads * 4) self.counter_values_offset + i * self.max_threads * 4)
def Main(data_file): def Main(data_file, name_filter):
"""Run the stats counter. """Run the stats counter.
Args: Args:
data_file: The counters file to monitor. data_file: The counters file to monitor.
name_filter: The regexp filter to apply to counter names.
""" """
StatsViewer(data_file).Run() StatsViewer(data_file, name_filter).Run()
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) != 2: parser = optparse.OptionParser("usage: %prog [--filter=re] "
print "Usage: stats-viewer.py <stats data>|<test_shell pid>" "<stats data>|<test_shell pid>")
parser.add_option("--filter",
default=".*",
help=("regexp filter for counter names "
"[default: %default]"))
(options, args) = parser.parse_args()
if len(args) != 1:
parser.print_help()
sys.exit(1) sys.exit(1)
Main(sys.argv[1]) Main(args[0], re.compile(options.filter))

Loading…
Cancel
Save