From 84458ec18ce33295636f7b26b8e3ff25ecb349f2 Mon Sep 17 00:00:00 2001 From: Rohitash Kumar Date: Wed, 16 Apr 2025 16:08:31 +0000 Subject: [PATCH] 8353013: java.net.URI.create(String) may have low performance to scan the host/domain name from URI string when the hostname starts with number Reviewed-by: michaelm, xpeng --- src/java.base/share/classes/java/net/URI.java | 15 ++++- test/jdk/java/net/URI/Test.java | 38 +++++++++++- .../net/URIAuthorityParsingBenchmark.java | 62 +++++++++++++++++++ 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 test/micro/org/openjdk/bench/java/net/URIAuthorityParsingBenchmark.java diff --git a/src/java.base/share/classes/java/net/URI.java b/src/java.base/share/classes/java/net/URI.java index 2e6f2409bf4..cd116f3877b 100644 --- a/src/java.base/share/classes/java/net/URI.java +++ b/src/java.base/share/classes/java/net/URI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3426,6 +3426,19 @@ public final class URI int p = start; int q = scan(p, n, L_DIGIT, H_DIGIT); if (q <= p) return q; + + // Handle leading zeros + int i = p, j; + while ((j = scan(i, q, '0')) > i) i = j; + + // Calculate the number of significant digits (after leading zeros) + int significantDigitsNum = q - i; + + if (significantDigitsNum < 3) return q; // definitely < 255 + + // If more than 3 significant digits, it's definitely > 255 + if (significantDigitsNum > 3) return p; + if (Integer.parseInt(input, p, q, 10) > 255) return p; return q; } diff --git a/test/jdk/java/net/URI/Test.java b/test/jdk/java/net/URI/Test.java index 00d473f87be..95dd49ea34f 100644 --- a/test/jdk/java/net/URI/Test.java +++ b/test/jdk/java/net/URI/Test.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* @test * @summary Unit test for java.net.URI * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 7041800 - * 7171415 6339649 6933879 8037396 8272072 8051627 8297687 + * 7171415 6339649 6933879 8037396 8272072 8051627 8297687 8353013 * @author Mark Reinhold */ @@ -1620,6 +1620,7 @@ public class Test { b8051627(); b8272072(); b8297687(); + b8353013(); } private static void b8297687() { @@ -1786,6 +1787,39 @@ public class Test { } } + // 8353013 - Increase test coverage for cases where the authority component of a hierarchical + // URI has a host component that starts with a number. + private static void b8353013() { + testCreate("https://0.0.0.1").s("https").h("0.0.0.1").p("").z(); + testCreate("https://00.0.0.2").s("https").h("00.0.0.2").p("").z(); + testCreate("https://000.0.0.3").s("https").h("000.0.0.3").p("").z(); + testCreate("https://0000.0.0.4").s("https").h("0000.0.0.4").p("").z(); + + testCreate("https://00000.0.0.5").s("https").h("00000.0.0.5").p("").z(); + testCreate("https://00001.0.0.6").s("https").h("00001.0.0.6").p("").z(); + + testCreate("https://01.0.0.1").s("https").h("01.0.0.1").p("").z(); + + testCreate("https://111111.2.3.com").s("https").h("111111.2.3.com").p("").z(); + + testCreate("https://1.example.com").s("https").h("1.example.com").p("").z(); + testCreate("https://12.example.com").s("https").h("12.example.com").p("").z(); + testCreate("https://123.example.com").s("https").h("123.example.com").p("").z(); + testCreate("https://1234.example.com").s("https").h("1234.example.com").p("").z(); + testCreate("https://12345.example.com").s("https").h("12345.example.com").p("").z(); + + testCreate("https://98765432101.example.com").s("https").h("98765432101.example.com").p("").z(); + testCreate("https://98765432101.www.example.com/").s("https").h("98765432101.www.example.com").p("/").z(); + testCreate("https://98765432101.www.example.com").s("https").h("98765432101.www.example.com").p("").z(); + + testCreate("https://9223372036854775808.example.com").s("https").h("9223372036854775808.example.com").p("").z(); + testCreate("https://9223372036854775808.www.example.com").s("https").h("9223372036854775808.www.example.com").p("").z(); + testCreate("https://9223372036854775808.xyz.abc.com").s("https").h("9223372036854775808.xyz.abc.com").p("").z(); + testCreate("https://9223372036854775808.xyz.abc.pqr.com").s("https").h("9223372036854775808.xyz.abc.pqr.com").p("").z(); + + testCreate("https://256.example.com").s("https").h("256.example.com").p("").z(); + } + public static void main(String[] args) throws Exception { switch (args.length) { diff --git a/test/micro/org/openjdk/bench/java/net/URIAuthorityParsingBenchmark.java b/test/micro/org/openjdk/bench/java/net/URIAuthorityParsingBenchmark.java new file mode 100644 index 00000000000..8e75b9e35ac --- /dev/null +++ b/test/micro/org/openjdk/bench/java/net/URIAuthorityParsingBenchmark.java @@ -0,0 +1,62 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.net; + +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.infra.Blackhole; + +import java.net.URI; +import java.util.concurrent.TimeUnit; + +/** + * Tests Java.net.URI.create performance on various URI types. + */ +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 3) +public class URIAuthorityParsingBenchmark { + + @Param({ + "https://98765432101.abc.xyz.com", + "https://ABCDEFGHIJK.abc.xyz.com" + }) + private String uri; + + @Benchmark + public void create(Blackhole blackhole) { + blackhole.consume(URI.create(uri)); + } + +}