dev@javaserverfaces.java.net

[REVIEW] Shore up object allocations in API

From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Date: Mon, 05 Jun 2006 11:53:28 -0700


<< ADD DESCRIPTION HERE >>


SECTION: Modified Files
----------------------------
M jsf-api/src/javax/faces/component/UICommand.java
M jsf-api/src/javax/faces/component/UIData.java
M jsf-api/src/javax/faces/component/UIGraphic.java
M jsf-api/src/javax/faces/component/UIInput.java
M jsf-api/src/javax/faces/component/UIMessage.java
M jsf-api/src/javax/faces/component/UIMessages.java
M jsf-api/src/javax/faces/component/UIOutput.java
M jsf-api/src/javax/faces/component/UIParameter.java
M jsf-api/src/javax/faces/component/UISelectItem.java
M jsf-api/src/javax/faces/component/UISelectItems.java
M jsf-api/src/javax/faces/component/UIViewRoot.java
M jsf-api/src/javax/faces/webapp/UIComponentClassicTagBase.java
 - Make the Object[] array used by saveState() and restoreState()
   be an ivar. This will reduce some object allocation overhead
   when restoreState() is called first, as saveState will resuse
   the Object[] passed to restoreState.

M jsf-tools/src/com/sun/faces/generate/HtmlComponentGenerator.java
 - Update the component generator to generate the same saveState
   restoreState code described above.

M jsf-api/src/javax/faces/component/UIComponentBase.java
 - In addition to the above, update restoreAttachedState()
   to replace the restore object in the existing List
   instead of creating a new List to hold the
   restored results.
 - so something similar as above in saveBindingState()
   reuse the array instead of creating a new structure.


SECTION: Diffs
----------------------------
Index: jsf-api/src/javax/faces/component/UICommand.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UICommand.java,v
retrieving revision 1.75
diff -u -r1.75 UICommand.java
--- jsf-api/src/javax/faces/component/UICommand.java 5 Dec 2005 16:42:43 -0000 1.75
+++ jsf-api/src/javax/faces/component/UICommand.java 5 Jun 2006 18:47:03 -0000
@@ -29,26 +29,20 @@
 
 package javax.faces.component;
 
+import javax.el.ELException;
 import javax.el.MethodExpression;
 import javax.el.ValueExpression;
-import javax.el.ELException;
 import javax.faces.FacesException;
 import javax.faces.application.Application;
 import javax.faces.context.FacesContext;
-import javax.faces.el.EvaluationException;
 import javax.faces.el.MethodBinding;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.ActionEvent;
 import javax.faces.event.ActionListener;
 import javax.faces.event.FacesEvent;
-import javax.faces.event.FacesListener;
 import javax.faces.event.PhaseId;
 import javax.faces.render.Renderer;
 
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
 
 /**
  * <p><strong>UICommand</strong> is a {_at_link UIComponent} that represents
@@ -313,9 +307,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[6];
+ if (values == null) {
+ values = new Object[6];
+ }
+
         values[0] = super.saveState(context);
         values[1] = saveAttachedState(context, methodBindingActionListener);
         values[2] = saveAttachedState(context, actionExpression);
@@ -329,7 +328,7 @@
 
 
     public void restoreState(FacesContext context, Object state) {
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         methodBindingActionListener = (MethodBinding)
             restoreAttachedState(context, values[1]);
Index: jsf-api/src/javax/faces/component/UIComponentBase.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIComponentBase.java,v
retrieving revision 1.132
diff -u -r1.132 UIComponentBase.java
--- jsf-api/src/javax/faces/component/UIComponentBase.java 20 Mar 2006 19:20:27 -0000 1.132
+++ jsf-api/src/javax/faces/component/UIComponentBase.java 5 Jun 2006 18:47:04 -0000
@@ -1088,7 +1088,7 @@
         if (count > 0) {
             
             // this arraylist will store state
- List stateList = new ArrayList(count);
+ List<Object> stateList = new ArrayList<Object>(count);
             
             // if we have children, add them to the stateList
             if (this.getChildCount() > 0) {
@@ -1230,15 +1230,17 @@
 
 
     // ----------------------------------------------------- StateHolder Methods
-
+ private Object[] values;
 
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[8];
+ if (values == null) {
+ values = new Object[8];
+ }
         // copy over "attributes" to a temporary map, so that
         // any references maintained due to "attributes" being an inner class
         // is not saved.
- if ( attributes != null ) {
+ if ( attributes != null && attributes.size() > 0) {
             HashMap<String, Object> attributesCopy = new HashMap<String, Object>(attributes);
             values[0] = attributesCopy;
         }
@@ -1257,16 +1259,13 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         // we need to get the map that knows how to handle attribute/property
- // transparency before we restore its values.
- attributes = getAttributes();
+ // transparency before we restore its values.
         if ( values[0] != null ) {
- Map attributesCopy = (Map) values[0];
- Iterator iter = attributesCopy.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry entry = (Map.Entry) iter.next();
- attributes.put((String) entry.getKey(), entry.getValue());
+ Map tempMap = (Map) values[0];
+ if (tempMap.size() > 0) {
+ getAttributes().putAll(tempMap);
             }
         }
         bindings = restoreBindingsState(context, values[1]);
@@ -1397,42 +1396,32 @@
      * previously returned by {_at_link #saveAttachedState}.
      *
      */
-
+
     public static Object restoreAttachedState(FacesContext context,
- Object stateObj) throws IllegalStateException {
+ Object stateObj)
+ throws IllegalStateException {
         if (null == context) {
             throw new NullPointerException();
         }
         if (null == stateObj) {
             return null;
         }
- Object result = null;
- List
- stateList = null,
- resultList = null;
- Iterator iter = null;
- StateHolderSaver saver = null;
+ Object result;
+ List stateList;
+
 
- if (stateObj instanceof List) {
+ if (stateObj instanceof List) {
             stateList = (List) stateObj;
- resultList = new ArrayList(stateList.size());
- iter = stateList.iterator();
- while (iter.hasNext()) {
- try {
- saver = (StateHolderSaver) iter.next();
- }
- catch (ClassCastException cce) {
- throw new IllegalStateException("Unknown object type");
- }
- resultList.add(saver.restore(context));
- }
- result = resultList;
- }
- else if (stateObj instanceof StateHolderSaver) {
- saver = (StateHolderSaver) stateObj;
+ for (int i = 0, size = stateList.size(); i < size; i++) {
+ stateList.set(i,
+ ((StateHolderSaver) stateList.get(i)).restore(
+ context));
+ }
+ result = stateList;
+ } else if (stateObj instanceof StateHolderSaver) {
+ StateHolderSaver saver = (StateHolderSaver) stateObj;
             result = saver.restore(context);
- }
- else {
+ } else {
             throw new IllegalStateException("Unknown object type");
         }
         return result;
@@ -1446,7 +1435,7 @@
         Object values[] = (Object[]) state;
         String names[] = (String[]) values[0];
         Object states[] = (Object[]) values[1];
- Map bindings = new HashMap();
+ Map<String,Object> bindings = new HashMap<String,Object>(names.length);
         for (int i = 0; i < names.length; i++) {
             bindings.put(names[i],
                          restoreAttachedState(context, states[i]));
@@ -1457,23 +1446,22 @@
 
 
     private Object saveBindingsState(FacesContext context) {
-
- if (bindings == null) {
- return (null);
- }
- List names = new ArrayList();
- List states = new ArrayList();
- Iterator keys = bindings.keySet().iterator();
- while (keys.hasNext()) {
- String key = (String) keys.next();
- ValueExpression binding = (ValueExpression) bindings.get(key);
- names.add(key);
- states.add(saveAttachedState(context, binding));
- }
- Object values[] = new Object[2];
- values[0] = names.toArray(new String[names.size()]);
- values[1] = states.toArray(new Object[states.size()]);
- return (values);
+
+ if (bindings == null) {
+ return (null);
+ }
+
+ Object values[] = new Object[2];
+ values[0] = bindings.keySet().toArray(new String[bindings.size()]);
+
+ Object[] bindingValues = bindings.values().toArray();
+ for (int i = 0; i < bindingValues.length; i++) {
+ bindingValues[i] = saveAttachedState(context, bindingValues[i]);
+ }
+
+ values[1] = bindingValues;
+
+ return (values);
 
     }
 
Index: jsf-api/src/javax/faces/component/UIData.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIData.java,v
retrieving revision 1.67
diff -u -r1.67 UIData.java
--- jsf-api/src/javax/faces/component/UIData.java 22 Mar 2006 21:45:08 -0000 1.67
+++ jsf-api/src/javax/faces/component/UIData.java 5 Jun 2006 18:47:04 -0000
@@ -25,15 +25,6 @@
 
 package javax.faces.component;
 
-import java.io.IOException;
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
 import javax.el.ELException;
 import javax.el.ValueExpression;
 import javax.faces.FacesException;
@@ -52,6 +43,15 @@
 import javax.faces.model.ScalarDataModel;
 import javax.servlet.jsp.jstl.sql.Result;
 
+import java.io.IOException;
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
 
 /**
  * <p><strong>UIData</strong> is a {_at_link UIComponent} that supports
@@ -519,9 +519,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[9];
+ if (values == null) {
+ values = new Object[9];
+ }
+
         values[0] = super.saveState(context);
         values[1] = new Integer(first);
         values[2] = firstSet ? Boolean.TRUE : Boolean.FALSE;
@@ -538,7 +543,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         first = ((Integer) values[1]).intValue();
         firstSet = ((Boolean) values[2]).booleanValue();
Index: jsf-api/src/javax/faces/component/UIGraphic.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIGraphic.java,v
retrieving revision 1.41
diff -u -r1.41 UIGraphic.java
--- jsf-api/src/javax/faces/component/UIGraphic.java 5 Dec 2005 16:42:45 -0000 1.41
+++ jsf-api/src/javax/faces/component/UIGraphic.java 5 Jun 2006 18:47:04 -0000
@@ -30,11 +30,9 @@
 package javax.faces.component;
 
 
-import java.io.IOException;
-import javax.el.ValueExpression;
 import javax.el.ELException;
+import javax.el.ValueExpression;
 import javax.faces.FacesException;
-import javax.faces.application.Application;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
 
@@ -265,9 +263,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[2];
+ if (values == null) {
+ values = new Object[2];
+ }
+
         values[0] = super.saveState(context);
         values[1] = value;
         return (values);
@@ -277,7 +280,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         value = values[1];
 
Index: jsf-api/src/javax/faces/component/UIInput.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIInput.java,v
retrieving revision 1.85
diff -u -r1.85 UIInput.java
--- jsf-api/src/javax/faces/component/UIInput.java 22 May 2006 14:57:56 -0000 1.85
+++ jsf-api/src/javax/faces/component/UIInput.java 5 Jun 2006 18:47:04 -0000
@@ -29,28 +29,21 @@
 
 package javax.faces.component;
 
-import javax.el.MethodExpression;
-import javax.el.ValueExpression;
 import javax.el.ELException;
+import javax.el.ValueExpression;
 import javax.faces.FacesException;
 import javax.faces.application.Application;
 import javax.faces.application.FacesMessage;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.convert.ConverterException;
-import javax.faces.el.EvaluationException;
 import javax.faces.el.MethodBinding;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.FacesEvent;
-import javax.faces.event.FacesListener;
-import javax.faces.event.PhaseId;
 import javax.faces.event.ValueChangeEvent;
 import javax.faces.event.ValueChangeListener;
 import javax.faces.render.Renderer;
 import javax.faces.validator.Validator;
 import javax.faces.validator.ValidatorException;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -1219,9 +1212,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[14];
+ if (values == null) {
+ values = new Object[14];
+ }
+
         values[0] = super.saveState(context);
         values[1] = localValueSet ? Boolean.TRUE : Boolean.FALSE;
         values[2] = required ? Boolean.TRUE : Boolean.FALSE;
@@ -1243,7 +1241,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         localValueSet = ((Boolean) values[1]).booleanValue();
         required = ((Boolean) values[2]).booleanValue();
Index: jsf-api/src/javax/faces/component/UIMessage.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIMessage.java,v
retrieving revision 1.17
diff -u -r1.17 UIMessage.java
--- jsf-api/src/javax/faces/component/UIMessage.java 22 Aug 2005 22:07:56 -0000 1.17
+++ jsf-api/src/javax/faces/component/UIMessage.java 5 Jun 2006 18:47:04 -0000
@@ -219,9 +219,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[6];
+ if (values == null) {
+ values = new Object[6];
+ }
+
         values[0] = super.saveState(context);
         values[1] = this.forVal;
         values[2] = this.showDetail ? Boolean.TRUE : Boolean.FALSE;
@@ -235,7 +240,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         forVal = (String) values[1];
         showDetail = ((Boolean) values[2]).booleanValue();
Index: jsf-api/src/javax/faces/component/UIMessages.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIMessages.java,v
retrieving revision 1.16
diff -u -r1.16 UIMessages.java
--- jsf-api/src/javax/faces/component/UIMessages.java 22 Aug 2005 22:07:56 -0000 1.16
+++ jsf-api/src/javax/faces/component/UIMessages.java 5 Jun 2006 18:47:04 -0000
@@ -220,9 +220,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[7];
+ if (values == null) {
+ values = new Object[7];
+ }
+
         values[0] = super.saveState(context);
         values[1] = this.globalOnly ? Boolean.TRUE : Boolean.FALSE;
         values[2] = this.globalOnlySet ? Boolean.TRUE : Boolean.FALSE;
@@ -238,7 +243,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         globalOnly = ((Boolean) values[1]).booleanValue();
         globalOnlySet = ((Boolean) values[2]).booleanValue();
Index: jsf-api/src/javax/faces/component/UIOutput.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIOutput.java,v
retrieving revision 1.52
diff -u -r1.52 UIOutput.java
--- jsf-api/src/javax/faces/component/UIOutput.java 22 Aug 2005 22:07:57 -0000 1.52
+++ jsf-api/src/javax/faces/component/UIOutput.java 5 Jun 2006 18:47:04 -0000
@@ -30,12 +30,9 @@
 package javax.faces.component;
 
 
-import java.io.IOException;
-
-import javax.el.ValueExpression;
 import javax.el.ELException;
+import javax.el.ValueExpression;
 import javax.faces.FacesException;
-import javax.faces.application.Application;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 
@@ -195,9 +192,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[3];
+ if (values == null) {
+ values = new Object[3];
+ }
+
         values[0] = super.saveState(context);
         values[1] = saveAttachedState(context, converter);
         values[2] = value;
@@ -208,7 +210,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         converter = (Converter) restoreAttachedState(context, values[1]);
         value = values[2];
Index: jsf-api/src/javax/faces/component/UIParameter.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIParameter.java,v
retrieving revision 1.28
diff -u -r1.28 UIParameter.java
--- jsf-api/src/javax/faces/component/UIParameter.java 22 Aug 2005 22:07:57 -0000 1.28
+++ jsf-api/src/javax/faces/component/UIParameter.java 5 Jun 2006 18:47:04 -0000
@@ -30,12 +30,10 @@
 package javax.faces.component;
 
 
-import java.io.IOException;
-import javax.faces.application.Application;
-import javax.faces.context.FacesContext;
-import javax.faces.FacesException;
-import javax.el.ValueExpression;
 import javax.el.ELException;
+import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
 
 
 
@@ -183,9 +181,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[3];
+ if (values == null) {
+ values = new Object[3];
+ }
+
         values[0] = super.saveState(context);
         values[1] = name;
         values[2] = value;
@@ -196,7 +199,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         name = (String) values[1];
         value = values[2];
Index: jsf-api/src/javax/faces/component/UISelectItem.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UISelectItem.java,v
retrieving revision 1.38
diff -u -r1.38 UISelectItem.java
--- jsf-api/src/javax/faces/component/UISelectItem.java 13 Mar 2006 21:21:46 -0000 1.38
+++ jsf-api/src/javax/faces/component/UISelectItem.java 5 Jun 2006 18:47:04 -0000
@@ -30,14 +30,11 @@
 package javax.faces.component;
 
 
-import java.io.IOException;
+import javax.el.ELException;
 import javax.el.ValueExpression;
-import javax.faces.application.Application;
+import javax.faces.FacesException;
 import javax.faces.context.FacesContext;
 import javax.faces.model.SelectItem;
-import javax.faces.FacesException;
-import javax.el.ELException;
-import javax.el.ValueExpression;
 
 
 
@@ -328,9 +325,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[9];
+ if (values == null) {
+ values = new Object[9];
+ }
+
         values[0] = super.saveState(context);
         values[1] = itemDescription;
         values[2] = itemDisabled ? Boolean.TRUE : Boolean.FALSE;
@@ -347,7 +349,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         itemDescription = (String) values[1];
         itemDisabled = ((Boolean) values[2]).booleanValue();
Index: jsf-api/src/javax/faces/component/UISelectItems.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UISelectItems.java,v
retrieving revision 1.29
diff -u -r1.29 UISelectItems.java
--- jsf-api/src/javax/faces/component/UISelectItems.java 22 Aug 2005 22:07:58 -0000 1.29
+++ jsf-api/src/javax/faces/component/UISelectItems.java 5 Jun 2006 18:47:04 -0000
@@ -29,13 +29,11 @@
 
 package javax.faces.component;
 
-import java.io.IOException;
-import javax.faces.application.Application;
-import javax.faces.context.FacesContext;
-import javax.faces.model.SelectItem;
-import javax.faces.FacesException;
 import javax.el.ELException;
 import javax.el.ValueExpression;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.model.SelectItem;
 
 
 /**
@@ -157,9 +155,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[2];
+ if (values == null) {
+ values = new Object[2];
+ }
+
         values[0] = super.saveState(context);
         values[1] = value;
         return (values);
@@ -169,7 +172,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         value = values[1];
 
Index: jsf-api/src/javax/faces/component/UIViewRoot.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIViewRoot.java,v
retrieving revision 1.43
diff -u -r1.43 UIViewRoot.java
--- jsf-api/src/javax/faces/component/UIViewRoot.java 11 May 2006 18:48:03 -0000 1.43
+++ jsf-api/src/javax/faces/component/UIViewRoot.java 5 Jun 2006 18:47:05 -0000
@@ -30,31 +30,29 @@
 package javax.faces.component;
 
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-import javax.faces.FactoryFinder;
+import javax.el.ELException;
+import javax.el.MethodExpression;
+import javax.el.ValueExpression;
 import javax.faces.FacesException;
-import javax.faces.lifecycle.LifecycleFactory;
-import javax.faces.lifecycle.Lifecycle;
+import javax.faces.FactoryFinder;
 import javax.faces.context.FacesContext;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.FacesEvent;
-import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseListener;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.render.RenderKit;
-import javax.faces.render.RenderKitFactory;
 import javax.faces.webapp.FacesServlet;
 
-import javax.el.ValueExpression;
-import javax.el.MethodExpression;
-import javax.el.ELException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 
 /**
@@ -924,9 +922,14 @@
     // ----------------------------------------------------- StateHolder Methods
 
 
+ private Object[] values;
+
     public Object saveState(FacesContext context) {
 
- Object values[] = new Object[8];
+ if (values == null) {
+ values = new Object[8];
+ }
+
         values[0] = super.saveState(context);
         values[1] = renderKitId;
         values[2] = viewId;
@@ -942,7 +945,7 @@
 
     public void restoreState(FacesContext context, Object state) {
 
- Object values[] = (Object[]) state;
+ values = (Object[]) state;
         super.restoreState(context, values[0]);
         renderKitId = (String) values[1];
         viewId = (String) values[2];
Index: jsf-api/src/javax/faces/webapp/UIComponentClassicTagBase.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/webapp/UIComponentClassicTagBase.java,v
retrieving revision 1.20
diff -u -r1.20 UIComponentClassicTagBase.java
--- jsf-api/src/javax/faces/webapp/UIComponentClassicTagBase.java 17 May 2006 19:00:43 -0000 1.20
+++ jsf-api/src/javax/faces/webapp/UIComponentClassicTagBase.java 5 Jun 2006 18:47:05 -0000
@@ -680,7 +680,7 @@
     protected void addChild(UIComponent child) {
 
         if (createdComponents == null) {
- createdComponents = new ArrayList<String>();
+ createdComponents = new ArrayList<String>(32);
         }
         createdComponents.add(child.getId());
     }
@@ -745,7 +745,7 @@
         // Remove old children that are no longer present
         List oldList =
             (List) component.getAttributes().get(JSP_CREATED_COMPONENT_IDS);
- if (oldList != null) {
+ if (oldList != null && oldList.size() > 0) {
 
             if (createdComponents != null) {
 
Index: jsf-tools/src/com/sun/faces/generate/HtmlComponentGenerator.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-tools/src/com/sun/faces/generate/HtmlComponentGenerator.java,v
retrieving revision 1.20
diff -u -r1.20 HtmlComponentGenerator.java
--- jsf-tools/src/com/sun/faces/generate/HtmlComponentGenerator.java 22 May 2006 14:58:11 -0000 1.20
+++ jsf-tools/src/com/sun/faces/generate/HtmlComponentGenerator.java 5 Jun 2006 18:47:06 -0000
@@ -34,14 +34,14 @@
 import java.io.FileWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import com.sun.faces.config.beans.ComponentBean;
 import com.sun.faces.config.beans.DescriptionBean;
 import com.sun.faces.config.beans.FacesConfigBean;
 import com.sun.faces.config.beans.PropertyBean;
 import com.sun.faces.util.ToolsUtil;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 
 /**
@@ -440,12 +440,17 @@
             }
         }
 
+ writer.fwrite("private Object[] _values;");
         // Generate the saveState() method
         writer.fwrite("public Object saveState(FacesContext _context) {\n");
         writer.indent();
- writer.fwrite("Object[] _values = new Object[");
+ writer.fwrite("if (_values == null) {\n");
+ writer.indent();
+ writer.fwrite("_values = new Object[");
         writer.write("" + (properties.size() + p + 1));
         writer.write("];\n");
+ writer.outdent();
+ writer.fwrite("}\n");
         writer.fwrite("_values[0] = super.saveState(_context);\n");
 
         int n = 1; // Index into values array
@@ -486,7 +491,7 @@
         writer.fwrite(
             "public void restoreState(FacesContext _context, Object _state) {\n");
         writer.indent();
- writer.fwrite("Object[] _values = (Object[]) _state;\n");
+ writer.fwrite("_values = (Object[]) _state;\n");
         writer.fwrite("super.restoreState(_context, _values[0]);\n");
         n = 1;
         for (int i = 0, size = properties.size(); i < size; i++) {