comparison graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/logging/CountingProxy.java @ 21551:5324104ac4f3

moved com.oracle.graal.hotspot.jvmci classes to com.oracle.jvmci.hotspot module (JBS:GRAAL-53)
author Doug Simon <doug.simon@oracle.com>
date Tue, 26 May 2015 17:13:37 +0200
parents
children
comparison
equal deleted inserted replaced
21550:f48a6cea31eb 21551:5324104ac4f3
1 /*
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.jvmci.hotspot.logging;
24
25 import java.lang.reflect.*;
26 import java.util.*;
27 import java.util.concurrent.*;
28 import java.util.concurrent.atomic.*;
29
30 import com.oracle.graal.debug.*;
31
32 /**
33 * A java.lang.reflect proxy that hierarchically logs all method invocations along with their
34 * parameters and return values.
35 */
36 public class CountingProxy<T> implements InvocationHandler {
37
38 public static final boolean ENABLED = Boolean.valueOf(System.getProperty("graal.countcalls"));
39
40 private T delegate;
41
42 private ConcurrentHashMap<Method, AtomicLong> calls = new ConcurrentHashMap<>();
43
44 public CountingProxy(T delegate) {
45 assert ENABLED;
46 TTY.println("Counting proxy for " + delegate.getClass().getSimpleName() + " created");
47 this.delegate = delegate;
48 proxies.add(this);
49 }
50
51 @Override
52 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
53 int argCount = args == null ? 0 : args.length;
54 if (method.getParameterTypes().length != argCount) {
55 throw new RuntimeException("wrong parameter count");
56 }
57 final Object result;
58 if (!calls.containsKey(method)) {
59 calls.putIfAbsent(method, new AtomicLong(0));
60 }
61 AtomicLong count = calls.get(method);
62 count.incrementAndGet();
63 try {
64 if (args == null) {
65 result = method.invoke(delegate);
66 } else {
67 result = method.invoke(delegate, args);
68 }
69 } catch (InvocationTargetException e) {
70 throw e.getCause();
71 }
72 return result;
73 }
74
75 public static <T> T getProxy(Class<T> interf, T delegate) {
76 Class<?>[] interfaces = ProxyUtil.getAllInterfaces(delegate.getClass());
77 Object obj = Proxy.newProxyInstance(interf.getClassLoader(), interfaces, new CountingProxy<>(delegate));
78 return interf.cast(obj);
79 }
80
81 private static ArrayList<CountingProxy<?>> proxies = new ArrayList<>();
82
83 static {
84 if (ENABLED) {
85 Runtime.getRuntime().addShutdownHook(new Thread() {
86
87 @Override
88 public void run() {
89 for (CountingProxy<?> proxy : proxies) {
90 proxy.print();
91 }
92 }
93 });
94 }
95 }
96
97 protected void print() {
98 long sum = 0;
99 for (Map.Entry<Method, AtomicLong> entry : calls.entrySet()) {
100 Method method = entry.getKey();
101 long count = entry.getValue().get();
102 sum += count;
103 TTY.println(delegate.getClass().getSimpleName() + "." + method.getName() + ": " + count);
104 }
105 TTY.println(delegate.getClass().getSimpleName() + " calls: " + sum);
106 }
107 }