On 6/30/2020 7:44 PM, Stuart Marks wrote:

An unconventional patch over an unusual hashcode/equals implementation is a bit too controversial. I'd like to propose a new patch that focus on the problem at hand, that is re-setting the opcode causes the item in HashSet to get lost because of the changed hash bucket. This patch therefore simply remove it from the HashSet before the change and then add it back as if it's a new item after setting the opcode. This patch resolves the issue while leaves BCEL 6.0's hashCode/equals alone.

Here's the new patch:
http://cr.openjdk.java.net/~joehw/jdk16/8248348/webrev02/

Hi Joe,

This makes a good deal more sense than the previous approach! As you note this preserves the consistency of equals() and hashCode(), which is an important invariant.

It seems a bit roundabout to have to remove something from the HashSet, mutate it, and re-add it, but I don't see an alternative. Mutating it while in the HashSet is the original cause of problem. Trying to contort things so that objects can remain in the HashSet while being mutated is difficult in general, and it seems likely to lead to additional problems. Given this, removing and re-adding seems the most sensible approach.

Indeed, mutating while in the HashSet indicates the code design might not have considered it could happen.

It's a bit fragile in that BranchInstruction now has to "know" that the InstructionTarget has a HashSet that requires this to be done. However, I don't see a way to avoid this without redesigning the relationships of the objects in this area -- which seems out of scope for this change.

Additional burden for BranchInstruction.  It would have been less troublesome if Instructions were not allowed to mutate, that is, changing opcode would mean creating new objects. But I think the intention is to reduce object creation (that worked for a straight forward compilation process).


Just one comment on the test: there are large test data files BCELHashCodeTest1.xsl and BCELHashCodeTest2.xsl. What are these? I'm not asking for a tutorial, but rather about what function they serve relative to this bug. Just a sentence or two about how BCELHashCodeTest2.xsl causes (I think) the generated bytecode to exceed the 64Kbyte method size limit. Splitting this into multiple methods requires mutating some of the instructions, and then hilarity ensued. :-)

I'm also not sure that BCELHashCodeTest1.xsl is necessary if it passes both with and without the patch. But if you think it's valuable, then it's ok for it to stay in.

Will add the comment to the DataProvider and update the webrev.

Aside from this, I think this change is good to go.

Thanks!

(had a nice hike today, and asked the beautiful Lake 22 ;-))

I had to look it up. Lake 22 looks very nice! Please give my regards the next time you visit.

It is! The trail itself is nice too with a stream running alongside. I'll tell Lake 22 you said hello next time ;-)

-Joe


s'marks

Reply via email to