[SOLVED] je_realloc crashes the JVM

Started by SHC, September 13, 2015, 07:43:48

Previous topic - Next topic

SHC

When I try to realloc (resize my buffer) with a new size, the JVM is crashing at

j  org.lwjgl.system.JNI.invokePPP(JJJ)J+0
j  org.lwjgl.system.jemalloc.JEmalloc.nje_realloc(JJ)J+12
j  org.lwjgl.system.jemalloc.JEmalloc.je_realloc(Ljava/nio/ByteBuffer;J)Ljava/nio/ByteBuffer;+5
j  com.shc.silenceengine.utils.BufferUtils.resizeBuffer(Ljava/nio/Buffer;I)Ljava/nio/ByteBuffer;+6


The code for my resizeBuffer method is as follows.

public static ByteBuffer resizeBuffer(Buffer buffer, int newSize)
{
    return je_realloc(MemoryUtil.memByteBuffer(memAddress(buffer), buffer.capacity()), newSize);
}


Am I doing something wrong?

spasi

Quote from: SHC on September 13, 2015, 07:43:48When I try to realloc (resize my buffer) with a new size, the JVM is crashing

A possible cause is: LWJGL always uses the current buffer position() when passing pointers to native code. If the buffer passed to resizeBuffer is not at position(0), then je_malloc is being asked to realloc a pointer address it knows nothing about. If that's not the problem, then please post a simple sample (with both the allocation and reallocation code) that I could test.

Btw, the free functions have the same requirement. I might do a special case for such functions in the code generator, to always use the origin pointer address and ignore the current position.

Quote from: SHC on September 13, 2015, 07:43:48The code for my resizeBuffer method is as follows.

public static ByteBuffer resizeBuffer(Buffer buffer, int newSize)
{
    return je_realloc(MemoryUtil.memByteBuffer(memAddress(buffer), buffer.capacity()), newSize);
}

The code above does not compile and you don't need to create a ByteBuffer instance just to reallocate it immediately. You can work with the address directly by using the unsafe nje_realloc(long ptr, long size) method.


SHC

You're right @Spasi, but I had to look more into it to find the issue. After reading your message, I tried to reallocate the buffers after rewinding/flipping them, and still got no luck, even the free is behaving like that. I've also tried using the memAddress(buffer, 0) to explicitly specify the position, and still had no luck. I even tried the memAddress0 method.

Then I realized that I had been using glMapBuffer function and I'm assigning the returned ByteBuffer to the original ByteBuffer. The solution to it is to keep addresses of the original buffers upon creation as long variables, and use it instead of calling memAddress on the modified ByteBuffer. This worked fortunately, but I also had to re-query the memory addresses after resizing them.

And BTW, could you please clarify what is the difference between memAddress and memAddress0? I initially thought memAddress0 is the same as memAddress(buffer, 0), but I still doubt that. Thanks.

spasi

Quote from: SHC on September 14, 2015, 14:58:49Then I realized that I had been using glMapBuffer function and I'm assigning the returned ByteBuffer to the original ByteBuffer. The solution to it is to keep addresses of the original buffers upon creation as long variables, and use it instead of calling memAddress on the modified ByteBuffer. This worked fortunately, but I also had to re-query the memory addresses after resizing them.

Well, you cannot and should not use a buffer returned from glMapBuffer with realloc/free. That memory is managed by the OpenGL driver and the only thing you need to do is stop referencing the corresponding ByteBuffer after glUnmapBuffer.

Quote from: SHC on September 14, 2015, 14:58:49And BTW, could you please clarify what is the difference between memAddress and memAddress0? I initially thought memAddress0 is the same as memAddress(buffer, 0), but I still doubt that. Thanks.

memAddress0(buffer) returns the memory address at position 0.
memAddress(buffer) returns the memory address at the current buffer position.
memAddress(buffer, position) returns the memory address at the specified position.

So yes, memAddress0(buffer) and memAddress(buffer, 0) are equivalent. Also note that the position is an element offset, not a byte offset. So memAddress(floatBuffer, 2) is equivalent to memAddress0(floatBuffer) + 2 * 4.