SystemPropertiesRuntime.java revision d05ad7d4bc65e91b6c6efb45687f7a850d07f02a
1/*******************************************************************************
2 * Copyright (c) 2009, 2011 Mountainminds GmbH & Co. KG and Contributors
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12package org.jacoco.core.runtime;
13
14import java.util.Map;
15
16import org.objectweb.asm.MethodVisitor;
17import org.objectweb.asm.Opcodes;
18
19/**
20 * This {@link IRuntime} implementation makes the execution data available
21 * through a special entry of the type {@link Map} in the
22 * {@link System#getProperties()} hash table. The advantage is, that the
23 * instrumented classes do not get dependencies to other classes than the JRE
24 * library itself.
25 *
26 * This runtime may cause problems in environments with security restrictions,
27 * in applications that replace the system properties or in applications that
28 * fail if non-String values are placed in the system properties.
29 *
30 * @author Marc R. Hoffmann
31 * @version $qualified.bundle.version$
32 */
33public class SystemPropertiesRuntime extends AbstractRuntime {
34
35	private static final String KEYPREFIX = "jacoco-";
36
37	private final String key;
38
39	/**
40	 * Creates a new runtime.
41	 */
42	public SystemPropertiesRuntime() {
43		this.key = KEYPREFIX + Integer.toHexString(hashCode());
44	}
45
46	public int generateDataAccessor(final long classid, final String classname,
47			final int probecount, final MethodVisitor mv) {
48		mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System",
49				"getProperties", "()Ljava/util/Properties;");
50
51		// Stack[0]: Ljava/util/Properties;
52
53		mv.visitLdcInsn(key);
54
55		// Stack[1]: Ljava/lang/String;
56		// Stack[0]: Ljava/util/Properties;
57
58		mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Properties",
59				"get", "(Ljava/lang/Object;)Ljava/lang/Object;");
60
61		// Stack[0]: Ljava/lang/Object;
62
63		ExecutionDataAccess.generateAccessCall(classid, classname, probecount,
64				mv);
65
66		// Stack[0]: [Z
67
68		return 6; // Maximum local stack size is 3
69	}
70
71	public void startup() {
72		setStartTimeStamp();
73		System.getProperties().put(key, access);
74	}
75
76	public void shutdown() {
77		System.getProperties().remove(key);
78	}
79
80}
81