<commit_before>/**
 *
 * Copyright 2011 (C) The original author or authors
 *
 * 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 com.toolazydogs.maiden.agent.asm;

import java.util.logging.Logger;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;


/**
 *
 */
public class WaitNotifyMethodVisitor implements MethodVisitor, Opcodes
{
    private final static String CLASS_NAME = WaitNotifyMethodVisitor.class.getName();
    private final static Logger LOGGER = Logger.getLogger(CLASS_NAME);
    private final MethodVisitor visitor;
    private State state = State.NONE;
    private int line;
    private long milliseconds;
    private int nanoseconds;

    public WaitNotifyMethodVisitor(MethodVisitor visitor)
    {
        this.visitor = visitor;
    }

    public AnnotationVisitor visitAnnotationDefault() { return visitor.visitAnnotationDefault(); }

    public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return visitor.visitAnnotation(desc, visible); }

    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { return visitor.visitParameterAnnotation(parameter, desc, visible); }

    public void visitAttribute(Attribute attr) { visitor.visitAttribute(attr); }

    public void visitCode() { visitor.visitCode(); }

    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack)
    {
        flush();
        visitor.visitFrame(type, nLocal, local, nStack, stack);
    }

    public void visitInsn(int opcode)
    {
        LOGGER.entering(CLASS_NAME, "visitInsn", opcode);

        if (state == State.FOUND_ALOAD0 && (opcode == LCONST_0 || opcode == LCONST_1))
        {
            milliseconds = opcode - LCONST_0;
            state = State.FOUND_MILLISECONDS;
        }
        else if (state == State.FOUND_MILLISECONDS && (opcode >= ICONST_0 && opcode <= ICONST_5))
        {
            nanoseconds = opcode - ICONST_0;
            state = State.FOUND_NANOSECONDS;
        }
        else
        {
            flush();
            visitor.visitInsn(opcode);
        }

        LOGGER.exiting(CLASS_NAME, "visitInsn");
    }

    public void visitIntInsn(int opcode, int operand)
    {
        LOGGER.entering(CLASS_NAME, "visitInsn", new Object[]{opcode, operand});

        if (state == State.FOUND_MILLISECONDS && (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH))
        {
            nanoseconds = opcode;
            state = State.FOUND_NANOSECONDS;
        }
        else
        {
            flush();
            visitor.visitIntInsn(opcode, operand);
        }

        LOGGER.exiting(CLASS_NAME, "visitIntInsn");
    }

    public void visitVarInsn(int opcode, int var)
    {
        LOGGER.entering(CLASS_NAME, "visitVarInsn", new Object[]{opcode, var});

        if (state == State.NONE && opcode == ALOAD && var == 0)
        {
            state = State.FOUND_ALOAD0;
        }
        else
        {
            flush();
            visitor.visitVarInsn(opcode, var);
        }

        LOGGER.exiting(CLASS_NAME, "visitVarInsn");
    }

    public void visitTypeInsn(int opcode, String type)
    {
        flush();
        visitor.visitTypeInsn(opcode, type);
    }

    public void visitFieldInsn(int opcode, String owner, String name, String desc)
    {
        flush();
        visitor.visitFieldInsn(opcode, owner, name, desc);
    }

    public void visitMethodInsn(int opcode, String owner, String name, String desc)
    {
        LOGGER.entering(CLASS_NAME, "visitVarInsn", new Object[]{opcode, owner, name, desc});

        if (opcode == INVOKEVIRTUAL)
        {
            boolean wait = "java/lang/Object".equals(owner) && "wait".equals(name);
            boolean notify = "java/lang/Object".equals(owner) && "notify".equals(name);
            boolean notifyAll = "java/lang/Object".equals(owner) && "notifyAll".equals(name);

            if (wait)
            {
                if (state == State.FOUND_ALOAD0)
                {
                    AsmUtils.push(visitor, line);
                    visitor.visitVarInsn(ALOAD, 0);
                    visitor.visitMethodInsn(INVOKESTATIC, "com/toolazydogs/maiden/IronMaiden", "waitStart", "(ILjava/lang/Object;)V");

                    state = State.NONE;
                }
                if (state == State.FOUND_MILLISECONDS)
                {
                    AsmUtils.push(visitor, line);
                    visitor.visitVarInsn(ALOAD, 0);
                    AsmUtils.push(visitor, milliseconds);
                    visitor.visitMethodInsn(INVOKESTATIC, "com/toolazydogs/maiden/IronMaiden", "waitStart", "(ILjava/lang/Object;J)V");<commit_msg>Minor performance improvement<commit_after>/**
 *
 * Copyright 2011 (C) The original author or authors
 *
 * 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 com.toolazydogs.maiden.agent.asm;

import java.util.logging.Logger;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;


/**
 *
 */
public class WaitNotifyMethodVisitor implements MethodVisitor, Opcodes
{
    private final static String CLASS_NAME = WaitNotifyMethodVisitor.class.getName();
    private final static Logger LOGGER = Logger.getLogger(CLASS_NAME);
    private final MethodVisitor visitor;
    private State state = State.NONE;
    private int line;
    private long milliseconds;
    private int nanoseconds;

    public WaitNotifyMethodVisitor(MethodVisitor visitor)
    {
        this.visitor = visitor;
    }

    public AnnotationVisitor visitAnnotationDefault() { return visitor.visitAnnotationDefault(); }

    public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return visitor.visitAnnotation(desc, visible); }

    public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { return visitor.visitParameterAnnotation(parameter, desc, visible); }

    public void visitAttribute(Attribute attr) { visitor.visitAttribute(attr); }

    public void visitCode() { visitor.visitCode(); }

    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack)
    {
        flush();
        visitor.visitFrame(type, nLocal, local, nStack, stack);
    }

    public void visitInsn(int opcode)
    {
        LOGGER.entering(CLASS_NAME, "visitInsn", opcode);

        if (state == State.FOUND_ALOAD0 && (opcode == LCONST_0 || opcode == LCONST_1))
        {
            milliseconds = opcode - LCONST_0;
            state = State.FOUND_MILLISECONDS;
        }
        else if (state == State.FOUND_MILLISECONDS && (opcode >= ICONST_0 && opcode <= ICONST_5))
        {
            nanoseconds = opcode - ICONST_0;
            state = State.FOUND_NANOSECONDS;
        }
        else
        {
            flush();
            visitor.visitInsn(opcode);
        }

        LOGGER.exiting(CLASS_NAME, "visitInsn");
    }

    public void visitIntInsn(int opcode, int operand)
    {
        LOGGER.entering(CLASS_NAME, "visitInsn", new Object[]{opcode, operand});

        if (state == State.FOUND_MILLISECONDS && (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH))
        {
            nanoseconds = opcode;
            state = State.FOUND_NANOSECONDS;
        }
        else
        {
            flush();
            visitor.visitIntInsn(opcode, operand);
        }

        LOGGER.exiting(CLASS_NAME, "visitIntInsn");
    }

    public void visitVarInsn(int opcode, int var)
    {
        LOGGER.entering(CLASS_NAME, "visitVarInsn", new Object[]{opcode, var});

        if (state == State.NONE && opcode == ALOAD && var == 0)
        {
            state = State.FOUND_ALOAD0;
        }
        else
        {
            flush();
            visitor.visitVarInsn(opcode, var);
        }

        LOGGER.exiting(CLASS_NAME, "visitVarInsn");
    }

    public void visitTypeInsn(int opcode, String type)
    {
        flush();
        visitor.visitTypeInsn(opcode, type);
    }

    public void visitFieldInsn(int opcode, String owner, String name, String desc)
    {
        flush();
        visitor.visitFieldInsn(opcode, owner, name, desc);
    }

    public void visitMethodInsn(int opcode, String owner, String name, String desc)
    {
        LOGGER.entering(CLASS_NAME, "visitVarInsn", new Object[]{opcode, owner, name, desc});

        if (opcode == INVOKEVIRTUAL)
        {
            boolean ownerIsObject = "java/lang/Object".equals(owner);
            boolean wait = ownerIsObject && "wait".equals(name);
            boolean notify = ownerIsObject && "notify".equals(name);
            boolean notifyAll = ownerIsObject && "notifyAll".equals(name);

            if (wait)
            {
                if (state == State.FOUND_ALOAD0)
                {
                    AsmUtils.push(visitor, line);
                    visitor.visitVarInsn(ALOAD, 0);
                    visitor.visitMethodInsn(INVOKESTATIC, "com/toolazydogs/maiden/IronMaiden", "waitStart", "(ILjava/lang/Object;)V");

                    state = State.NONE;
                }
                if (state == State.FOUND_MILLISECONDS)
                {
                    AsmUtils.push(visitor, line);
                    visitor.visitVarInsn(ALOAD, 0);
                    AsmUtils.push(visitor, milliseconds);
                    visitor.visitMethodInsn(INVOKESTATIC, "com/toolazydogs/maiden/IronMaiden", "waitStart", "(ILjava/lang/Object;J)V");
{'fraction_non_alphanumeric': 0.10328285203649704, 'fraction_numerical': 0.0037625811306556296, 'mean_word_length': 2.4893337709222187, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6544465', 'n_tokens_mistral': 3100, 'n_tokens_neox': 3049, 'n_words': 742}