diff --git a/core/src/main/java/org/teavm/ast/optimization/OptimizingVisitor.java b/core/src/main/java/org/teavm/ast/optimization/OptimizingVisitor.java index f12aaf75a..70fae9542 100644 --- a/core/src/main/java/org/teavm/ast/optimization/OptimizingVisitor.java +++ b/core/src/main/java/org/teavm/ast/optimization/OptimizingVisitor.java @@ -654,11 +654,14 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { if (statements.isEmpty()) { return; } + + boolean shouldOptimizeBreaks = !hitsRedundantBreakThreshold(statements, exit); + for (int i = 0; i < statements.size(); ++i) { Statement stmt = statements.get(i); if (stmt instanceof ConditionalStatement) { ConditionalStatement cond = (ConditionalStatement) stmt; - check_conditional: { + check_conditional: if (shouldOptimizeBreaks) { last = cond.getConsequent().isEmpty() ? null : cond.getConsequent().get(cond.getConsequent().size() - 1); if (last instanceof BreakStatement) { @@ -724,6 +727,37 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { } } + private boolean hitsRedundantBreakThreshold(List statements, IdentifiedStatement exit) { + int count = 0; + for (int i = 0; i < statements.size(); ++i) { + Statement stmt = statements.get(i); + if (!(stmt instanceof ConditionalStatement)) { + continue; + } + + ConditionalStatement conditional = (ConditionalStatement) stmt; + if (!conditional.getConsequent().isEmpty() && !conditional.getAlternative().isEmpty()) { + continue; + } + List innerStatements = !conditional.getConsequent().isEmpty() + ? conditional.getConsequent() : conditional.getAlternative(); + if (innerStatements.isEmpty()) { + continue; + } + + Statement last = innerStatements.get(innerStatements.size() - 1); + if (!(last instanceof BreakStatement)) { + continue; + } + + BreakStatement breakStmt = (BreakStatement) last; + if (exit != null && exit == breakStmt.getTarget() && ++count == 8) { + return true; + } + } + + return false; + } private void normalizeConditional(ConditionalStatement stmt) { if (stmt.getConsequent().isEmpty()) { diff --git a/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java b/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java index 58637aebd..3c0c6ae0a 100644 --- a/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java +++ b/core/src/main/java/org/teavm/backend/c/generate/StringPoolGenerator.java @@ -56,43 +56,55 @@ public class StringPoolGenerator { } private void generateSimpleStringLiteral(String string) { - writer.print("u\""); - - for (int j = 0; j < string.length(); ++j) { - char c = string.charAt(j); - switch (c) { - case '\\': - writer.print("\\\\"); - break; - case '"': - writer.print("\\\""); - break; - case '\r': - writer.print("\\r"); - break; - case '\n': - writer.print("\\n"); - break; - case '\t': - writer.print("\\t"); - break; - default: - if (c < 32) { - writer.print("\\0" + Character.forDigit(c >> 3, 8) + Character.forDigit(c & 0x7, 8)); - } else if (c > 127) { - writer.print("\\u" - + Character.forDigit(c >> 12, 16) - + Character.forDigit((c >> 8) & 15, 16) - + Character.forDigit((c >> 4) & 15, 16) - + Character.forDigit(c & 15, 16)); - } else { - writer.print(String.valueOf(c)); - } - break; - } + if (string.isEmpty()) { + writer.print("u\"\""); + return; } - writer.print("\""); + int chunkSize = 256; + for (int i = 0; i < string.length(); i += chunkSize) { + if (i > 0) { + writer.println(); + } + int last = Math.min(i + chunkSize, string.length()); + writer.print("u\""); + + for (int j = i; j < last; ++j) { + char c = string.charAt(j); + switch (c) { + case '\\': + writer.print("\\\\"); + break; + case '"': + writer.print("\\\""); + break; + case '\r': + writer.print("\\r"); + break; + case '\n': + writer.print("\\n"); + break; + case '\t': + writer.print("\\t"); + break; + default: + if (c < 32) { + writer.print("\\0" + Character.forDigit(c >> 3, 8) + Character.forDigit(c & 0x7, 8)); + } else if (c > 127) { + writer.print("\\u" + + Character.forDigit(c >> 12, 16) + + Character.forDigit((c >> 8) & 15, 16) + + Character.forDigit((c >> 4) & 15, 16) + + Character.forDigit(c & 15, 16)); + } else { + writer.print(String.valueOf(c)); + } + break; + } + } + + writer.print("\""); + } } private void generateNumericStringLiteral(String string) { diff --git a/core/src/main/java/org/teavm/common/RangeTree.java b/core/src/main/java/org/teavm/common/RangeTree.java index 3799a008e..57a6a4759 100644 --- a/core/src/main/java/org/teavm/common/RangeTree.java +++ b/core/src/main/java/org/teavm/common/RangeTree.java @@ -88,7 +88,7 @@ public class RangeTree { for (Range range : ranges) { rangeList.add(range); } - Collections.sort(rangeList, (o1, o2) -> { + rangeList.sort((o1, o2) -> { if (o1.right != o2.right) { return o2.right - o1.right; } diff --git a/core/src/main/resources/org/teavm/backend/c/runtime.c b/core/src/main/resources/org/teavm/backend/c/runtime.c index ce78b44fd..e47ecaa89 100644 --- a/core/src/main/resources/org/teavm/backend/c/runtime.c +++ b/core/src/main/resources/org/teavm/backend/c/runtime.c @@ -200,13 +200,6 @@ static int64_t currentTimeMillis() { return time.tv_sec * 1000 + (int64_t) round(time.tv_nsec / 1000000); } - -static int32_t teavm_timeZoneOffset() { - time_t t = time(NULL); - time_t local = mktime(localtime(&t)); - time_t utc = mktime(gmtime(&t)); - return difftime(utc, local) / 60; -} #endif #ifdef _MSC_VER @@ -271,3 +264,10 @@ static int64_t currentTimeMillis() { return (int64_t) ((current - start) / 10000); } #endif + +static int32_t teavm_timeZoneOffset() { + time_t t = time(NULL); + time_t local = mktime(localtime(&t)); + time_t utc = mktime(gmtime(&t)); + return difftime(utc, local) / 60; +} \ No newline at end of file