From 6b0104f9032b3dcfd05ef4a0cf8cde2ffb056853 Mon Sep 17 00:00:00 2001 From: David Mandelin Date: Mon, 16 Aug 2010 18:56:04 -0700 Subject: [PATCH] Bug 570663: turn a tableswitch on trace into a no-op if it has no cases, r=njn --- js/src/jstracer.cpp | 13 +++++++++++-- js/src/trace-test/tests/basic/bug570663-1.js | 4 ++++ js/src/trace-test/tests/basic/bug570663-2.js | 12 ++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 js/src/trace-test/tests/basic/bug570663-1.js create mode 100644 js/src/trace-test/tests/basic/bug570663-2.js diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 723d991e8a6..c499dc2eaf1 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -8731,13 +8731,22 @@ TraceRecorder::tableswitch() high = GET_JUMPX_OFFSET(pc); } + /* + * If there are no cases, this is a no-op. The default case immediately + * follows in the bytecode and is always taken, so we need no special + * action to handle it. + */ + int count = high + 1 - low; + if (count == 0) + return ARECORD_CONTINUE; + /* Cap maximum table-switch size for modesty. */ - if ((high + 1 - low) > MAX_TABLE_SWITCH) + if (count > MAX_TABLE_SWITCH) return InjectStatus(switchop()); /* Generate switch LIR. */ SwitchInfo* si = new (traceAlloc()) SwitchInfo(); - si->count = high + 1 - low; + si->count = count; si->table = 0; si->index = (uint32) -1; LIns* diff = lir->ins2(LIR_subi, v_ins, lir->insImmI(low)); diff --git a/js/src/trace-test/tests/basic/bug570663-1.js b/js/src/trace-test/tests/basic/bug570663-1.js new file mode 100644 index 00000000000..08f14ecf7ae --- /dev/null +++ b/js/src/trace-test/tests/basic/bug570663-1.js @@ -0,0 +1,4 @@ +// don't crash +for (var a = 0; a < 4; a++) { + switch (NaN) {} +} diff --git a/js/src/trace-test/tests/basic/bug570663-2.js b/js/src/trace-test/tests/basic/bug570663-2.js new file mode 100644 index 00000000000..bc4b08869da --- /dev/null +++ b/js/src/trace-test/tests/basic/bug570663-2.js @@ -0,0 +1,12 @@ +function f() { + var x; + for (var a = 0; a < 4; a++) { + switch (NaN) { + default: + x = a; + } + } + assertEq(x, 3); +} + +f();