Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mozilla bug 1861010 - Improve nsHTMLAttributeName performance for non-interned attributes. #89

Merged
merged 3 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/nu/validator/htmlparser/annotation/CppInlineLength.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2023 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package nu.validator.htmlparser.annotation;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;

/**
* The array member marked with this annotation will be inline.
*
* @version $Id$
* @author Emilio Cobos Álvarez <[email protected]>
*/
@Target(ElementType.FIELD)
public @interface CppInlineLength {
int value();
}
34 changes: 34 additions & 0 deletions src/nu/validator/htmlparser/annotation/StaticLocal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2023 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package nu.validator.htmlparser.annotation;

/**
* The local name of an element or attribute. Must be comparable with
* <code>==</code> (interned <code>String</code> in Java).
*
* @version $Id$
* @author Emilio Cobos Álvarez <[email protected]>
*/
public @interface StaticLocal {

}
34 changes: 34 additions & 0 deletions src/nu/validator/htmlparser/annotation/WeakLocal.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2023 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package nu.validator.htmlparser.annotation;

/**
* The local name of an element or attribute. Must be comparable with
* <code>==</code> (interned <code>String</code> in Java).
*
* @version $Id$
* @author Emilio Cobos Álvarez <[email protected]>
*/
public @interface WeakLocal {

}
49 changes: 29 additions & 20 deletions src/nu/validator/htmlparser/impl/AttributeName.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
import java.util.LinkedList;
import java.util.List;

import nu.validator.htmlparser.annotation.CppInlineLength;
import nu.validator.htmlparser.annotation.Inline;
import nu.validator.htmlparser.annotation.Local;
import nu.validator.htmlparser.annotation.StaticLocal;
import nu.validator.htmlparser.annotation.WeakLocal;
import nu.validator.htmlparser.annotation.NoLength;
import nu.validator.htmlparser.annotation.NsUri;
import nu.validator.htmlparser.annotation.Prefix;
Expand Down Expand Up @@ -181,9 +184,9 @@ public final class AttributeName
* the name for the SVG mode
* @return the initialized name array
*/
private static @NoLength @Local String[] SVG_DIFFERENT(@Local String name,
@Local String camel) {
@NoLength @Local String[] arr = new String[4];
private static @NoLength @StaticLocal String[] SVG_DIFFERENT(@StaticLocal String name,
@StaticLocal String camel) {
@NoLength @StaticLocal String[] arr = new String[4];
arr[0] = name;
arr[1] = name;
arr[2] = camel;
Expand All @@ -203,9 +206,9 @@ public final class AttributeName
* the name for the MathML mode
* @return the initialized name array
*/
private static @NoLength @Local String[] MATH_DIFFERENT(@Local String name,
@Local String camel) {
@NoLength @Local String[] arr = new String[4];
private static @NoLength @StaticLocal String[] MATH_DIFFERENT(@StaticLocal String name,
@StaticLocal String camel) {
@NoLength @StaticLocal String[] arr = new String[4];
arr[0] = name;
arr[1] = camel;
arr[2] = name;
Expand All @@ -225,9 +228,9 @@ public final class AttributeName
* the name for the SVG and MathML modes
* @return the initialized name array
*/
private static @NoLength @Local String[] COLONIFIED_LOCAL(
@Local String name, @Local String suffix) {
@NoLength @Local String[] arr = new String[4];
private static @NoLength @StaticLocal String[] COLONIFIED_LOCAL(
@StaticLocal String name, @StaticLocal String suffix) {
@NoLength @StaticLocal String[] arr = new String[4];
arr[0] = name;
arr[1] = suffix;
arr[2] = suffix;
Expand All @@ -244,8 +247,8 @@ public final class AttributeName
* the name
* @return the initialized name array
*/
static @NoLength @Local String[] SAME_LOCAL(@Local String name) {
@NoLength @Local String[] arr = new String[4];
static @NoLength @StaticLocal String[] SAME_LOCAL(@StaticLocal String name) {
@NoLength @StaticLocal String[] arr = new String[4];
arr[0] = name;
arr[1] = name;
arr[2] = name;
Expand Down Expand Up @@ -376,17 +379,20 @@ public final class AttributeName
/**
* The namespaces indexable by mode.
*/
private final @NsUri @NoLength String[] uri;
private final @CppInlineLength(3) @NsUri @NoLength String[] uri;

/**
* The local names indexable by mode.
*
* These are weak because they're either all static, or
* all the same, in wich case we just need to take one reference.
*/
private final @Local @NoLength String[] local;
private final @CppInlineLength(3) @WeakLocal @NoLength String[] local;

/**
* The prefixes indexably by mode.
*/
private final @Prefix @NoLength String[] prefix;
private final @CppInlineLength(3) @Prefix @NoLength String[] prefix;

// CPPONLY: private final boolean custom;

Expand Down Expand Up @@ -416,7 +422,7 @@ public final class AttributeName
* whether this is an xmlns attribute
*/
private AttributeName(@NsUri @NoLength String[] uri,
@Local @NoLength String[] local, @Prefix @NoLength String[] prefix
@StaticLocal @NoLength String[] local, @Prefix @NoLength String[] prefix
// [NOCPP[
, int flags
// ]NOCPP]
Expand All @@ -429,6 +435,7 @@ private AttributeName(@NsUri @NoLength String[] uri,
this.flags = flags;
// ]NOCPP]
// CPPONLY: this.custom = false;
// CPPONLY: Portability.deleteArray(local);
}

// CPPONLY: public AttributeName() {
Expand All @@ -444,6 +451,8 @@ private AttributeName(@NsUri @NoLength String[] uri,
// CPPONLY:
// CPPONLY: @Inline public void setNameForNonInterned(@Local String name) {
// CPPONLY: assert custom;
// CPPONLY: Portability.addrefIfNonNull(name);
// CPPONLY: Portability.releaseIfNonNull(local[0]);
// CPPONLY: local[0] = name;
// CPPONLY: local[1] = name;
// CPPONLY: local[2] = name;
Expand All @@ -458,28 +467,28 @@ private AttributeName(@NsUri @NoLength String[] uri,
* whether to check ncnameness
* @return an <code>AttributeName</code>
*/
static AttributeName createAttributeName(@Local String name
// [NOCPP[
static AttributeName createAttributeName(@Local String name
, boolean checkNcName
// ]NOCPP]
) {
// [NOCPP[
int flags = NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG;
if (name.startsWith("xmlns:")) {
flags = IS_XMLNS;
} else if (checkNcName && !NCName.isNCName(name)) {
flags = 0;
}
// ]NOCPP]
return new AttributeName(AttributeName.ALL_NO_NS,
AttributeName.SAME_LOCAL(name), ALL_NO_PREFIX, flags);
}
// ]NOCPP]

/**
* The C++ destructor.
*/
@SuppressWarnings("unused") private void destructor() {
Portability.deleteArray(local);
// CPPONLY: if (custom) {
// CPPONLY: Portability.releaseIfNonNull(local[0]);
// CPPONLY: }
}

// [NOCPP[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@

import java.util.List;

import japa.parser.ast.expr.Expression;
import japa.parser.ast.expr.IntegerLiteralExpr;
import japa.parser.ast.expr.AnnotationExpr;
import japa.parser.ast.expr.MarkerAnnotationExpr;
import japa.parser.ast.expr.SingleMemberAnnotationExpr;
import japa.parser.ast.type.ReferenceType;
import japa.parser.ast.visitor.VoidVisitorAdapter;

Expand All @@ -56,6 +59,14 @@ protected boolean prefix() {
return hasAnnotation("Prefix");
}

protected boolean staticLocal() {
return hasAnnotation("StaticLocal");
}

protected boolean weakLocal() {
return hasAnnotation("WeakLocal");
}

protected boolean local() {
return hasAnnotation("Local");
}
Expand Down Expand Up @@ -108,32 +119,59 @@ protected boolean svgCreator() {
return hasAnnotation("SvgCreator");
}

protected int inlineLength() {
AnnotationExpr anno = findAnnotation("CppInlineLength");
if (anno == null || !(anno instanceof SingleMemberAnnotationExpr)) {
return 0;
}
Expression expr = ((SingleMemberAnnotationExpr)anno).getMemberValue();
if (!(expr instanceof IntegerLiteralExpr)) {
return 0;
}
return Integer.parseInt(((IntegerLiteralExpr)expr).getValue());
}

private boolean hasAnnotation(String anno) {
AnnotationExpr expr = findAnnotation(anno);
return expr != null && expr instanceof MarkerAnnotationExpr;
}

private AnnotationExpr findAnnotation(String anno) {
if (currentAnnotations == null) {
return false;
return null;
}
for (AnnotationExpr ann : currentAnnotations) {
if (ann instanceof MarkerAnnotationExpr) {
MarkerAnnotationExpr marker = (MarkerAnnotationExpr) ann;
if (marker.getName().getName().equals(anno)) {
return true;
if (((MarkerAnnotationExpr)ann).getName().getName().equals(anno)) {
return ann;
}
}
if (ann instanceof SingleMemberAnnotationExpr) {
if (((SingleMemberAnnotationExpr)ann).getName().getName().equals(anno)) {
return ann;
}
}
}
return false;
return null;
}

protected Type convertType(japa.parser.ast.type.Type type, int modifiers) {
if (type instanceof ReferenceType) {
ReferenceType referenceType = (ReferenceType) type;
return new Type(convertTypeName(referenceType.getType().toString()), referenceType.getArrayCount(), noLength(), modifiers);
return new Type(convertTypeName(referenceType.getType().toString()));
} else {
return new Type(convertTypeName(type.toString()), 0, false, modifiers);
return new Type(convertTypeName(type.toString()));
}
}

private String convertTypeName(String name) {
if ("String".equals(name)) {
if (staticLocal()) {
return "@StaticLocal";
}
if (weakLocal()) {
return "@WeakLocal";
}
if (local()) {
return "@Local";
}
Expand Down
12 changes: 12 additions & 0 deletions translator-src/nu/validator/htmlparser/cpptranslate/CppTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ public String localType() {
return "RefPtr<nsAtom>";
}

public String staticLocalType() {
return "nsStaticAtom*";
}

public String prefixType() {
return "nsStaticAtom*";
}
Expand Down Expand Up @@ -514,6 +518,14 @@ public String[] stateLoopPolicies() {
return STATE_LOOP_POLICIES;
}

public String releaseIfNonNull() {
return "NS_IF_RELEASE";
}

public String addrefIfNonNull() {
return "NS_IF_ADDREF";
}

public String assertionMacro() {
return "MOZ_ASSERT";
}
Expand Down
Loading