Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 615fff058785
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c30e0ecc0b47
Choose a head ref
  • 4 commits
  • 10 files changed
  • 1 contributor

Commits on Sep 9, 2016

  1. Copy the full SHA
    fb8ebff View commit details
  2. [Truffle] Add a new native memory manager, as the rest are so complic…

    …ated.
    
    Maybe I'll figure out why they're complicated in the future.
    chrisseaton committed Sep 9, 2016
    Copy the full SHA
    69ce166 View commit details
  3. 5
    Copy the full SHA
    58e79d5 View commit details
  4. Copy the full SHA
    c30e0ec View commit details
69 changes: 69 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/core/rope/NativeRope.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.core.rope;

import org.jcodings.Encoding;
import org.jruby.truffle.platform.NativePointer;
import org.jruby.truffle.platform.SimpleNativeMemoryManager;
import org.jruby.util.unsafe.UnsafeHolder;

public class NativeRope extends Rope {

private final int length;
private NativePointer pointer;

public NativeRope(SimpleNativeMemoryManager nativeMemoryManager, byte[] bytes, Encoding encoding, int characterLength) {
super(encoding, CodeRange.CR_UNKNOWN, false, bytes.length, characterLength, 1, null);

length = bytes.length;

pointer = nativeMemoryManager.allocate(length);

for (int n = 0; n < length; n++) {
pointer.writeByte(n, bytes[n]);
}
}

@Override
protected byte[] getBytesSlow() {
final byte[] bytes = new byte[length];

for (int n = 0; n < length; n++) {
bytes[n] = pointer.readByte(n);
}

return bytes;
}

@Override
public byte getByteSlow(int index) {
return get(index);
}

@Override
public byte get(int index) {
return pointer.readByte(index);
}

@Override
public String toString() {
throw new UnsupportedOperationException();
}

@Override
public Rope withEncoding(Encoding newEncoding, CodeRange newCodeRange) {
throw new UnsupportedOperationException();
}

public NativePointer getNativePointer() {
return pointer;
}

}
Original file line number Diff line number Diff line change
@@ -10,13 +10,18 @@
package org.jruby.truffle.interop.cext;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.RubyLanguage;
import org.jruby.truffle.core.rope.NativeRope;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.rope.RopeNodes.GetByteNode;
import org.jruby.truffle.core.rope.RopeNodesFactory.GetByteNodeGen;
import org.jruby.truffle.core.string.StringNodes.SetByteNode;
@@ -98,4 +103,36 @@ private SetByteNode getHelperNode() {

}

@Resolve(message = "UNBOX")
public static abstract class ForeignUnboxNode extends Node {

@Child private Node findContextNode;

private final ConditionProfile convertProfile = ConditionProfile.createBinaryProfile();

@CompilationFinal private RubyContext context;

protected Object access(CExtString cExtString) {
final Rope currentRope = Layouts.STRING.getRope(cExtString.getString());

final NativeRope nativeRope;

if (convertProfile.profile(currentRope instanceof NativeRope)) {
nativeRope = (NativeRope) currentRope;
} else {
if (findContextNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
findContextNode = insert(RubyLanguage.INSTANCE.unprotectedCreateFindContextNode());
context = RubyLanguage.INSTANCE.unprotectedFindContext(findContextNode);
}

nativeRope = new NativeRope(context.getNativePlatform().getSimpleNativeMemoryManager(), currentRope.getBytes(), currentRope.getEncoding(), currentRope.characterLength());
Layouts.STRING.setRope(cExtString.getString(), nativeRope);
}

return nativeRope.getNativePointer().getAddress();
}

}

}
Original file line number Diff line number Diff line change
@@ -23,6 +23,8 @@ public interface NativePlatform {

MemoryManager getMemoryManager();

SimpleNativeMemoryManager getSimpleNativeMemoryManager();

SignalManager getSignalManager();

ProcessName getProcessName();
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform;

public interface NativePointer {

long getAddress();

byte readByte(long offset);
void writeByte(long offset, byte value);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform;

public interface SimpleNativeMemoryManager {

NativePointer allocate(long size);

}
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.jruby.truffle.platform.NativePlatform;
import org.jruby.truffle.platform.ProcessName;
import org.jruby.truffle.platform.RubiniusConfiguration;
import org.jruby.truffle.platform.SimpleNativeMemoryManager;
import org.jruby.truffle.platform.java.JavaClockGetTime;
import org.jruby.truffle.platform.openjdk.OpenJDKArrayBlockingQueueLocksConditions;
import org.jruby.truffle.platform.openjdk.OpenJDKLinkedBlockingQueueLocksConditions;
@@ -30,11 +31,15 @@
import org.jruby.truffle.platform.posix.TrufflePosixHandler;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscUnsafeSimpleNativeMemoryManager;
import org.jruby.util.unsafe.UnsafeHolder;
import sun.misc.Unsafe;

public class DarwinPlatform implements NativePlatform {

private final TrufflePosix posix;
private final MemoryManager memoryManager;
private final SimpleNativeMemoryManager simpleNativeMemoryManager;
private final SignalManager signalManager;
private final ProcessName processName;
private final Sockets sockets;
@@ -44,6 +49,7 @@ public class DarwinPlatform implements NativePlatform {
public DarwinPlatform(RubyContext context) {
posix = new JNRTrufflePosix(POSIXFactory.getNativePOSIX(new TrufflePosixHandler(context)));
memoryManager = Runtime.getSystemRuntime().getMemoryManager();
simpleNativeMemoryManager = new SunMiscUnsafeSimpleNativeMemoryManager(UnsafeHolder.U);
signalManager = new SunMiscSignalManager();
processName = new DarwinProcessName();
sockets = LibraryLoader.create(Sockets.class).library("c").load();
@@ -63,6 +69,11 @@ public MemoryManager getMemoryManager() {
return memoryManager;
}

@Override
public SimpleNativeMemoryManager getSimpleNativeMemoryManager() {
return simpleNativeMemoryManager;
}

@Override
public SignalManager getSignalManager() {
return signalManager;
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import org.jruby.truffle.platform.NativePlatform;
import org.jruby.truffle.platform.ProcessName;
import org.jruby.truffle.platform.RubiniusConfiguration;
import org.jruby.truffle.platform.SimpleNativeMemoryManager;
import org.jruby.truffle.platform.linux.LinuxRubiniusConfiguration;
import org.jruby.truffle.platform.openjdk.OpenJDKArrayBlockingQueueLocksConditions;
import org.jruby.truffle.platform.openjdk.OpenJDKLinkedBlockingQueueLocksConditions;
@@ -27,11 +28,14 @@
import org.jruby.truffle.platform.posix.TrufflePosixHandler;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscUnsafeSimpleNativeMemoryManager;
import org.jruby.util.unsafe.UnsafeHolder;

public class JavaPlatform implements NativePlatform {

private final TrufflePosix posix;
private final MemoryManager memoryManager;
private final SimpleNativeMemoryManager simpleNativeMemoryManager;
private final SignalManager signalManager;
private final ProcessName processName;
private final Sockets sockets;
@@ -41,6 +45,7 @@ public class JavaPlatform implements NativePlatform {
public JavaPlatform(RubyContext context) {
posix = new JavaTrufflePosix(POSIXFactory.getJavaPOSIX(new TrufflePosixHandler(context)));
memoryManager = new JavaMemoryManager();
simpleNativeMemoryManager = new SunMiscUnsafeSimpleNativeMemoryManager(UnsafeHolder.U);
signalManager = new SunMiscSignalManager();
processName = new JavaProcessName();
sockets = new JavaSockets();
@@ -60,6 +65,11 @@ public MemoryManager getMemoryManager() {
return memoryManager;
}

@Override
public SimpleNativeMemoryManager getSimpleNativeMemoryManager() {
return simpleNativeMemoryManager;
}

@Override
public SignalManager getSignalManager() {
return signalManager;
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
import org.jruby.truffle.platform.NativePlatform;
import org.jruby.truffle.platform.ProcessName;
import org.jruby.truffle.platform.RubiniusConfiguration;
import org.jruby.truffle.platform.SimpleNativeMemoryManager;
import org.jruby.truffle.platform.java.JavaProcessName;
import org.jruby.truffle.platform.openjdk.OpenJDKArrayBlockingQueueLocksConditions;
import org.jruby.truffle.platform.openjdk.OpenJDKLinkedBlockingQueueLocksConditions;
@@ -30,11 +31,14 @@
import org.jruby.truffle.platform.posix.TrufflePosixHandler;
import org.jruby.truffle.platform.signal.SignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscSignalManager;
import org.jruby.truffle.platform.sunmisc.SunMiscUnsafeSimpleNativeMemoryManager;
import org.jruby.util.unsafe.UnsafeHolder;

public class LinuxPlatform implements NativePlatform {

private final TrufflePosix posix;
private final MemoryManager memoryManager;
private final SimpleNativeMemoryManager simpleNativeMemoryManager;
private final SignalManager signalManager;
private final ProcessName processName;
private final Sockets sockets;
@@ -44,6 +48,7 @@ public class LinuxPlatform implements NativePlatform {
public LinuxPlatform(RubyContext context) {
posix = new JNRTrufflePosix(POSIXFactory.getNativePOSIX(new TrufflePosixHandler(context)));
memoryManager = Runtime.getSystemRuntime().getMemoryManager();
simpleNativeMemoryManager = new SunMiscUnsafeSimpleNativeMemoryManager(UnsafeHolder.U);
signalManager = new SunMiscSignalManager();
processName = new JavaProcessName();
sockets = LibraryLoader.create(Sockets.class).library("c").load();
@@ -63,6 +68,11 @@ public MemoryManager getMemoryManager() {
return memoryManager;
}

@Override
public SimpleNativeMemoryManager getSimpleNativeMemoryManager() {
return simpleNativeMemoryManager;
}

@Override
public SignalManager getSignalManager() {
return signalManager;
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.platform.sunmisc;

import org.jruby.truffle.platform.NativePointer;
import org.jruby.truffle.platform.SimpleNativeMemoryManager;
import sun.misc.Unsafe;

public class SunMiscUnsafeSimpleNativeMemoryManager implements SimpleNativeMemoryManager {

private final Unsafe unsafe;

public SunMiscUnsafeSimpleNativeMemoryManager(Unsafe unsafe) {
this.unsafe = unsafe;
}

@Override
public NativePointer allocate(long size) {
final long address = unsafe.allocateMemory(size);

if (address == 0) {
throw new OutOfMemoryError();
}

// TODO deallocation

return new UnsafeNativePointer(address);
}

private class UnsafeNativePointer implements NativePointer {

private final long address;

public UnsafeNativePointer(long address) {
this.address = address;
}

@Override
public long getAddress() {
return address;
}

@Override
public byte readByte(long offset) {
return unsafe.getByte(address + offset);
}

@Override
public void writeByte(long offset, byte value) {
unsafe.putByte(address + offset, value);
}
}

}
2 changes: 1 addition & 1 deletion truffle/src/main/ruby/core/truffle/cext.rb
Original file line number Diff line number Diff line change
@@ -293,7 +293,7 @@ def rb_str_new(cext_str, length)
end

def rb_str_new_nul(length)
'\0' * length
"\0" * length
end

def rb_str_new_cstr(java_string)