-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
[fix] Maximum call stack size exceeded (#4694) #6716
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
[fix] Maximum call stack size exceeded (#4694) #6716
Conversation
922dd3a
to
7597e20
Compare
a test svelte/test/limits/index.tsimport { svelte } from '../helpers';
// [].push(...Array.from({ length: 125*1000 }))
// Uncaught RangeError: Maximum call stack size exceeded
const critical_width = 125*1000; // 4 seconds
//const critical_width = 500*1000; // 12 seconds
//const critical_width = 1000*1000; // 32 seconds
describe('limits', () => {
it(`can handle width of ${critical_width} elements`, function() {
this.timeout(5*1000);
// FIXME timeout does not kill the test, test hangs forever
let source = '';
for (let i = 0; i < critical_width; i++) {
source += `<br>`;
}
svelte.compile(source, {
generate: false // make test much faster
});
});
const depth_step = 200;
it(`find maximum depth of elements`, function() {
for (let critical_depth = 800; ; critical_depth += depth_step ) {
let source = '';
for (let i = 0; i < critical_depth; i++) {
source += `<div>`;
}
for (let i = 0; i < critical_depth; i++) {
source += `</div>`;
}
try {
svelte.compile(source, {
generate: false // make test much faster
});
}
catch (error) {
// error: maximum call stack size exceeded
console.log(` maximum depth is between ${critical_depth - depth_step} and ${critical_depth} elements`)
break
}
}
});
}); output:
when the element-depth is too large (elements are nested too deep), |
7597e20
to
b79a62d
Compare
b79a62d
to
3387e22
Compare
} | ||
count += other.length; | ||
} | ||
return count; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this need to return count
? the return value doesn't seem to ever be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
compatibility with Array.prototype.push
, almost zero cost
@@ -0,0 +1,11 @@ | |||
export function push_array(thisArray: any[], ...otherList: any[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, do we even need this method? It looks like we could just call concat
everywhere this is being called for the same effect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*usually* push is faster than concat. depends on the exact input data. i can add the concat version for benchmarks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are talking about the compiler step here (not runtime), do we really need to be that performance sensitive here if it doesn't make a difference of more than 0.1 ms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
benchmarks to the rescue ... in the worst case, this is hot code
closing for #7203 - thanks all : ) |
draft
start fixing #4694
the patch was generated with https://github.com/milahu/random/tree/master/svelte/patch-svelte-compiler-sources
ideally, the patch script would be implemented in eslint or putout
Before submitting the PR, please make sure you do the following
[feat]
,[fix]
,[chore]
, or[docs]
.Tests
npm test
and lint the project withnpm run lint
alternatives to pushArray
a very simple benchmark suggests that concat is faster than push
but performance depends on input data
todo: compare different methods with real-world data
to use
dst = dst.concat(src)
, we must transformconst dst
tolet dst