Index: fop =================================================================== --- fop (revision 479586) +++ fop (working copy) @@ -243,7 +243,11 @@ # Execute FOP using eval/exec to preserve spaces in paths, # java options, and FOP args -fop_exec_command="exec \"$JAVACMD\" $LOGCHOICE $LOGLEVEL -classpath \"$LOCALCLASSPATH\" $FOP_OPTS org.apache.fop.cli.Main $fop_exec_args" + +# JMP: -Xrunjmp +# Hat: -Xrunhprof:file=dump.hprof,format=b + +fop_exec_command="exec \"$JAVACMD\" -Xrunhprof:file=dump.hprof,format=b $LOGCHOICE $LOGLEVEL -classpath \"$LOCALCLASSPATH\" $FOP_OPTS org.apache.fop.cli.Main $fop_exec_args" if $fop_exec_debug ; then echo $fop_exec_command fi Index: src/java/org/apache/fop/fo/properties/EnumProperty.java =================================================================== --- src/java/org/apache/fop/fo/properties/EnumProperty.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/EnumProperty.java (working copy) @@ -23,6 +23,9 @@ import org.apache.fop.fo.PropertyList; import org.apache.fop.fo.expr.PropertyException; +import java.util.Map; +import java.util.WeakHashMap; + /** * Superclass for properties that wrap an enumeration value */ @@ -62,18 +65,31 @@ } } - private int value; - private String text; + private static final Map propertyCache = new WeakHashMap(); + private final int value; + private final String text; + /** * @param explicitValue enumerated value to be set for this property * @param text the string value of the enum. */ - public EnumProperty(int explicitValue, String text) { + private EnumProperty(int explicitValue, String text) { this.value = explicitValue; this.text = text; } + public static EnumProperty getInstance(int explicitValue, String text) { + EnumProperty ep = new EnumProperty(explicitValue, text); + EnumProperty cacheEntry = (EnumProperty)propertyCache.get(ep); + if (cacheEntry == null) { + propertyCache.put(ep, ep); + return ep; + } else { + return cacheEntry; + } + } + /** * @return this.value */ @@ -88,5 +104,19 @@ return text; } + public boolean equals(Object obj) { + if (obj instanceof EnumProperty) { + EnumProperty ep = (EnumProperty)obj; + return ep.value == this.value && + ((ep.text == null && this.text == null) + || ep.text.equals(this.text)); + } else { + return false; + } + } + + public int hashCode() { + return value + text.hashCode(); + } } Index: src/java/org/apache/fop/fo/properties/PageBreakShorthandParser.java =================================================================== --- src/java/org/apache/fop/fo/properties/PageBreakShorthandParser.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/PageBreakShorthandParser.java (working copy) @@ -49,11 +49,11 @@ || propId == Constants.PR_BREAK_AFTER) { switch (property.getEnum()) { case Constants.EN_ALWAYS: - return new EnumProperty(Constants.EN_PAGE, "PAGE"); + return EnumProperty.getInstance(Constants.EN_PAGE, "PAGE"); case Constants.EN_LEFT: - return new EnumProperty(Constants.EN_EVEN_PAGE, "EVEN_PAGE"); + return EnumProperty.getInstance(Constants.EN_EVEN_PAGE, "EVEN_PAGE"); case Constants.EN_RIGHT: - return new EnumProperty(Constants.EN_ODD_PAGE, "ODD_PAGE"); + return EnumProperty.getInstance(Constants.EN_ODD_PAGE, "ODD_PAGE"); case Constants.EN_AVOID: default: //nop; Index: src/java/org/apache/fop/fo/properties/VerticalAlignShorthandParser.java =================================================================== --- src/java/org/apache/fop/fo/properties/VerticalAlignShorthandParser.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/VerticalAlignShorthandParser.java (working copy) @@ -40,101 +40,101 @@ case EN_BASELINE: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_BASELINE, "BASELINE"); + return EnumProperty.getInstance(EN_BASELINE, "BASELINE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + return new EnumLength(EnumProperty.getInstance(EN_BASELINE, "BASELINE")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } case EN_TOP: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_BEFORE_EDGE, "BEFORE_EDGE"); + return EnumProperty.getInstance(EN_BEFORE_EDGE, "BEFORE_EDGE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + return new EnumLength(EnumProperty.getInstance(EN_BASELINE, "BASELINE")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } case EN_TEXT_TOP: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_TEXT_BEFORE_EDGE, "TEXT_BEFORE_EDGE"); + return EnumProperty.getInstance(EN_TEXT_BEFORE_EDGE, "TEXT_BEFORE_EDGE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + return new EnumLength(EnumProperty.getInstance(EN_BASELINE, "BASELINE")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } case EN_MIDDLE: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_MIDDLE, "MIDDLE"); + return EnumProperty.getInstance(EN_MIDDLE, "MIDDLE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + return new EnumLength(EnumProperty.getInstance(EN_BASELINE, "BASELINE")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } case EN_BOTTOM: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_AFTER_EDGE, "AFTER_EDGE"); + return EnumProperty.getInstance(EN_AFTER_EDGE, "AFTER_EDGE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + return new EnumLength(EnumProperty.getInstance(EN_BASELINE, "BASELINE")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } case EN_TEXT_BOTTOM: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_TEXT_AFTER_EDGE, "TEXT_AFTER_EDGE"); + return EnumProperty.getInstance(EN_TEXT_AFTER_EDGE, "TEXT_AFTER_EDGE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + return new EnumLength(EnumProperty.getInstance(EN_BASELINE, "BASELINE")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } case EN_SUB: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_BASELINE, "BASELINE"); + return EnumProperty.getInstance(EN_BASELINE, "BASELINE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_SUB, "SUB")); + return new EnumLength(EnumProperty.getInstance(EN_SUB, "SUB")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } case EN_SUPER: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_BASELINE, "BASELINE"); + return EnumProperty.getInstance(EN_BASELINE, "BASELINE"); case PR_ALIGNMENT_ADJUST: - return new EnumLength(new EnumProperty(EN_AUTO, "AUTO")); + return new EnumLength(EnumProperty.getInstance(EN_AUTO, "AUTO")); case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_SUPER, "SUPER")); + return new EnumLength(EnumProperty.getInstance(EN_SUPER, "SUPER")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } default: switch (propId) { case PR_ALIGNMENT_BASELINE: - return new EnumProperty(EN_BASELINE, "BASELINE"); + return EnumProperty.getInstance(EN_BASELINE, "BASELINE"); case PR_ALIGNMENT_ADJUST: return property; case PR_BASELINE_SHIFT: - return new EnumLength(new EnumProperty(EN_BASELINE, "BASELINE")); + return new EnumLength(EnumProperty.getInstance(EN_BASELINE, "BASELINE")); case PR_DOMINANT_BASELINE: - return new EnumProperty(EN_AUTO, "AUTO"); + return EnumProperty.getInstance(EN_AUTO, "AUTO"); } } return null; Index: src/java/org/apache/fop/fo/properties/EnumNumber.java =================================================================== --- src/java/org/apache/fop/fo/properties/EnumNumber.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/EnumNumber.java (working copy) @@ -19,17 +19,32 @@ package org.apache.fop.fo.properties; +import java.util.Map; +import java.util.WeakHashMap; + /** * A number quantity in XSL which is specified as an enum, such as "no-limit". */ public class EnumNumber extends NumberProperty { - private Property enumProperty; + + private static final Map cache = new WeakHashMap(); + + private final EnumProperty enumProperty; - public EnumNumber(Property enumProperty) { + private EnumNumber(EnumProperty enumProperty) { super(null); this.enumProperty = enumProperty; } + public static EnumNumber getInstance(Property enumProperty) { + EnumNumber en = (EnumNumber)cache.get(enumProperty); + if (en == null) { + en = new EnumNumber((EnumProperty)enumProperty); + cache.put(enumProperty, en); + } + return en; + } + public int getEnum() { return enumProperty.getEnum(); } Index: src/java/org/apache/fop/fo/properties/PositionShorthandParser.java =================================================================== --- src/java/org/apache/fop/fo/properties/PositionShorthandParser.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/PositionShorthandParser.java (working copy) @@ -41,11 +41,11 @@ switch (propVal) { case Constants.EN_STATIC: case Constants.EN_RELATIVE: - return new EnumProperty(Constants.EN_AUTO, "AUTO"); + return EnumProperty.getInstance(Constants.EN_AUTO, "AUTO"); case Constants.EN_ABSOLUTE: - return new EnumProperty(Constants.EN_ABSOLUTE, "ABSOLUTE"); + return EnumProperty.getInstance(Constants.EN_ABSOLUTE, "ABSOLUTE"); case Constants.EN_FIXED: - return new EnumProperty(Constants.EN_FIXED, "FIXED"); + return EnumProperty.getInstance(Constants.EN_FIXED, "FIXED"); default: //nop } @@ -53,13 +53,13 @@ if (propId == Constants.PR_RELATIVE_POSITION) { switch (propVal) { case Constants.EN_STATIC: - return new EnumProperty(Constants.EN_STATIC, "STATIC"); + return EnumProperty.getInstance(Constants.EN_STATIC, "STATIC"); case Constants.EN_RELATIVE: - return new EnumProperty(Constants.EN_RELATIVE, "RELATIVE"); + return EnumProperty.getInstance(Constants.EN_RELATIVE, "RELATIVE"); case Constants.EN_ABSOLUTE: - return new EnumProperty(Constants.EN_STATIC, "STATIC"); + return EnumProperty.getInstance(Constants.EN_STATIC, "STATIC"); case Constants.EN_FIXED: - return new EnumProperty(Constants.EN_STATIC, "STATIC"); + return EnumProperty.getInstance(Constants.EN_STATIC, "STATIC"); default: //nop } Index: src/java/org/apache/fop/fo/properties/NumberProperty.java =================================================================== --- src/java/org/apache/fop/fo/properties/NumberProperty.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/NumberProperty.java (working copy) @@ -58,7 +58,7 @@ return p; } if (p instanceof EnumProperty) { - return new EnumNumber(p); + return EnumNumber.getInstance(p); } Number val = p.getNumber(); if (val != null) { Index: src/java/org/apache/fop/fo/properties/LineHeightPropertyMaker.java =================================================================== --- src/java/org/apache/fop/fo/properties/LineHeightPropertyMaker.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/LineHeightPropertyMaker.java (working copy) @@ -54,9 +54,9 @@ */ Property p = super.make(propertyList, value, fo); p.getSpace().setConditionality( - new EnumProperty(Constants.EN_RETAIN, "RETAIN"), true); + EnumProperty.getInstance(Constants.EN_RETAIN, "RETAIN"), true); p.getSpace().setPrecedence( - new EnumProperty(Constants.EN_FORCE, "FORCE"), true); + EnumProperty.getInstance(Constants.EN_FORCE, "FORCE"), true); return p; } Index: src/java/org/apache/fop/fo/properties/SpacePropertyMaker.java =================================================================== --- src/java/org/apache/fop/fo/properties/SpacePropertyMaker.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/SpacePropertyMaker.java (working copy) @@ -43,7 +43,7 @@ Property prop = super.compute(propertyList); if (prop != null && prop instanceof SpaceProperty) { ((SpaceProperty)prop).setConditionality( - new EnumProperty(Constants.EN_RETAIN, "RETAIN"), false); + EnumProperty.getInstance(Constants.EN_RETAIN, "RETAIN"), false); } return prop; } Index: src/java/org/apache/fop/fo/properties/WhiteSpaceShorthandParser.java =================================================================== --- src/java/org/apache/fop/fo/properties/WhiteSpaceShorthandParser.java (revision 479586) +++ src/java/org/apache/fop/fo/properties/WhiteSpaceShorthandParser.java (working copy) @@ -42,17 +42,17 @@ switch (propId) { case Constants.PR_LINEFEED_TREATMENT: case Constants.PR_WHITE_SPACE_TREATMENT: - return new EnumProperty(Constants.EN_PRESERVE, "PRESERVE"); + return EnumProperty.getInstance(Constants.EN_PRESERVE, "PRESERVE"); case Constants.PR_WHITE_SPACE_COLLAPSE: - return new EnumProperty(Constants.EN_FALSE, "FALSE"); + return EnumProperty.getInstance(Constants.EN_FALSE, "FALSE"); case Constants.PR_WRAP_OPTION: - return new EnumProperty(Constants.EN_NO_WRAP, "NO_WRAP"); + return EnumProperty.getInstance(Constants.EN_NO_WRAP, "NO_WRAP"); default: //nop } case Constants.EN_NO_WRAP: if (propId == Constants.PR_WRAP_OPTION) { - return new EnumProperty(Constants.EN_NO_WRAP, "NO_WRAP"); + return EnumProperty.getInstance(Constants.EN_NO_WRAP, "NO_WRAP"); } case Constants.EN_NORMAL: default: Index: src/java/org/apache/fop/fo/FOPropertyMapping.java =================================================================== --- src/java/org/apache/fop/fo/FOPropertyMapping.java (revision 479586) +++ src/java/org/apache/fop/fo/FOPropertyMapping.java (working copy) @@ -265,7 +265,7 @@ enums = new Property[ENUM_COUNT + 1]; } if (enums[enumValue] == null) { - enums[enumValue] = new EnumProperty(enumValue, text); + enums[enumValue] = EnumProperty.getInstance(enumValue, text); } return enums[enumValue]; }