/* * Copyright 2016 higherfrequencytrading.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.openhft.lang.io; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import sun.misc.Unsafe; import java.nio.CharBuffer; import java.security.AccessController; import java.security.PrivilegedAction; interface CharBufferReuse { CharBufferReuse INSTANCE = Inner.getReuse(); CharBuffer reuse(CharSequence cs, CharBuffer toReuse); class Inner extends Reuses implements Opcodes { private static CharBufferReuse getReuse() { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; final String reuseImplClassName = "net/openhft/lang/io/CharBufferReuseImpl"; cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, reuseImplClassName, null, "sun/reflect/MagicAccessorImpl", new String[] {"net/openhft/lang/io/CharBufferReuse"}); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "reuse", "(Ljava/lang/CharSequence;Ljava/nio/CharBuffer;)Ljava/nio/CharBuffer;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 2); String stringCharBuffer = "java/nio/StringCharBuffer"; mv.visitTypeInsn(INSTANCEOF, stringCharBuffer); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); mv.visitVarInsn(ALOAD, 2); mv.visitTypeInsn(CHECKCAST, stringCharBuffer); mv.visitVarInsn(ASTORE, 3); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_M1); mv.visitFieldInsn(PUTFIELD, stringCharBuffer, "mark", "I"); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ICONST_0); mv.visitFieldInsn(PUTFIELD, stringCharBuffer, "position", "I"); mv.visitVarInsn(ALOAD, 1); String charSequence = "java/lang/CharSequence"; mv.visitMethodInsn(INVOKEINTERFACE, charSequence, "length", "()I", true); mv.visitVarInsn(ISTORE, 4); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 4); mv.visitFieldInsn(PUTFIELD, stringCharBuffer, "limit", "I"); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ILOAD, 4); mv.visitFieldInsn(PUTFIELD, stringCharBuffer, "capacity", "I"); mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, stringCharBuffer, "str", "Ljava/lang/CharSequence;"); mv.visitVarInsn(ALOAD, 3); mv.visitInsn(ARETURN); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitTypeInsn(NEW, stringCharBuffer); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ICONST_0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEINTERFACE, charSequence, "length", "()I", true); mv.visitMethodInsn(INVOKESPECIAL, stringCharBuffer, "<init>", "(Ljava/lang/CharSequence;II)V", false); mv.visitInsn(ARETURN); mv.visitMaxs(5, 5); mv.visitEnd(); } cw.visitEnd(); final byte[] impl = cw.toByteArray(); final Unsafe unsafe = NativeBytes.UNSAFE; Class clazz = AccessController.doPrivileged(new PrivilegedAction<Class>() { @Override public Class run() { ClassLoader cl = MAGIC_CLASS_LOADER; return unsafe.defineClass(reuseImplClassName, impl, 0, impl.length, cl, null); } }); try { return (CharBufferReuse) clazz.newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } } }