Package org.jruby.ext.ffi.jffi

Source Code of org.jruby.ext.ffi.jffi.JITCompiler$HandleRef

/*
*
*/
package org.jruby.ext.ffi.jffi;

import com.kenai.jffi.CallingConvention;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

import org.jruby.RubyInstanceConfig;
import org.jruby.ext.ffi.CallbackInfo;
import org.jruby.ext.ffi.MappedType;
import org.jruby.ext.ffi.NativeType;
import org.jruby.ext.ffi.Type;
import org.jruby.util.WeakIdentityHashMap;
import org.jruby.util.cli.Options;

/**
*
*/
class JITCompiler {
   
    private final Map<JITSignature, HandleRef>
            handles = new HashMap<JITSignature, HandleRef>();

    private final Map<Class<? extends NativeInvoker>, JITHandle>
            classes = new WeakHashMap();

    private final ReferenceQueue referenceQueue = new ReferenceQueue();
   
    private final JITHandle failedHandle = new JITHandle(this,
            new JITSignature(NativeType.VOID, new NativeType[0], false, new boolean[0], CallingConvention.DEFAULT, false),
            true);

    private static class SingletonHolder {
        private static final JITCompiler INSTANCE = new JITCompiler();
    }
   
    public static JITCompiler getInstance() {
        return SingletonHolder.INSTANCE;
    }
   
    private static final class HandleRef extends WeakReference<JITHandle> {
        JITSignature signature;

        public HandleRef(JITHandle handle, JITSignature signature, ReferenceQueue refqueue) {
            super(handle, refqueue);
            this.signature = signature;
        }
    }

    private void cleanup() {
        HandleRef ref;
        while ((ref = (HandleRef) referenceQueue.poll()) != null) {
            handles.remove(ref.signature);
        }
    }
   
   
    JITHandle getHandle(Signature signature, boolean unique) {
       
        boolean hasResultConverter = !(signature.getResultType() instanceof Type.Builtin);
        NativeType nativeResultType;
        Type resultType = signature.getResultType();
       
        if (resultType instanceof Type.Builtin || resultType instanceof CallbackInfo) {
            nativeResultType = resultType.getNativeType();
       
        } else if (resultType instanceof MappedType) {
            nativeResultType = ((MappedType) resultType).getRealType().getNativeType();
       
        } else {
            return failedHandle;
        }

        NativeType[] nativeParameterTypes = new NativeType[signature.getParameterCount()];
        boolean[] hasParameterConverter = new boolean[signature.getParameterCount()];
       
        for (int i = 0; i < hasParameterConverter.length; i++) {
            Type parameterType = signature.getParameterType(i);
            if (parameterType instanceof Type.Builtin || parameterType instanceof CallbackInfo) {
                nativeParameterTypes[i] = parameterType.getNativeType();
       
            } else if (parameterType instanceof MappedType) {
                nativeParameterTypes[i] = ((MappedType) parameterType).getRealType().getNativeType();
       
            } else {
                return failedHandle;
            }

            hasParameterConverter[i] = !(parameterType instanceof Type.Builtin)
                    || DataConverters.isEnumConversionRequired(parameterType, signature.getEnums());
        }
       
        JITSignature jitSignature = new JITSignature(nativeResultType, nativeParameterTypes,
                hasResultConverter, hasParameterConverter, signature.getCallingConvention(), signature.isIgnoreError());
       
        if (unique) {
            return new JITHandle(this, jitSignature, Options.COMPILE_MODE.load() == RubyInstanceConfig.CompileMode.OFF);
        }

        synchronized (this) {
            cleanup();
            HandleRef ref = handles.get(jitSignature);
            JITHandle handle = ref != null ? ref.get() : null;
            if (handle == null) {
                handle = new JITHandle(this, jitSignature, Options.COMPILE_MODE.load() == RubyInstanceConfig.CompileMode.OFF);
                handles.put(jitSignature, new HandleRef(handle, jitSignature, referenceQueue));
            }
           
            return handle;
        }
    }

    void registerClass(JITHandle handle, Class<? extends NativeInvoker> klass) {
        classes.put(klass, handle);
    }
}
TOP

Related Classes of org.jruby.ext.ffi.jffi.JITCompiler$HandleRef

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
ga('send', 'pageview');