Bug 558844 - ? : Operator causes java.lang.VerifyError: Inconsistent stackmap frames
Summary: ? : Operator causes java.lang.VerifyError: Inconsistent stackmap frames
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.14   Edit
Hardware: All All
: P3 major with 1 vote (vote)
Target Milestone: 4.15 M1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords: regression
: 558821 559094 559155 560504 562610 (view as bug list)
Depends on:
Blocks:
 
Reported: 2020-01-06 10:48 EST by Sascha Warmeling CLA
Modified: 2021-07-09 02:16 EDT (History)
12 users (show)

See Also:


Attachments
Proposed patch + regression test (3.45 KB, patch)
2020-01-06 12:18 EST, Olivier Thomann CLA
no flags Details | Diff
Proposed patch + regression test (3.70 KB, patch)
2020-01-06 14:57 EST, Olivier Thomann CLA
no flags Details | Diff
jdt core gerrit config screenshot (84.78 KB, image/png)
2020-01-06 17:53 EST, Andrey Loskutov CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sascha Warmeling CLA 2020-01-06 10:48:08 EST
This error doesn't come if you compile with older versions of eclipse...

The testcode:
public class CrashTest {
	
	public static void main( String[] args ) {
		System.out.println(new CrashTest().getText());
	}

	public String getText() {
		Long lValue1 = getValue1();
		Long lValue2 = getValue2();
		return ( isValue1() ? "" : ( lValue1 == null ? "" : lValue1.toString() ) + "-" ) + ( lValue2 == null ? "" : lValue2.toString() );
	}

	private Long getValue1() {
		return Long.valueOf( 1 );
	}

	private Long getValue2() {
		return Long.valueOf( 1 );
	}

	private boolean isValue1() {
		return false;
	}
}

Causes: 
Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 39
Exception Details:
  Location:
    CrashTest.getText()Ljava/lang/String; @39: aload_1
  Reason:
    Type uninitialized 26 (current frame, stack[2]) is not assignable to uninitialized 10 (stack map, stack[2])
  Current Frame:
    bci: @31
    flags: { }
    locals: { 'CrashTest', 'java/lang/Long', 'java/lang/Long' }
    stack: { uninitialized 10, uninitialized 10, uninitialized 26, uninitialized 26, 'java/lang/Long' }
  Stackmap Frame:
    bci: @39
    flags: { }
    locals: { 'CrashTest', 'java/lang/Long', 'java/lang/Long' }
    stack: { uninitialized 10, uninitialized 10, uninitialized 10, uninitialized 10 }
  Bytecode:
    0x0000000: 2ab7 0023 4c2a b700 274d bb00 2a59 2ab7
    0x0000010: 002c 9900 0812 30a7 0022 bb00 2a59 2bc7
    0x0000020: 0008 1230 a700 072b b600 32b8 0037 b700
    0x0000030: 3d12 3fb6 0041 b600 45b8 0037 b700 3d2c
    0x0000040: c700 0812 30a7 0007 2cb6 0032 b600 41b6
    0x0000050: 0045 b0                                
  Stackmap Table:
    full_frame(@26,{Object[#1],Object[#51],Object[#51]},{Uninitialized[#10],Uninitialized[#10]})
    full_frame(@39,{Object[#1],Object[#51],Object[#51]},{Uninitialized[#10],Uninitialized[#10],Uninitialized[#10],Uninitialized[#10]})
    full_frame(@43,{Object[#1],Object[#51],Object[#51]},{Uninitialized[#10],Uninitialized[#10],Uninitialized[#10],Uninitialized[#10],Object[#56]})
    full_frame(@57,{Object[#1],Object[#51],Object[#51]},{Uninitialized[#10],Uninitialized[#10],Object[#56]})
    same_locals_1_stack_item_frame(@72,Object[#42])
    full_frame(@76,{Object[#1],Object[#51],Object[#51]},{Object[#42],Object[#56]})

	at java.lang.Class.getDeclaredMethods0(Native Method)
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
	at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
	at java.lang.Class.getMethod0(Class.java:3018)
	at java.lang.Class.getMethod(Class.java:1784)
	at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
	at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Comment 1 Olivier Thomann CLA 2020-01-06 11:00:34 EST
I will take a look at it.
Comment 2 Olivier Thomann CLA 2020-01-06 12:18:23 EST
Created attachment 281385 [details]
Proposed patch + regression test

Jay, Manoj, could you please deliver this one to master? Thanks.
Comment 3 Andrey Loskutov CLA 2020-01-06 13:24:24 EST
*** Bug 558821 has been marked as a duplicate of this bug. ***
Comment 4 Eclipse Genie CLA 2020-01-06 13:27:51 EST
New Gerrit change created: https://git.eclipse.org/r/155329
Comment 5 Andrey Loskutov CLA 2020-01-06 13:54:25 EST
(In reply to Eclipse Genie from comment #4)
> New Gerrit change created: https://git.eclipse.org/r/155329

Olivier, looking on the patch I wonder why equals() and hashCode() in VerificationTypeInfo.java are not symmetrical.

See
https://git.eclipse.org/r/#/c/155329/1/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java@199

and

https://git.eclipse.org/r/#/c/155329/1/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java@206

equals() uses tag, constantPoolName and offset, but hashCode uses tag, constantPoolName and *id*. Bug or feature? If later, I think we should explain this in the code.
Comment 6 Andrey Loskutov CLA 2020-01-06 14:30:00 EST
(In reply to Andrey Loskutov from comment #5) 
> Olivier, looking on the patch I wonder why equals() and hashCode() in
> VerificationTypeInfo.java are not symmetrical.
 
> equals() uses tag, constantPoolName and offset, but hashCode uses tag,
> constantPoolName and *id*. Bug or feature? If later, I think we should
> explain this in the code.

Looking further, VerificationTypeInfo.hashCode() value is not constant, because all fields from which the hash is computed can be changed after object creation. This is highly dangerous.

Is VerificationTypeInfo.hashCode() really used somewhere in the code? If yes, it  probably shouldn't be in the current state.

But I assume this is not relevant for the current bug, so should I create another one to request removal of current hashCode() implementation from VerificationTypeInfo (should just use Object.hashCode())? The code was added via  commit https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=7818c2b6805e0779da46c84f61ed508653a87614 without further explanation.
Comment 7 Olivier Thomann CLA 2020-01-06 14:40:43 EST
(In reply to Andrey Loskutov from comment #5)
> See
> https://git.eclipse.org/r/#/c/155329/1/org.eclipse.jdt.core/compiler/org/
> eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java@199
> 
> and
> 
> https://git.eclipse.org/r/#/c/155329/1/org.eclipse.jdt.core/compiler/org/
> eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java@206
> 
> equals() uses tag, constantPoolName and offset, but hashCode uses tag,
> constantPoolName and *id*. Bug or feature? If later, I think we should
> explain this in the code.

I think it should be consistent. This is a potential bug and yes, these instances are used in an Hashmap so these methods are used.
Comment 8 Andrey Loskutov CLA 2020-01-06 14:50:49 EST
(In reply to Olivier Thomann from comment #7)
> I think it should be consistent. This is a potential bug and yes, these
> instances are used in an Hashmap so these methods are used.

I would open another bug for that. Can you please point me to the places where VerificationTypeInfo is used in maps/sets?
Comment 9 Olivier Thomann CLA 2020-01-06 14:56:30 EST
(In reply to Andrey Loskutov from comment #8)
> (In reply to Olivier Thomann from comment #7)
> > I think it should be consistent. This is a potential bug and yes, these
> > instances are used in an Hashmap so these methods are used.
> 
> I would open another bug for that. Can you please point me to the places
> where VerificationTypeInfo is used in maps/sets?
This is done in the duplicate() code to handle instances that needs to be the same instance and not a copy.
I'll provide a new patch for that. Let's fix it all together.
Comment 10 Olivier Thomann CLA 2020-01-06 14:57:36 EST
Created attachment 281389 [details]
Proposed patch + regression test

New patch for a new gerrit. Jay, I think we should have a quick talk so I know how to setup my environment to trigger gerrit builds myself.
Comment 11 Andrey Loskutov CLA 2020-01-06 15:36:03 EST
(In reply to Olivier Thomann from comment #10)
> Created attachment 281389 [details]
> Proposed patch + regression test
> 
> New patch for a new gerrit.

I will push it with a small change in the evaluation order in equals, to have slower char[] comparison last in equals() and a call to constantPoolName() instead of this.binding.constantPoolName() in hashCode().
Comment 13 Andrey Loskutov CLA 2020-01-06 17:53:27 EST
Created attachment 281390 [details]
jdt core gerrit config screenshot

(In reply to Olivier Thomann from comment #10)
> Jay, I think we should have a quick talk so I
> know how to setup my environment to trigger gerrit builds myself.

Olivier, can I help you?
At which step are you failing?
Please check https://wiki.eclipse.org/Platform-releng/Git_Workflows#Gerrit_workflow_for_a_committer

The most important part is probably that you shouldn't use ssh but fetch/push to https://git.eclipse.org/r/jdt/eclipse.jdt.core.git url, see attached picture for remote configuration.

Once you get this remote config done, the only thing to remember is to "amend" commits if you are re-working the same patch.
Comment 14 Jay Arthanareeswaran CLA 2020-01-07 01:16:31 EST
(In reply to Olivier Thomann from comment #10)
> Jay, I think we should have a quick talk so I
> know how to setup my environment to trigger gerrit builds myself.

Sure, we can catch up soon to set it up if you haven't already done it yourself.

And I will soon start creating backport patches as soon as I am bring my current work to conclusion.

BTW, thanks Andrey, for the instruction!
Comment 15 Andrey Loskutov CLA 2020-01-07 07:33:46 EST
CrashTest snippet and snippet from bug 558821 are working now, JDT tests are green too. Closing.

Thanks Olivier!
Comment 16 Andrey Loskutov CLA 2020-01-07 07:34:03 EST
Verified with  I20200106-1805
Comment 17 Mark Thomas CLA 2020-01-07 09:43:46 EST
Confirmed the test case derived from Tomcat reported in bug 558821 is also fixed. Tested with I20200107-0600.

Thanks for the rapid fix.
Comment 18 Andrey Loskutov CLA 2020-01-13 04:32:56 EST
*** Bug 559094 has been marked as a duplicate of this bug. ***
Comment 19 Andrey Loskutov CLA 2020-01-14 07:51:18 EST
*** Bug 559155 has been marked as a duplicate of this bug. ***
Comment 20 George Suaridze CLA 2020-01-21 10:35:54 EST
Can you please port this to 2019-12 Eclipse or we should wait 2020-03?
Comment 21 Andrey Loskutov CLA 2020-01-21 10:50:44 EST
(In reply to George Suaridze from comment #20)
> Can you please port this to 2019-12 Eclipse or we should wait 2020-03?

There will be no backporting to 4.14. You can either pick 4.15 M1 or wait for 4.15. Also you can try build Eclipse from sources by yourself, if this is urgent issue and you need this patch backported to 4.14 build in your project.
Comment 22 George Suaridze CLA 2020-01-21 11:18:28 EST
Andrey, thanks!

I'll give 4.15 M1 a try.
Comment 23 Andrey Loskutov CLA 2020-02-25 06:38:42 EST
*** Bug 560504 has been marked as a duplicate of this bug. ***
Comment 24 Andrey Loskutov CLA 2020-04-29 09:46:21 EDT
*** Bug 562610 has been marked as a duplicate of this bug. ***