diff --git a/pkg/compiler/lib/src/ssa/validate.dart b/pkg/compiler/lib/src/ssa/validate.dart index 99a8f5a9a66..f53f94f019d 100644 --- a/pkg/compiler/lib/src/ssa/validate.dart +++ b/pkg/compiler/lib/src/ssa/validate.dart @@ -133,9 +133,17 @@ class HValidator extends HInstructionVisitor { super.visitBasicBlock(block); } + // Limit for the size of `inputs` and `usedBy` lists. We assume lists longer + // than this are OK in order to avoid the O(N^2) validation getting out of + // hand. + // + // Poster child: corelib_2/regexp/pcre_test.dart, which has a 7KLOC main(). + static const int kMaxValidatedInstructionListLength = 1000; + /// Verifies [instruction] is contained in [instructions] [count] times. static bool checkInstructionCount( List instructions, HInstruction instruction, int count) { + if (instructions.length > kMaxValidatedInstructionListLength) return true; int result = 0; for (int i = 0; i < instructions.length; i++) { if (identical(instructions[i], instruction)) result++; @@ -146,7 +154,9 @@ class HValidator extends HInstructionVisitor { /// Returns true if the predicate returns true for every instruction in the /// list. The argument to [f] is an instruction with the count of how often /// it appeared in the list [instructions]. - static bool everyInstruction(List instructions, Function f) { + static bool everyInstruction( + List instructions, bool Function(HInstruction, int) f) { + if (instructions.length > kMaxValidatedInstructionListLength) return true; var copy = new List.from(instructions); // TODO(floitsch): there is currently no way to sort HInstructions before // we have assigned an ID. The loop is therefore O(n^2) for now. diff --git a/tests/compiler/dart2js/analyses/dart2js_allowed.json b/tests/compiler/dart2js/analyses/dart2js_allowed.json index 0b70e2e52c8..ff6c98ad732 100644 --- a/tests/compiler/dart2js/analyses/dart2js_allowed.json +++ b/tests/compiler/dart2js/analyses/dart2js_allowed.json @@ -146,6 +146,15 @@ "Dynamic invocation of '-'.": 1, "Dynamic invocation of '+'.": 1 }, + "pkg/compiler/lib/src/serialization/binary_sink.dart": { + "Dynamic access of 'index'.": 1 + }, + "pkg/compiler/lib/src/native/behavior.dart": { + "Dynamic invocation of 'add'.": 1 + }, + "pkg/compiler/lib/src/util/enumset.dart": { + "Dynamic access of 'index'.": 4 + }, "pkg/compiler/lib/src/constants/constant_system.dart": { "Dynamic invocation of '&'.": 1, "Dynamic invocation of '|'.": 1, @@ -165,9 +174,6 @@ "Dynamic invocation of '>='.": 1, "Dynamic invocation of 'codeUnitAt'.": 1 }, - "pkg/compiler/lib/src/serialization/binary_sink.dart": { - "Dynamic access of 'index'.": 1 - }, "third_party/pkg/dart2js_info/lib/json_info_codec.dart": { "Dynamic invocation of '[]'.": 11, "Dynamic invocation of 'forEach'.": 2, @@ -177,12 +183,6 @@ "third_party/pkg/dart2js_info/lib/binary_serialization.dart": { "Dynamic invocation of 'cast'.": 1 }, - "pkg/compiler/lib/src/util/enumset.dart": { - "Dynamic access of 'index'.": 4 - }, - "pkg/compiler/lib/src/native/enqueue.dart": { - "Dynamic access of 'isDynamic'.": 1 - }, "pkg/compiler/lib/src/inferrer/inferrer_engine.dart": { "Dynamic access of 'isVoid'.": 1, "Dynamic access of 'isDynamic'.": 1, @@ -195,8 +195,8 @@ "pkg/compiler/lib/src/universe/side_effects.dart": { "Dynamic access of 'universe.side_effects::_flags'.": 1 }, - "pkg/compiler/lib/src/native/behavior.dart": { - "Dynamic invocation of 'add'.": 1 + "pkg/compiler/lib/src/native/enqueue.dart": { + "Dynamic access of 'isDynamic'.": 1 }, "pkg/compiler/lib/src/ssa/builder_kernel.dart": { "Dynamic update to 'instantiatedTypes'.": 1, @@ -211,17 +211,11 @@ "Dynamic access of 'treatAsDynamic'.": 1, "Dynamic access of 'element'.": 1 }, - "pkg/compiler/lib/src/ssa/validate.dart": { - "Dynamic invocation of 'isInBasicBlock'.": 2, - "Dynamic access of 'usedBy'.": 2, - "Dynamic access of 'inputs'.": 1 - }, - "third_party/pkg/dart2js_info/lib/src/util.dart": { - "Dynamic access of 'name'.": 1, - "Dynamic invocation of '-'.": 1 - }, - "third_party/pkg/dart2js_info/lib/src/binary/sink.dart": { - "Dynamic access of 'index'.": 1 + "pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": { + "Dynamic access of 'keys'.": 1, + "Dynamic invocation of 'toSet'.": 1, + "Dynamic invocation of '[]='.": 1, + "Dynamic invocation of 'add'.": 1 }, "pkg/js_ast/lib/src/builder.dart": { "Dynamic invocation of 'call'.": 2 @@ -235,6 +229,13 @@ "Dynamic invocation of '[]'.": 9, "Dynamic invocation of 'toStatement'.": 3 }, + "third_party/pkg/dart2js_info/lib/src/util.dart": { + "Dynamic access of 'name'.": 1, + "Dynamic invocation of '-'.": 1 + }, + "third_party/pkg/dart2js_info/lib/src/binary/sink.dart": { + "Dynamic access of 'index'.": 1 + }, "pkg/compiler/lib/src/inferrer/type_graph_nodes.dart": { "Dynamic invocation of 'add'.": 1, "Dynamic invocation of 'remove'.": 1, @@ -250,16 +251,14 @@ "Dynamic access of 'named'.": 2, "Dynamic invocation of '[]'.": 2 }, - "pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart": { - "Dynamic access of 'keys'.": 1, - "Dynamic invocation of 'toSet'.": 1, - "Dynamic invocation of '[]='.": 1, - "Dynamic invocation of 'add'.": 1 - }, "pkg/compiler/lib/src/universe/function_set.dart": { "Dynamic access of 'selector'.": 1, "Dynamic access of 'receiver'.": 1 }, + "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart": { + "Dynamic access of 'superclass'.": 1, + "Dynamic access of 'needsTearOff'.": 1 + }, "pkg/compiler/lib/src/ssa/variable_allocator.dart": { "Dynamic access of 'usedBy'.": 1, "Dynamic access of 'isEmpty'.": 1, @@ -275,9 +274,5 @@ }, "pkg/compiler/lib/src/ssa/value_set.dart": { "Dynamic invocation of 'add'.": 2 - }, - "pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart": { - "Dynamic access of 'superclass'.": 1, - "Dynamic access of 'needsTearOff'.": 1 } } \ No newline at end of file