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

[Truffle] SystemStackError in String#[] #4394

Closed
eregon opened this issue Dec 17, 2016 · 5 comments
Closed

[Truffle] SystemStackError in String#[] #4394

eregon opened this issue Dec 17, 2016 · 5 comments
Assignees
Milestone

Comments

@eregon
Copy link
Member

eregon commented Dec 17, 2016

I was looking at running my solution for http://adventofcode.com/2016/day/16 with JRuby+Truffle, but it seems it does not like to look in the 35MB String.

The full code is at https://gist.github.com/eregon/fdf20a89763e87045cbefb9309cef76c
I also tried a variant by pre-allocating a String and modifying it, but then []= died in stack overflow.

Here is a small repro:

length = 10*1024*1024
buf = ""
length.times {
  buf << "0"
}
p buf[buf.size-1] # OK
p buf[0] # NOK
@eregon eregon added the truffle label Dec 17, 2016
@eregon eregon added this to the truffle-dev milestone Dec 17, 2016
@eregon
Copy link
Member Author

eregon commented Dec 17, 2016

Here is a repro for String#[]=:

length = 10*1024*1024
buf = " " * length
length.times { |i|
  buf[i] = "0"
}
p buf[0]

and the backtrace:

$ jth ruby --graal 16bug2.rb                                           
.../jruby-dev/truffle/src/main/ruby/core/string_mirror.rb:65:in `splice': stack level too deep (SystemStackError)
	from .../jruby-dev/truffle/src/main/ruby/core/string.rb:1308:in `[]='
	from 16bug2.rb:4:in `block in <main>'
	from 16bug2.rb:3:in `times'
	from 16bug2.rb:3:in `<main>'

@bjfish
Copy link
Contributor

bjfish commented Dec 18, 2016

I'll mention this old pull request since it might have been trying to solve a similar issue:
#4201

@nirvdrum
Copy link
Contributor

This is unfortunately a pathological case for ropes currently. Replacing each byte or character is problematic because the ropes themselves are read-only. Preallocating really has no additional benefit because you're not going to update bytes in a fixed buffer. But, if you really just wanted 35 MB of "0", then String#* is your best bet.

I'll see if I can find a way to make this work better.

@eregon
Copy link
Member Author

eregon commented Dec 19, 2016

At first I do not care so much about performance, but at least it should not stack overflow.
My guess would be it should be a loop for looking up a character in a rope and not recursive calls.

The first snippet only does appends, so that one should not be so bad with ropes, isn't it?

@eregon
Copy link
Member Author

eregon commented Dec 20, 2016

It looks like 8abc05a solves both cases, thank you!
The full script, using << is reasonably fast but slower than MRI, and surprisingly the version using []= is about the same speed, while I was not patient enough to wait for MRI to terminate.

@eregon eregon closed this as completed Dec 20, 2016
@enebo enebo added this to the Non-Release milestone Dec 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants