nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
author lagergren
Fri, 22 Feb 2013 12:22:16 +0100
changeset 16256 f2d9a0c49914
parent 16234 86cb162cec6c
child 16277 fd698c5ee684
permissions -rw-r--r--
8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code Reviewed-by: attila, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime.linker;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.runtime.linker.Lookup.MH;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
import java.io.FileNotFoundException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import java.io.FileOutputStream;
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
    32
import java.io.PrintWriter;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import java.lang.invoke.MethodHandle;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import java.lang.invoke.MethodHandles;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import java.lang.invoke.MethodType;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    36
import java.util.ArrayList;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    37
import java.util.Collections;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import java.util.Comparator;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
import java.util.HashMap;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import java.util.LinkedList;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import java.util.Map;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    42
import java.util.Map.Entry;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import java.util.Random;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import java.util.Set;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import java.util.concurrent.atomic.AtomicInteger;
16234
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16201
diff changeset
    46
import jdk.internal.dynalink.ChainedCallSite;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16201
diff changeset
    47
import jdk.internal.dynalink.DynamicLinker;
86cb162cec6c 8008085: Integrate Dynalink source code into Nashorn codebase
attila
parents: 16201
diff changeset
    48
import jdk.internal.dynalink.linker.GuardedInvocation;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
import jdk.nashorn.internal.runtime.Context;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
import jdk.nashorn.internal.runtime.Debug;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
import jdk.nashorn.internal.runtime.ScriptObject;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import jdk.nashorn.internal.runtime.ScriptRuntime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
import jdk.nashorn.internal.runtime.options.Options;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
 * Relinkable form of call site.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
public class LinkerCallSite extends ChainedCallSite {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
    /** Maximum number of arguments passed directly. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    61
    public static final int ARGLIMIT = 250;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
    private static final String PROFILEFILE = Options.getStringProperty("nashorn.profilefile", "NashornProfile.txt");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
    private static final MethodHandle INCREASE_MISS_COUNTER = findOwnMH("increaseMissCount", Object.class, String.class, Object.class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    66
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    67
    LinkerCallSite(final NashornCallSiteDescriptor descriptor) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
        super(descriptor);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
        if (Context.DEBUG) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
            LinkerCallSite.count++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
     * Construct a new linker call site.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
     * @param name     Name of method.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
     * @param type     Method type.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
     * @param flags    Call site specific flags.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
     * @return New LinkerCallSite.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    80
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    81
    static LinkerCallSite newLinkerCallSite(final String name, final MethodType type, final int flags) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
        final NashornCallSiteDescriptor desc = NashornCallSiteDescriptor.get(name, type, flags);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    83
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    84
        if (desc.isProfile()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    85
            return ProfilingLinkerCallSite.newProfilingLinkerCallSite(desc);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    86
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
        if (desc.isTrace()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
            return new TracingLinkerCallSite(desc);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    92
        return new LinkerCallSite(desc);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    94
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    95
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
    public String toString() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    97
        return getDescriptor().toString();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
     * Get the descriptor for this callsite
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
     * @return a {@link NashornCallSiteDescriptor}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   103
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   104
    public NashornCallSiteDescriptor getNashornDescriptor() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   105
        return (NashornCallSiteDescriptor)getDescriptor();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   106
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   109
    public void relink(final GuardedInvocation invocation, final MethodHandle relink) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
        super.relink(invocation, getDebuggingRelink(relink));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   111
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   112
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   113
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
    public void resetAndRelink(final GuardedInvocation invocation, final MethodHandle relink) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
        super.resetAndRelink(invocation, getDebuggingRelink(relink));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   116
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   117
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
    private MethodHandle getDebuggingRelink(final MethodHandle relink) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   119
        if (Context.DEBUG) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
            return MH.filterArguments(relink, 0, getIncreaseMissCounter(relink.type().parameterType(0)));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   121
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
        return relink;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   124
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   125
    private MethodHandle getIncreaseMissCounter(final Class<?> type) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   126
        final MethodHandle missCounterWithDesc = MH.bindTo(INCREASE_MISS_COUNTER, getDescriptor().getName() + " @ " + getScriptLocation());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   127
        if (type == Object.class) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   128
            return missCounterWithDesc;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   129
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   130
        return MH.asType(missCounterWithDesc, missCounterWithDesc.type().changeParameterType(0, type).changeReturnType(type));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   131
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   132
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   133
    private static String getScriptLocation() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   134
        final StackTraceElement caller = DynamicLinker.getRelinkedCallSiteLocation();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   135
        return caller == null ? "unknown location" : (caller.getFileName() + ":" + caller.getLineNumber());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   136
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   137
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   138
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   139
     * Instrumentation - increase the miss count when a callsite misses. Used as filter
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   140
     * @param desc descriptor for table entry
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   141
     * @param self self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   142
     * @return self reference
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   143
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   144
    public static Object increaseMissCount(final String desc, final Object self) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   145
        ++missCount;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   146
        if(r.nextInt(100) < missSamplingPercentage) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   147
            AtomicInteger i = missCounts.get(desc);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   148
            if(i == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   149
                i = new AtomicInteger(1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   150
                missCounts.put(desc, i);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   151
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   152
                i.incrementAndGet();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   154
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
        return self;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   157
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   160
            return MH.findStatic(MethodHandles.lookup(), LinkerCallSite.class, name, MH.type(rtype, types));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   161
        } catch (final MethodHandleFactory.LookupException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
            return MH.findVirtual(MethodHandles.lookup(), LinkerCallSite.class, name, MH.type(rtype, types));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   163
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   164
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
    /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
     * Debugging call sites.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   169
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   170
    private static class ProfilingLinkerCallSite extends LinkerCallSite {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   171
        /** List of all profiled call sites. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   172
        private static LinkedList<ProfilingLinkerCallSite> profileCallSites = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   173
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   174
        /** Start time when entered at zero depth. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   175
        private long startTime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   176
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   177
        /** Depth of nested calls. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   178
        private int depth;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   179
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   180
        /** Total time spent in this call site. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   181
        private long totalTime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   183
        /** Total number of times call site entered. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   184
        private long hitCount;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
        private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
        private static final MethodHandle PROFILEENTRY    = MH.findVirtual(LOOKUP, ProfilingLinkerCallSite.class, "profileEntry",    MH.type(Object.class, Object.class));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   189
        private static final MethodHandle PROFILEEXIT     = MH.findVirtual(LOOKUP, ProfilingLinkerCallSite.class, "profileExit",     MH.type(Object.class, Object.class));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   190
        private static final MethodHandle PROFILEVOIDEXIT = MH.findVirtual(LOOKUP, ProfilingLinkerCallSite.class, "profileVoidExit", MH.type(void.class));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
        /*
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
         * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   194
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   195
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
        ProfilingLinkerCallSite(final NashornCallSiteDescriptor desc) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
           super(desc);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   198
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   199
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   200
        public static ProfilingLinkerCallSite newProfilingLinkerCallSite(final NashornCallSiteDescriptor desc) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   201
            if (profileCallSites == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
                profileCallSites = new LinkedList<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
                final Thread profileDumperThread = new Thread(new ProfileDumper());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
                Runtime.getRuntime().addShutdownHook(profileDumperThread);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   207
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   208
            final ProfilingLinkerCallSite callSite = new ProfilingLinkerCallSite(desc);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   209
            profileCallSites.add(callSite);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   210
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
            return callSite;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
        public void setTarget(final MethodHandle newTarget) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
            final MethodType type   = type();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   217
            final boolean    isVoid = type.returnType() == void.class;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
            MethodHandle methodHandle = MH.filterArguments(newTarget, 0, MH.bindTo(PROFILEENTRY, this));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
            if (isVoid) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
                methodHandle = MH.filterReturnValue(methodHandle, MH.bindTo(PROFILEVOIDEXIT, this));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
            } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
                final MethodType filter = MH.type(type.returnType(), type.returnType());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
                methodHandle = MH.filterReturnValue(methodHandle, MH.asType(MH.bindTo(PROFILEEXIT, this), filter));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   226
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
            super.setTarget(methodHandle);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   231
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   232
         * Start the clock for a profile entry and increase depth
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
         * @param self argument to filter
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   234
         * @return preserved argument
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   236
        @SuppressWarnings("unused")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
        public Object profileEntry(final Object self) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
            if (depth == 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   239
                startTime = System.nanoTime();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   240
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   241
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
            depth++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   243
            hitCount++;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   244
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   245
            return self;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   246
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   248
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   249
         * Decrease depth and stop the clock for a profile entry
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   250
         * @param result return value to filter
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   251
         * @return preserved argument
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   252
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   253
        @SuppressWarnings("unused")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   254
        public Object profileExit(final Object result) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   255
            depth--;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   256
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   257
            if (depth == 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   258
                totalTime += System.nanoTime() - startTime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   259
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   260
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   261
            return result;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   262
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   263
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   264
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   265
         * Decrease depth without return value filter
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
        @SuppressWarnings("unused")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   268
        public void profileVoidExit() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   269
            depth--;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   270
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   271
            if (depth == 0) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   272
                totalTime += System.nanoTime() - startTime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   273
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   274
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   275
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   276
        static class ProfileDumper implements Runnable {
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   277
            @SuppressWarnings("resource")
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   278
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   279
            public void run() {
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   280
                PrintWriter out = null;
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   281
                boolean fileOutput = false;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   283
                try {
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   284
                    try {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   285
                        out = new PrintWriter(new FileOutputStream(PROFILEFILE));
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   286
                        fileOutput = true;
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   287
                    } catch (final FileNotFoundException e) {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   288
                        out = Context.getCurrentErr();
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   289
                    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   290
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   291
                    dump(out);
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   292
                } finally {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   293
                    if (out != null && fileOutput) {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   294
                        out.close();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   295
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   296
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   297
            }
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   298
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   299
            private static void dump(final PrintWriter out) {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   300
                int index = 0;
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   301
                for (final ProfilingLinkerCallSite callSite : profileCallSites) {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   302
                   out.println("" + (index++) + '\t' +
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   303
                                  callSite.getDescriptor().getName() + '\t' +
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   304
                                  callSite.totalTime + '\t' +
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   305
                                  callSite.hitCount);
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   306
                }
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   307
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   311
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   312
     * Debug subclass for LinkerCallSite that allows tracing
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   313
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   314
    private static class TracingLinkerCallSite extends LinkerCallSite {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   315
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   316
        private static final MethodHandle TRACEOBJECT = findOwnMH("traceObject", Object.class, MethodHandle.class, Object[].class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   317
        private static final MethodHandle TRACEVOID   = findOwnMH("traceVoid", void.class, MethodHandle.class, Object[].class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   318
        private static final MethodHandle TRACEMISS   = findOwnMH("traceMiss", void.class, Object[].class);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   319
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   320
        TracingLinkerCallSite(final NashornCallSiteDescriptor desc) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   321
           super(desc);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   322
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   323
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   324
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   325
        public void setTarget(final MethodHandle newTarget) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   326
            if (!getNashornDescriptor().isTraceEnterExit()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   327
                super.setTarget(newTarget);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   328
                return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   329
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   330
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   331
            final MethodType type = type();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
            final boolean isVoid = type.returnType() == void.class;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   334
            MethodHandle traceMethodHandle = isVoid ? TRACEVOID : TRACEOBJECT;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   335
            traceMethodHandle = MH.bindTo(traceMethodHandle, this);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   336
            traceMethodHandle = MH.bindTo(traceMethodHandle, newTarget);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   337
            traceMethodHandle = MH.asCollector(traceMethodHandle, Object[].class, type.parameterCount());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   338
            traceMethodHandle = MH.asType(traceMethodHandle, type);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   339
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   340
            super.setTarget(traceMethodHandle);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   341
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   342
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   343
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   344
        public void initialize(final MethodHandle relinkAndInvoke) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   345
            super.initialize(getFallbackLoggingRelink(relinkAndInvoke));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   346
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   347
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   348
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   349
        public void relink(final GuardedInvocation invocation, final MethodHandle relink) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   350
            super.relink(invocation, getFallbackLoggingRelink(relink));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   351
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   352
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   353
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   354
        public void resetAndRelink(final GuardedInvocation invocation, final MethodHandle relink) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   355
            super.resetAndRelink(invocation, getFallbackLoggingRelink(relink));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   356
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   357
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   358
        private MethodHandle getFallbackLoggingRelink(final MethodHandle relink) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   359
            if (!getNashornDescriptor().isTraceMisses()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   360
                // If we aren't tracing misses, just return relink as-is
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   361
                return relink;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   362
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   363
            final MethodType type = relink.type();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   364
            return MH.foldArguments(relink, MH.asType(MH.asCollector(MH.bindTo(TRACEMISS, this), Object[].class, type.parameterCount()), type.changeReturnType(void.class)));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   365
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   366
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   367
        private void printObject(final PrintWriter out, final Object arg) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   368
            if (!getNashornDescriptor().isTraceObjects()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   369
                out.print((arg instanceof ScriptObject) ? "ScriptObject" : arg);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   370
                return;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   371
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   372
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   373
            if (arg instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   374
                final ScriptObject object = (ScriptObject)arg;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   375
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   376
                boolean isFirst = true;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   377
                final Set<Object> keySet = object.keySet();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   378
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   379
                if (keySet.isEmpty()) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   380
                    out.print(ScriptRuntime.safeToString(arg));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   381
                } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   382
                    out.print("{ ");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   383
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   384
                    for (final Object key : keySet) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   385
                        if (!isFirst) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   386
                            out.print(", ");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   387
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
                        out.print(key);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   390
                        out.print(":");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   391
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   392
                        final Object value = object.get(key);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   393
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   394
                        if (value instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   395
                            out.print("...");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   396
                        } else {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   397
                            printObject(out, value);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
                        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   399
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
                        isFirst = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
                    out.print(" }");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   404
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   405
             } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   406
                out.print(ScriptRuntime.safeToString(arg));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   407
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   408
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   410
        private void tracePrint(final PrintWriter out, final String tag, final Object[] args, final Object result) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   411
            //boolean isVoid = type().returnType() == void.class;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   412
            out.print(Debug.id(this) + " TAG " + tag);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   413
            out.print(getDescriptor().getName() + "(");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   414
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
            if (args.length > 0) {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   416
                printObject(out, args[0]);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   417
                for (int i = 1; i < args.length; i++) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   418
                    final Object arg = args[i];
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
                    out.print(", ");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   420
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   421
                    if (getNashornDescriptor().isTraceScope() || !(arg instanceof ScriptObject && ((ScriptObject)arg).isScope())) {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   422
                        printObject(out, arg);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   423
                    } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
                        out.print("SCOPE");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
            out.print(")");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
            if (tag.equals("EXIT  ")) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
                out.print(" --> ");
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   433
                printObject(out, result);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   434
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   435
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
            out.println();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   437
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   438
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   439
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   440
         * Trace event. Wrap an invocation with a return value
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   441
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   442
         * @param mh     invocation handle
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   443
         * @param args   arguments to call
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   444
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   445
         * @return return value from invocation
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   446
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   447
         * @throws Throwable if invocation fails or throws exception/error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
         */
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16185
diff changeset
   449
        @SuppressWarnings({"unused", "resource"})
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
        public Object traceObject(final MethodHandle mh, final Object... args) throws Throwable {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   451
            final PrintWriter out = Context.getCurrentErr();
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   452
            tracePrint(out, "ENTER ", args, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
            final Object result = mh.invokeWithArguments(args);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   454
            tracePrint(out, "EXIT  ", args, result);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
            return result;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   460
         * Trace event. Wrap an invocation that returns void
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
         * @param mh     invocation handle
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   463
         * @param args   arguments to call
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   464
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   465
         * @throws Throwable if invocation fails or throws exception/error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   466
         */
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16185
diff changeset
   467
        @SuppressWarnings({"unused", "resource"})
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   468
        public void traceVoid(final MethodHandle mh, final Object... args) throws Throwable {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   469
            final PrintWriter out = Context.getCurrentErr();
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   470
            tracePrint(out, "ENTER ", args, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
            mh.invokeWithArguments(args);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   472
            tracePrint(out, "EXIT  ", args, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   473
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
        /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
         * Tracer function that logs a callsite miss
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
         * @param args arguments to function
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
         *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
         * @throws Throwable if invocation failes or throws exception/error
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
         */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   482
        @SuppressWarnings("unused")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   483
        public void traceMiss(final Object... args) throws Throwable {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   484
            tracePrint(Context.getCurrentErr(), "MISS ", args, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   486
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
        private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   488
            try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   489
                return MH.findStatic(MethodHandles.lookup(), TracingLinkerCallSite.class, name, MH.type(rtype, types));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
            } catch (final MethodHandleFactory.LookupException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
                return MH.findVirtual(MethodHandles.lookup(), TracingLinkerCallSite.class, name, MH.type(rtype, types));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   494
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   495
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   496
    // counters updated in debug mode
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   497
    private static int count;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   498
    private static final HashMap<String, AtomicInteger> missCounts = new HashMap<>();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   499
    private static int missCount;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   500
    private static final Random r = new Random();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   501
    private static final int missSamplingPercentage = Options.getIntProperty("nashorn.tcs.miss.samplePercent", 1);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   502
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   503
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   504
     * Get the callsite count
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   505
     * @return the count
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   506
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   507
    public static int getCount() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   508
        return count;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   509
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   510
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
     * Get the callsite miss count
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
     * @return the missCount
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
    public static int getMissCount() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
        return missCount;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   518
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   519
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   520
     * Get given miss sampling percentage for sampler. Default is 1%. Specified with -Dnashorn.tcs.miss.samplePercent=x
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
     * @return miss sampling percentage
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
    public static int getMissSamplingPercentage() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
        return missSamplingPercentage;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   528
     * Dump the miss counts collected so far to a given output stream
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
     * @param out print stream
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
     */
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   531
    public static void getMissCounts(final PrintWriter out) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   532
        final ArrayList<Entry<String, AtomicInteger>> entries = new ArrayList<>(missCounts.entrySet());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
        Collections.sort(entries, new Comparator<Map.Entry<String, AtomicInteger>>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   535
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   536
            public int compare(final Entry<String, AtomicInteger> o1, final Entry<String, AtomicInteger> o2) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
                return o2.getValue().get() - o1.getValue().get();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
        });
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   540
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   541
        for (final Entry<String, AtomicInteger> entry : entries) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
            out.println("  " + entry.getKey() + "\t" + entry.getValue().get());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   544
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
}