Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug on array spread operator on NodeJS 6.10.0 with --optimize_for_size #11545

Closed
vitorbaptista opened this issue Feb 24, 2017 · 8 comments
Closed
Labels
v8 engine Issues and PRs related to the V8 dependency.

Comments

@vitorbaptista
Copy link

vitorbaptista commented Feb 24, 2017

  • Version: v6.10.0 and v6.9.5
  • Platform: Linux sager 4.4.0-64-generic Update README.md #85-Ubuntu SMP Mon Feb 20 11:50:30 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

The following code causes an error:

'use strict';
const assert = require('assert');
const entities = Array.apply(null, { length: 1000 }).map(() => (
  {}
));

const bulkBody = entities.reduce((res, entity) => {
  const action = {
    foo: {
      bar: 10,
      baz: 20,
      foobar: undefined,
    },
  };

  // no-op
  if (false) {
    let a;
    let b;
  }

  return [
    ...res,
    action,
    entity,
  ];
}, []);

assert(bulkBody.length == 2 * entities.length, `bulkBody.length: ${bulkBody.length}\tentities.length: ${entities.length}`);

Note that on each loop of the reduce we add 2 elements to the result array. As it starts as an empty array (i.e. with 0 elements), at the end we expect that bulkBody.length == 2 * entities.length. This isn't what happens. See:

$ node --version
v6.10.0
$ node error/reproduce.js  # no errors
$ node --optimize_for_size error/reproduce.js 

assert.js:85
  throw new assert.AssertionError({
  ^
AssertionError: bulkBody.length: 1999   entities.length: 1000
    at Object.<anonymous> (/home/vitor/Projetos/okfn/opentrials/api/error/reproduce.js:29:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3
$ nvm use 5.6.0
Now using node v5.6.0 (npm v3.6.0)
$ node --version
v5.6.0
$ node error/reproduce.js 
$ node --optimize_for_size error/reproduce.js

I tested both on 6.10.0 and 6.9.5 and the error is the same. Note that the code has many no-op operations. If you remove the if (false) {} clause, for example, the error isn't triggered. If you change the entities array length from 1000 to 10000 (for example), the error isn't triggered either. Even if you change the foobar: undefined to foobar: 30, the error isn't triggered.

It seems like that Node is optimizing a very specific code and, if we change even no-op code, the bug isn't triggered.

@fernandobrito
Copy link

I could reproduce it on:

$ node --version
v6.10.0

$ node reproduce.js # no error
$ node --optimize_for_size reproduce.js                                                                                                                                                           

assert.js:85
  throw new assert.AssertionError({
  ^
AssertionError: bulkBody.length: 1999   entities.length: 1000
    at Object.<anonymous> (/tmp/reproduce.js:29:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3

v7.6.0 seems to be unaffacted.

$ node --version
v7.6.0
$ node reproduce.js                                                                                                                                                                               
$ node --optimize_for_size reproduce.js

@mscdex mscdex added v8 engine Issues and PRs related to the V8 dependency. v6.x labels Feb 24, 2017
@mscdex
Copy link
Contributor

mscdex commented Feb 24, 2017

/cc @nodejs/v8

vitorbaptista added a commit to opentrials/api that referenced this issue Feb 25, 2017
The error was caused by a bug on NodeJS 6.9.5 (possibly 6.x), reported on
nodejs/node#11545.

opentrials/opentrials#693
vitorbaptista added a commit to opentrials/api that referenced this issue Feb 25, 2017
The error was caused by a bug on NodeJS 6.9.5 (possibly 6.x), reported on
nodejs/node#11545.

opentrials/opentrials#693
@bnoordhuis
Copy link
Member

Interesting bug. I can reproduce and a quick investigation suggests it might have something to do with allocation site pretenuring in Crankshaft.

--trace_deopt logs a rather suspicious reason: allocation-site-tenuring-changed message and adding either --noallocation_site_pretenuring or --nocrankshaft makes the test pass reliably again.

It sometimes passes without the flags too so there is a timing aspect to it as well but I'm reasonably sure allocation site pretenuring is involved somehow.

@targos
Copy link
Member

targos commented Feb 27, 2017

I can't reproduce with d8 (5.1.281.75)

@targos
Copy link
Member

targos commented Feb 28, 2017

@nodejs/v8 FYI I built several 5.x-lkgr V8 branches on 64bit Linux to be able to check easily which release fixes a particular issue. Binaries are here: https://github.com/targos/d8/tree/master/bin

@Trott
Copy link
Member

Trott commented Jul 27, 2017

Is this still a bug in Node.js 6.11.1? (Bug isn't tripped on my operating system, so I'm guessing it's Linux-specific.)

@bnoordhuis
Copy link
Member

I can still reproduce, on MacOS too. Try running it in a loop:

$ for i in {0..99}; do ./tmp/node-v6.11.1-darwin-x64/bin/node --optimize_for_size tmp/bug11545.js || break; done

assert.js:81
  throw new assert.AssertionError({
  ^
AssertionError: bulkBody.length: 1999   entities.length: 1000
    at Object.<anonymous> (/Users/bnoordhuis/src/v1.x/tmp/bug11545.js:29:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:504:3

@apapirovski
Copy link
Member

Works as expected 6.14.0 so I guess this did get fixed at some point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v8 engine Issues and PRs related to the V8 dependency.
Projects
None yet
Development

No branches or pull requests

7 participants