Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-17 Thread Denis Benoit

On Fri, 17 May 2002, Kin-Man Chung wrote:

> I'll implement maximum tag nesting (though PageInfo) and you can work on
> #1.  Deal?

Deal!

Thanks!

-- 
Denis Benoit
[EMAIL PROTECTED]


--
To unsubscribe, e-mail:   
For additional commands, e-mail: 




Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-17 Thread Kin-Man Chung


> 
> Now, about the level of nesting, shouldn't the information be available
> through the PageInfo object?  After all, the purpose of this class is
> "A repository for various info about the page under compilation".  And
> Generator currently has access to an instance of it.  So, if PageInfo
> had something like a "public int getTagElementsMaxNestingLevel()" method,
> Generator could use it to allocate the arrays.
> 

Yes, the information will be available throught PageInfo object,
and which is updated in either Validator or Collector (I just make this
up).

> We have two changes on the table:
> 
> 1. Get the information about the level of the nesting with Visitor, or a
>separate pass;
> 
> 2. Remove the "finallies" and replace it with the "two state arrays";
> 
> For #2, I'm confident that I could do it without problem.  For the #1, well,
> I've taken a quick look at Visitor, but the change seems to me far less
> obvious.
> 
> The way I see it, in the constructor we initialize the nesting to zero.
> Each time:
> 
>   "public void visit(Node.CustomTag n) throws JasperException"
> 
> is called we increment the nesting, and right after the call "visitBody(n);",
> just before the method terminate we decrement the nesting count.
> 
> Obviously, we must keep track of the maximum depth level.  The information
> is ready to be used at the end of the:
> 
>   "public static void validate(Compiler compiler, ..."
> 
> method, this is the one that initiates the visit(XXX) calls, right?.
> 
> Would you like me to propose a patch for #1?  For #2?  And what about having
> the maximum CustomTag nesting depth level available through PageInfo?
> 

I'll implement maximum tag nesting (though PageInfo) and you can work on
#1.  Deal?

> Thanks!
> 

Thanks.

> -- 
> Denis Benoit
> [EMAIL PROTECTED]
> 


--
To unsubscribe, e-mail:   
For additional commands, e-mail: 




Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-17 Thread Denis Benoit

Mr Chung,

I agree completely with your proposed change.  Two arrays is all right
for me.

On Fri, 17 May 2002, Kin-Man Chung wrote:

> This way, the size of the stack is the maximum number of nesting of the
> tags, which should much smaller than the number of tags in the page.
> Such information is easy to collect in Jasper 2, which can be
> done either in Validator.java, or we have a separate pass whose sole
> purpose is to collect info such as this.

Now, about the level of nesting, shouldn't the information be available
through the PageInfo object?  After all, the purpose of this class is
"A repository for various info about the page under compilation".  And
Generator currently has access to an instance of it.  So, if PageInfo
had something like a "public int getTagElementsMaxNestingLevel()" method,
Generator could use it to allocate the arrays.

We have two changes on the table:

1. Get the information about the level of the nesting with Visitor, or a
   separate pass;

2. Remove the "finallies" and replace it with the "two state arrays";

For #2, I'm confident that I could do it without problem.  For the #1, well,
I've taken a quick look at Visitor, but the change seems to me far less
obvious.

The way I see it, in the constructor we initialize the nesting to zero.
Each time:

"public void visit(Node.CustomTag n) throws JasperException"

is called we increment the nesting, and right after the call "visitBody(n);",
just before the method terminate we decrement the nesting count.

Obviously, we must keep track of the maximum depth level.  The information
is ready to be used at the end of the:

"public static void validate(Compiler compiler, ..."

method, this is the one that initiates the visit(XXX) calls, right?.

Would you like me to propose a patch for #1?  For #2?  And what about having
the maximum CustomTag nesting depth level available through PageInfo?

Thanks!

-- 
Denis Benoit
[EMAIL PROTECTED]


--
To unsubscribe, e-mail:   
For additional commands, e-mail: 




Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-17 Thread Kin-Man Chung

Denis,

Glad that you agree.  About the timing for the patch, I think now is OK.
Jasper 2 is fairly stable and the only bug that may interact with our
fix is 4964 and I already have a fix for it; but am hold off committing
it because struts depends on this bug, and my fix would break it! :-(

Now down to details.  :-)

Since a popBody is always followed by a release, it would be simpler
to have each stack element consists of two entries:

1. the tag, and
2. the state: 0 - release only
  1 - popBody and release.
  
That way we only need to do one push per tag handler.  Of course, all
tags would get state 0 first, and some of them would change to state 1
later.

For efficiency we can use two separate arrays for implementing the
stack: one for holding the tags, the other for keeping track of the state.
The code generated would be like:

stackIndex = -1;
...
++stackIndex;   // Entering a tag
MyTag mt = new MyTag();
tagStack[stackIndex] = mt;
stateStack[stackIndex] = 0; // state 0
if (_jspx_eval_myTag != EVAL_BODY_INCLUDE) {
stateStack[stackIndex] = 1;
...
}
...
--currentIndex; // Exiting a tag

This way, the size of the stack is the maximum number of nesting of the
tags, which should much smaller than the number of tags in the page.
Such information is easy to collect in Jasper 2, which can be
done either in Validator.java, or we have a separate pass whose sole
purpose is to collect info such as this.

- Kin-man

> Date: Thu, 16 May 2002 23:16:15 -0400 (EDT)
> From: Denis Benoit <[EMAIL PROTECTED]>
> Subject: Re: [PATCH] Re: [PROPOSAL] Modification of the code generated by 
Jasper2
> To: Kin-Man Chung <[EMAIL PROTECTED]>
> Cc: [EMAIL PROTECTED]
> MIME-version: 1.0
> 

> 
> > Now you mentioned the use of an array to hold tag objects, I have
> > another idea.  Why don't we use a stack to simulate the runtime state?
> > Each stack entry would have a tag object and a state.  State 0 means
> > call release() only, and state 1 means call popBody() and then release().
> > We push an entry onto the stack when we enter a tag body, and pop it
> > when we exit the body.  We change the state on the stack top when we do
> > a pushBody.  When an exception is thrown, we just need to pop the entries
> > from the stack to decide what to do.  For efficiency, we can use an
> > array to simulate the stack, and its size would be the number of nesting
> > of the tags.
> > 
> > I think this is quite simple and faster.  What do you think?
> 
> Yes! Yes!
> 
> In my last e-mail, I mentionned that there is only two actions that we need
> to do in the "finallies".  This is:
> 
>   1) do a release() on a Tag
>   2) do a popBody()
> 
> We could push on the stack in this order:
> 
> Either:
>   1- A tag
>   2- The Action identifier for release (a Constant representing 
"release()")
> Or:
>   1- The Action identifier for popBody (a Constant representing 
"popBody()")
> 
> 
> Now the "finallies" code look like this:
> 
>   While stack is not empty:
>   Pop an action
>   If action is RELEASE then
>   pop a Tag
>   Do a Tag.release()
>   Otherwise /* Action is assumed to be POPBODY */
>   do a popBody()
> 
> So the "finallies" could very well be "inlined" because it would be short.
> 
> The other modification would be when we begin the "pseudo" finally block.  At
> that point we have to remove from the stack what was pushed at the begin of
> the "pseudo" try block.  If we do a popBody() in the "finally", then we must
> pop one element.  If we do a release(), we will pop two elements.
> 
> In the event of an exception anywhere in the page, the stack would contain
> only the actions that must be performed in the order to be performed.  Your
> solution is clean, efficient and simple!
> 
> The stack could very well be an Object[], but if we must rely on arrayCopy(),
> to extend the array periodically, would it be really much more efficient than
> using a plain Stack object?  After all, this is the way a Stack is implemented
> by the JDK itself.  On the other hand, we know the lower and upper bounds of 
the
> stack.  Each tag will need to be pushed at least once for the "release()" and
> the action identifier will need to be pushed too (so we push two times the
> number of Tags in the page).  And maybe we will need to push once more for a
> "popBody()" (so one more time to indicate the action).
> 
> This would give us an array of size 2 to 3 times the number of tags in the 
page.
> I think it would be more efficient to allocate an array of 3 times the number 
of
> tags and save us the occasional overhead of arrayCopy() calls to extend the 
array.
> 
> Now, I see two ways to determine the size of the array. 

Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-16 Thread Denis Benoit

Mr Chung,

You mentioned three areas where the code could be improved.

On Thu, 16 May 2002, Kin-Man Chung wrote:

> 1. I notice the following code pattern that is now generated.
> 
> bitmask.set(1);
> addTagToVector(tags, 1, new Integer(_jspx_eval_eg_foo_0));
> if (_jspx_eval_eg_foo_0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUD
> E) {
>   out = pageContext.pushBody();
>   _jspx_th_eg_foo_0.setBodyContent((javax.servlet.jsp.tagext.BodyContent
> ) out);
>   _jspx_th_eg_foo_0.doInitBody();
> }
> 
> and from finallies:
> 
> if (bitmask.get(1)) {
>   if (((Integer)tags.elementAt(1)).intValue() != javax.servlet.jsp.tagext.Ta
> g.EVAL_BODY_INCLUDE)
> out = pageContext.popBody();
> }
> 
> I notice that the code "bitmask.set(1);" is there just for popBody, so
> if we move it to inside the test that do pushBody, then we don't need
> to do the test in the finallies.  See the codes below.
> 
> addTagToVector(tags, 1, new Integer(_jspx_eval_eg_foo_0));
> if (_jspx_eval_eg_foo_0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUD
> E) {
>   bitmask.set(1);
>   out = pageContext.pushBody();
>   _jspx_th_eg_foo_0.setBodyContent((javax.servlet.jsp.tagext.BodyContent
> ) out);
>   _jspx_th_eg_foo_0.doInitBody();
> }
> 
> and in finallies:
> 
> if (bitmask.get(1)) {
> out = pageContext.popBody();
> }
> 
> Maybe you don't need to change the argument for addTagToVector afterall!

You're right, in fact, we might get rid of the addTagToVector completely with
your next two proposals.


> 2. We don't really need to call finallies if there is no exceptions, so
> the call to finallies can be placed in a catch block instead of a finally
> block.  This would save us time to check for all the bits that have been
> cleared, under normal execution.

Yes, this is a very good point.


> Now you mentioned the use of an array to hold tag objects, I have
> another idea.  Why don't we use a stack to simulate the runtime state?
> Each stack entry would have a tag object and a state.  State 0 means
> call release() only, and state 1 means call popBody() and then release().
> We push an entry onto the stack when we enter a tag body, and pop it
> when we exit the body.  We change the state on the stack top when we do
> a pushBody.  When an exception is thrown, we just need to pop the entries
> from the stack to decide what to do.  For efficiency, we can use an
> array to simulate the stack, and its size would be the number of nesting
> of the tags.
> 
> I think this is quite simple and faster.  What do you think?

Yes! Yes!

In my last e-mail, I mentionned that there is only two actions that we need
to do in the "finallies".  This is:

1) do a release() on a Tag
2) do a popBody()

We could push on the stack in this order:

Either:
1- A tag
2- The Action identifier for release (a Constant representing "release()")
Or:
1- The Action identifier for popBody (a Constant representing "popBody()")


Now the "finallies" code look like this:

While stack is not empty:
Pop an action
If action is RELEASE then
pop a Tag
Do a Tag.release()
Otherwise /* Action is assumed to be POPBODY */
do a popBody()

So the "finallies" could very well be "inlined" because it would be short.

The other modification would be when we begin the "pseudo" finally block.  At
that point we have to remove from the stack what was pushed at the begin of
the "pseudo" try block.  If we do a popBody() in the "finally", then we must
pop one element.  If we do a release(), we will pop two elements.

In the event of an exception anywhere in the page, the stack would contain
only the actions that must be performed in the order to be performed.  Your
solution is clean, efficient and simple!

The stack could very well be an Object[], but if we must rely on arrayCopy(),
to extend the array periodically, would it be really much more efficient than
using a plain Stack object?  After all, this is the way a Stack is implemented
by the JDK itself.  On the other hand, we know the lower and upper bounds of the
stack.  Each tag will need to be pushed at least once for the "release()" and
the action identifier will need to be pushed too (so we push two times the
number of Tags in the page).  And maybe we will need to push once more for a
"popBody()" (so one more time to indicate the action).

This would give us an array of size 2 to 3 times the number of tags in the page.
I think it would be more efficient to allocate an array of 3 times the number of
tags and save us the occasional overhead of arrayCopy() calls to extend the array.

Now, I see two ways to determine the size of the array.  Either, after
generating the _jsp_service() method, the class 

Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-16 Thread Kin-Man Chung

Denis,

First let me mention a couple of improvements over the existing codes
that was generated for flattening out the try/catch block.  See if
you agree with me.

1. I notice the following code pattern that is now generated.

bitmask.set(1);
addTagToVector(tags, 1, new Integer(_jspx_eval_eg_foo_0));
if (_jspx_eval_eg_foo_0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUD
E) {
  out = pageContext.pushBody();
  _jspx_th_eg_foo_0.setBodyContent((javax.servlet.jsp.tagext.BodyContent
) out);
  _jspx_th_eg_foo_0.doInitBody();
}

and from finallies:

if (bitmask.get(1)) {
  if (((Integer)tags.elementAt(1)).intValue() != javax.servlet.jsp.tagext.Ta
g.EVAL_BODY_INCLUDE)
out = pageContext.popBody();
}

I notice that the code "bitmask.set(1);" is there just for popBody, so
if we move it to inside the test that do pushBody, then we don't need
to do the test in the finallies.  See the codes below.

addTagToVector(tags, 1, new Integer(_jspx_eval_eg_foo_0));
if (_jspx_eval_eg_foo_0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUD
E) {
  bitmask.set(1);
  out = pageContext.pushBody();
  _jspx_th_eg_foo_0.setBodyContent((javax.servlet.jsp.tagext.BodyContent
) out);
  _jspx_th_eg_foo_0.doInitBody();
}

and in finallies:

if (bitmask.get(1)) {
out = pageContext.popBody();
}

Maybe you don't need to change the argument for addTagToVector afterall!

2. We don't really need to call finallies if there is no exceptions, so
the call to finallies can be placed in a catch block instead of a finally
block.  This would save us time to check for all the bits that have been
cleared, under normal execution.


Now you mentioned the use of an array to hold tag objects, I have
another idea.  Why don't we use a stack to simulate the runtime state?
Each stack entry would have a tag object and a state.  State 0 means
call release() only, and state 1 means call popBody() and then release().
We push an entry onto the stack when we enter a tag body, and pop it
when we exit the body.  We change the state on the stack top when we do
a pushBody.  When an exception is thrown, we just need to pop the entries
from the stack to decide what to do.  For efficiency, we can use an
array to simulate the stack, and its size would be the number of nesting
of the tags.

I think this is quite simple and faster.  What do you think?



--
To unsubscribe, e-mail:   
For additional commands, e-mail: 




Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-09 Thread Denis Benoit

Kim,

On Thu, 9 May 2002, Kin-Man Chung wrote:

> If we have distinct values for each state, theorectically we can implement
> a state transition machine in the finallies.  Something like the following.
> 
>   while (state > 0) {
>   switch (state) {
>   case 0: ...
>   state = 3; break;   // goto state 3
>   case 1:
>   state = 13; break;  // goto state 13
>   ...
>   case 10: ...
>   state = -1; break   // stop
>   }
>}

Yes, that could be some thing to implement, when "generating" the code for a
state we have to know two things, the state itself, and the next state, it
may very well be possible.

Thinking about it, I think this is a feature that we could take advantage from.
Whenever we hit a state, the next state is determined and so on.

The more I look at it, the more it looks like a state machine.  Then, why not
implement it as a regular state machine in an array?  We could build a static
array at compile time, and just modify a state variable at run time that
represent the index in the array.  Then, if an exception occurs, we would only
have to apply the state to the static array to find out what we have to do.

I definitively need to think more about it, but it seems that we have something
here.

> 
> There maybe other ways to branch out part of the code in _jspService to
> a method.  I am considering moving the body of a tag that does not have
> scriptlets out; but that's just a thought at this moments.
> 
> Even if we do keep finallies, it may worth looking into passing all the
> necessary objects as arguments to it, instead of putting them in a Vector,
> at least for the case with samll number of states.  I think VM spec allows
> 256 arguments to a method.  :-)  We want to avoid "unnecessay" codes in
> the main flow, but can afford to work harder when exceptions occur.

What about keeping a reference to the elements in an array?  Assignment to
an array element is not very costly.  We could even use the array elements
themselves instead of creating distinct variables for each tag.

If we do it this way, it can very well pave the way to reuse elements in
the same page.  Whenever we call "release()" on a Tag, instead of allocating
a new tag of the same type, we could reuse the tag, no?  I thought that the
specs allowed optimization of this sort?

If we have an array of tags, then the array of the state machine begins to
take form.  We could have "four columns" in the array (either objects to
hold the 4 data elements, or four distinct arrays).

The index of the array would be the state, the first "element of the row"
would be the next state (-1) for done.  The second "element of the row"
would be the action to perform, either "release()" or "popBody()", and
the last "element of the row" would be the index in the Tag array to apply
the action to (only meaningful for "release()").

The state array is "final static", built at compile time and never modified
for a given JSP, so thread safe.  The finallies method would only have to
loop thru the states and apply the action to the tags.

I need to think more about it, but it's starting to take form.

What do you think about it?

-- 
Denis Benoit
[EMAIL PROTECTED]


--
To unsubscribe, e-mail:   
For additional commands, e-mail: 




Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-09 Thread Kin-Man Chung

See intermixed.

> Date: Thu, 09 May 2002 20:48:27 -0400 (EDT)
> From: Denis Benoit <[EMAIL PROTECTED]>
> Subject: Re: [PATCH] Re: [PROPOSAL] Modification of the code generated by 
Jasper2

> 
> Good idea, but I think it would be hard to accomplish as presented.  Look 
again
> at your pseudo-code:
> 
> > int state = 0;
> > // try {// 1st try
> > ++state;
> > ...
> > // try {// 2nd try
> > ++state;
> > ;;;
> > // }// end of 2nd try
> > --state;
> > // try {// 3rd try
> > ++state;
> > ;;;
> > // }// end of 2nd try
> > --state;
> > // }// end of 1st try
> 
> You'll notice that both state 2 and state 3 have the value 2 assigned to the
> state variable.  What is complex here, is that it is hard to find a generic
> way to represent all the states possible.  Sometimes the states are nested,
> like the first with the 2nd and 3rd.  Sometimes the states follow one another,
> like the second and third.
> 

I realized my mistake as soon as I sent it out.  :-) 

> But there is surely something to do.  Suppose we assign distinct values to
> the state variable at each step where we enter a "pseudo try" and a
> "pseudo finally".  Then, theoritically, it should be possible to determine
> in the "finallies" method, just by looking at the value of the state variable
> what remains to do.  The problem could be to do it in exactly the same order
> that would have been done if the page would have nested try/finally clauses.
> 

If we have distinct values for each state, theorectically we can implement
a state transition machine in the finallies.  Something like the following.

while (state > 0) {
switch (state) {
case 0: ...
state = 3; break;   // goto state 3
case 1:
state = 13; break;  // goto state 13
...
case 10: ...
state = -1; break   // stop
}
 }
 
This way we can specify any sequence we want.  Of course there are various
optimizations that one can do here, but I won't go into them here.

> If we look at what we have to do in the "finallies" method, we have 
essentially
> two types of method call.  Either the "popBody()" or the "release()" of a Tag.
> I'm certainly not expert enough with the JSP specs to take a decision.  Is it
> critical that we call the "release()" of the tags in the proper order, if all
> what's left to do is "release()" calls?  What about the popBody()?
> 

popBody() simulates popping stacks, and has to be called in order.

> If we could do the "popBody()" calls out of order, say after all the 
"release()"
> have been called, then the case of the "popBody()" is easy to deal with.  We
> just have to increment a counter for each "pushBody()" calls and decrement
> it after each "popBody()" calls.  In the "finallies" method we only have to
> call "popBody()" the number of times the value of the counter.  If so, the
> state variable would only to have to represent the different combinations that
> the tags "doStartTag()" have been called and if their respective "release()"
> have been called.
> 

Unfortunately we cannot call release() before calling popBody(), because
popBody() may use resources released by release().  (I'll need to check
that).

> I'm a little cautious about "inlining" the "finallies" method, because of
> java's 64K per method limitation.  One of the first pass of my test JSP did
> generate over 64K in the _jsp_service method, so it generated an "Invalid
> branch" exception or something named like that.  Once I removed a few tags,
> the page worked fine.  It's easy to bypass by "JSP include", but some people
> might find the message cryptic (it is!), to determine what's exactly the
> problem.  The _jsp_service method can be really long, even without the
> "finallies" being inlined.  That's why I had created a new method.
> 

There maybe other ways to branch out part of the code in _jspService to
a method.  I am considering moving the body of a tag that does not have
scriptlets out; but that's just a thought at this moments.

Even if we do keep finallies, it may worth looking into passing all the
necessary objects as arguments to it, instead of putting them in a Vector,
at least for the case with samll number of states.  I think VM spec allows
256 arguments to a method.  :-)  We want to avoid "unnecessay" codes in
the main flow, but can afford to work harder when exceptions occur.

> Your idea of getting information from the PageInfo is certainly welcome.  This
> way we could prevent the creation of the "finallies" method and
> "addTagToVector".  We could even replace the Vector by an Array that could be
> allocated to the proper size at the start of the method.  It would prevent to
> have to cope with the expansion of a Vector.  Your idea of the "state" 
variable,
> me

Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-09 Thread Denis Benoit

Mr Chung,

On Thu, 9 May 2002, Kin-Man Chung wrote:

> Denis,
> 
> One way to get rid of BidSet is to keep the state of things that needs to
> be done in the (now virtual) finally block.  Since the try blocks are
> properly nested, it is sufficient to increment the state when entering
> a try block, and to decrement it when exiting a try block.  Something
> like:
> 
>   int state = 0;
>   // try {// 1st try
>   ++state;
>   ...
>   // try {// 2nd try
>   ++state;
>   ;;;
>   // }// end of 2nd try
>   --state;
>   // try {// 3rd try
>   ++state;
>   ;;;
>   // }// end of 2nd try
>   --state;
>   // }// end of 1st try
>   
> Then in finallies, you can do
> 
>   if (state >= 1 && state <= 3) {
>   if (state == 2) {
>   // do finally for 2nd try
>   } else if (state == 3) {
>   // do finally for the 3rd try
>   }
>   // do finally for 1st try
>}
>
> and so forth.  I think it would be faster than using bitset.
> 
> To avoid using a Vector, you can try inlining finallies in _jspService
> method.  The compiler needs to keep track of what needs to be done
> at the finally blocks for each of the state, but we don't need to do
> any of the Vector operations at all, a big performance gain.  If you
> insist on having a separate finallies, then you can still pass all the
> objects it needs to it as arguments.
> 
> In is now possible in jasper2 to scan the nodes for the page and collection
> infos on the page (that's what PageInfo class is for), and the compiler
> only needs to generate codes that is really necessary.  For instance,
> the generation of the method addTagToVector can be ommited when there is no
> custom tag action in the page.  I can add such info in PageInfo, now
> that there is a use.
> 
> Comments?

Good idea, but I think it would be hard to accomplish as presented.  Look again
at your pseudo-code:

>   int state = 0;
>   // try {// 1st try
>   ++state;
>   ...
>   // try {// 2nd try
>   ++state;
>   ;;;
>   // }// end of 2nd try
>   --state;
>   // try {// 3rd try
>   ++state;
>   ;;;
>   // }// end of 2nd try
>   --state;
>   // }// end of 1st try

You'll notice that both state 2 and state 3 have the value 2 assigned to the
state variable.  What is complex here, is that it is hard to find a generic
way to represent all the states possible.  Sometimes the states are nested,
like the first with the 2nd and 3rd.  Sometimes the states follow one another,
like the second and third.

But there is surely something to do.  Suppose we assign distinct values to
the state variable at each step where we enter a "pseudo try" and a
"pseudo finally".  Then, theoritically, it should be possible to determine
in the "finallies" method, just by looking at the value of the state variable
what remains to do.  The problem could be to do it in exactly the same order
that would have been done if the page would have nested try/finally clauses.

If we look at what we have to do in the "finallies" method, we have essentially
two types of method call.  Either the "popBody()" or the "release()" of a Tag.
I'm certainly not expert enough with the JSP specs to take a decision.  Is it
critical that we call the "release()" of the tags in the proper order, if all
what's left to do is "release()" calls?  What about the popBody()?

If we could do the "popBody()" calls out of order, say after all the "release()"
have been called, then the case of the "popBody()" is easy to deal with.  We
just have to increment a counter for each "pushBody()" calls and decrement
it after each "popBody()" calls.  In the "finallies" method we only have to
call "popBody()" the number of times the value of the counter.  If so, the
state variable would only to have to represent the different combinations that
the tags "doStartTag()" have been called and if their respective "release()"
have been called.

I'm a little cautious about "inlining" the "finallies" method, because of
java's 64K per method limitation.  One of the first pass of my test JSP did
generate over 64K in the _jsp_service method, so it generated an "Invalid
branch" exception or something named like that.  Once I removed a few tags,
the page worked fine.  It's easy to bypass by "JSP include", but some people
might find the message cryptic (it is!), to determine what's exactly the
problem.  The _jsp_service method can be really long, even without the
"finallies" being inlined.  That's why I had created a new method.

Your idea of getting information from the PageInfo is certainly welcome.  This
way we could prevent the creation of the "finallies" method and
"addTagToVector".  We could ev

Re: [PATCH] Re: [PROPOSAL] Modification of the code generated byJasper2

2002-05-09 Thread Kin-Man Chung


> Date: Wed, 08 May 2002 20:50:06 -0400 (EDT)
> 
> Mr Maucherat noticed that the patch do create a BitSet and a Vector, even for
> JSPs that don't have tags, I think it could be avoided if we did some kind of
> lazy initialisation.  My first, dumb, I confess! idea was to put the Vector
> and the BitSet as instance variables, but Mr Barker was quick to point out
> that it would cause thread problem.  My idea was then to have the patch mature
> and if everything was ok to do a second pass to optimize it.
> 

> -- 
> Denis Benoit
> [EMAIL PROTECTED]
> 

Denis,

One way to get rid of BidSet is to keep the state of things that needs to
be done in the (now virtual) finally block.  Since the try blocks are
properly nested, it is sufficient to increment the state when entering
a try block, and to decrement it when exiting a try block.  Something
like:

int state = 0;
// try {// 1st try
++state;
...
// try {// 2nd try
++state;
;;;
// }// end of 2nd try
--state;
// try {// 3rd try
++state;
;;;
// }// end of 2nd try
--state;
// }// end of 1st try

Then in finallies, you can do

if (state >= 1 && state <= 3) {
if (state == 2) {
// do finally for 2nd try
} else if (state == 3) {
// do finally for the 3rd try
}
// do finally for 1st try
 }
 
and so forth.  I think it would be faster than using bitset.

To avoid using a Vector, you can try inlining finallies in _jspService
method.  The compiler needs to keep track of what needs to be done
at the finally blocks for each of the state, but we don't need to do
any of the Vector operations at all, a big performance gain.  If you
insist on having a separate finallies, then you can still pass all the
objects it needs to it as arguments.

In is now possible in jasper2 to scan the nodes for the page and collection
infos on the page (that's what PageInfo class is for), and the compiler
only needs to generate codes that is really necessary.  For instance,
the generation of the method addTagToVector can be ommited when there is no
custom tag action in the page.  I can add such info in PageInfo, now
that there is a use.

Comments?



--
To unsubscribe, e-mail:   
For additional commands, e-mail: