Package st.gravel.support.jvm.runtime

Source Code of st.gravel.support.jvm.runtime.AlmostFinalValue$AlmostFinalCallSite

package st.gravel.support.jvm.runtime;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.MutableCallSite;
import java.lang.invoke.SwitchPoint;

public class AlmostFinalValue {
    private final AlmostFinalCallSite callsite =
        new AlmostFinalCallSite(this);
   
    protected Object initialValue() {
      return null;
    }
   
    public MethodHandle createGetter() {
      return callsite.dynamicInvoker();
    }
   
    public Object setValue(Object value) {
      callsite.setValue(value);
      return value;
    }
   
    private static class AlmostFinalCallSite extends MutableCallSite {
      private Object value;
      private SwitchPoint switchPoint;
      private final AlmostFinalValue volatileFinalValue;
      private final MethodHandle fallback;
      private final Object lock;
     
      private static final Object NONE = new Object();
      private static final MethodHandle FALLBACK;
      static {
        try {
          FALLBACK = MethodHandles.lookup().findVirtual(AlmostFinalCallSite.class, "fallback",
              MethodType.methodType(Object.class));
        } catch (NoSuchMethodException|IllegalAccessException e) {
          throw new AssertionError(e.getMessage(), e);
        }
      }
     
      AlmostFinalCallSite(AlmostFinalValue volatileFinalValue) {
        super(MethodType.methodType(Object.class));
        Object lock = new Object();
        MethodHandle fallback = FALLBACK.bindTo(this);
        synchronized(lock) {
          value = NONE;
          switchPoint = new SwitchPoint();
          setTarget(fallback);
        }
        this.volatileFinalValue = volatileFinalValue;
        this.lock = lock;
        this.fallback = fallback;
      }

      Object fallback() {
        synchronized(lock) {
          Object value = this.value;
          if (value == NONE) {
            value = volatileFinalValue.initialValue();
          }
          MethodHandle target = switchPoint.guardWithTest(MethodHandles.constant(Object.class, value), fallback);
          setTarget(target);
          return value;
        }
      }
     
      void setValue(Object value) {
        synchronized(lock) {
          SwitchPoint switchPoint = this.switchPoint;
          this.value = value;
          this.switchPoint = new SwitchPoint();
          SwitchPoint.invalidateAll(new SwitchPoint[] {switchPoint});
        }
      }
    }
  }
TOP

Related Classes of st.gravel.support.jvm.runtime.AlmostFinalValue$AlmostFinalCallSite

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.