JDK-8166902 : Nested object literal property maps not reset in optimistic recompilation
  • Type: Bug
  • Component: core-libs
  • Sub-Component: jdk.nashorn
  • Affected Version: 8u102,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2016-09-29
  • Updated: 2017-11-29
  • Resolved: 2016-09-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u152Fixed 9 b139Fixed
Description
Reported on nashorn-dev: http://mail.openjdk.java.net/pipermail/nashorn-dev/2016-September/006504.html

When optimistic conversion is triggered during initialization of an object literal, we have a mechanism to update the property map of the object as the types may (and probably will) have changed.

However, this is only done for the top-level object in a nested object initializer. There are cases where the map may have to be updated on outer objects as well, as the example code below shows. The reason is that we may have better type information during recompilation because of type evaluation, for instance.

=================================================================

var o = {
   a: "LEARN_MORE",
   b: "http:/some.url",
};

var m = {
   x: { z: o.a },
   y: o.b
};

print(m.x.z);
print(m.y);

===================================================================

Expected output: 

LEARN_MORE
http:/some.url

Actual output:

LEARN_MORE
0

Comments
While my initial analysis of the cause was correct, the fix suggested was wrong. In fact, object literals are expected to change property maps during recompilation. This was implemented/fixed in JDK-8041995 and JDK-8043133. However, this is only done for the top level object map. As this example shows, it may be possible to update the property maps on several objects in a nested object literal.
30-09-2016

What's happening is that the assignments of properties in question are initially optimistic. Then the initialization of the nested object (linkData.call_to_action in the example code) throws a RewriteException and triggers a recompilation. However, in the recompiled code the property assignment are not optimistic anymore, therefore no RewriteException is thrown and the type mismatch with the existing type map goes unnoticed. It looks like the TypeEvaluator is to blame for making assignments non-optimistic in recompiled code, so one solution might be not to run the TypeEvaluator on optimistic recompilation.
29-09-2016