author | joehw |
Sun, 13 Aug 2017 21:10:40 -0700 | |
changeset 46174 | 5611d2529b49 |
parent 44797 | 8b3b3b911b8a |
permissions | -rw-r--r-- |
6 | 1 |
/* |
46174 | 2 |
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. |
6 | 3 |
*/ |
44797
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
4 |
/* |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
5 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
6 |
* contributor license agreements. See the NOTICE file distributed with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
7 |
* this work for additional information regarding copyright ownership. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
8 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
9 |
* (the "License"); you may not use this file except in compliance with |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
10 |
* the License. You may obtain a copy of the License at |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
11 |
* |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
12 |
* http://www.apache.org/licenses/LICENSE-2.0 |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
13 |
* |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
14 |
* Unless required by applicable law or agreed to in writing, software |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
15 |
* distributed under the License is distributed on an "AS IS" BASIS, |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
16 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
17 |
* See the License for the specific language governing permissions and |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
18 |
* limitations under the License. |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
19 |
*/ |
8b3b3b911b8a
8162572: Update License Header for all JAXP sources
joehw
parents:
25868
diff
changeset
|
20 |
|
6 | 21 |
package com.sun.org.apache.bcel.internal.classfile; |
22 |
||
46174 | 23 |
import com.sun.org.apache.bcel.internal.Const; |
24 |
import java.io.DataInput; |
|
25 |
import java.io.DataOutputStream; |
|
26 |
import java.io.IOException; |
|
27 |
import java.util.HashMap; |
|
28 |
import java.util.LinkedHashMap; |
|
29 |
import java.util.Map; |
|
6 | 30 |
|
31 |
/** |
|
46174 | 32 |
* This class is derived from the abstract {@link Constant} |
6 | 33 |
* and represents a reference to a Utf8 encoded string. |
34 |
* |
|
46174 | 35 |
* @version $Id: ConstantUtf8.java 1750029 2016-06-23 22:14:38Z sebb $ |
6 | 36 |
* @see Constant |
37 |
*/ |
|
38 |
public final class ConstantUtf8 extends Constant { |
|
46174 | 39 |
|
40 |
private final String bytes; |
|
41 |
||
42 |
// TODO these should perhaps be AtomicInt? |
|
43 |
private static volatile int considered = 0; |
|
44 |
private static volatile int hits = 0; |
|
45 |
private static volatile int skipped = 0; |
|
46 |
private static volatile int created = 0; |
|
47 |
||
48 |
// Set the size to 0 or below to skip caching entirely |
|
49 |
private static final int MAX_CACHED_SIZE = 200; |
|
50 |
private static final boolean BCEL_STATISTICS = false; |
|
51 |
||
52 |
||
53 |
private static class CACHE_HOLDER { |
|
6 | 54 |
|
46174 | 55 |
private static final int MAX_CACHE_ENTRIES = 20000; |
56 |
private static final int INITIAL_CACHE_CAPACITY = (int)(MAX_CACHE_ENTRIES/0.75); |
|
57 |
||
58 |
private static final HashMap<String, ConstantUtf8> CACHE = |
|
59 |
new LinkedHashMap<String, ConstantUtf8>(INITIAL_CACHE_CAPACITY, 0.75f, true) { |
|
60 |
private static final long serialVersionUID = -8506975356158971766L; |
|
61 |
||
62 |
@Override |
|
63 |
protected boolean removeEldestEntry(final Map.Entry<String, ConstantUtf8> eldest) { |
|
64 |
return size() > MAX_CACHE_ENTRIES; |
|
65 |
} |
|
66 |
}; |
|
67 |
||
68 |
} |
|
69 |
||
70 |
// for accesss by test code |
|
71 |
static void printStats() { |
|
72 |
System.err.println("Cache hit " + hits + "/" + considered +", " + skipped + " skipped"); |
|
73 |
System.err.println("Total of " + created + " ConstantUtf8 objects created"); |
|
74 |
} |
|
6 | 75 |
|
46174 | 76 |
// for accesss by test code |
77 |
static void clearStats() { |
|
78 |
hits = considered = skipped = created = 0; |
|
79 |
} |
|
6 | 80 |
|
46174 | 81 |
static { |
82 |
if (BCEL_STATISTICS) { |
|
83 |
Runtime.getRuntime().addShutdownHook(new Thread() { |
|
84 |
@Override |
|
85 |
public void run() { |
|
86 |
printStats(); |
|
87 |
} |
|
88 |
}); |
|
89 |
} |
|
90 |
} |
|
6 | 91 |
|
46174 | 92 |
/** |
93 |
* @since 6.0 |
|
94 |
*/ |
|
95 |
public static ConstantUtf8 getCachedInstance(final String s) { |
|
96 |
if (s.length() > MAX_CACHED_SIZE) { |
|
97 |
skipped++; |
|
98 |
return new ConstantUtf8(s); |
|
99 |
} |
|
100 |
considered++; |
|
101 |
synchronized (ConstantUtf8.class) { // might be better with a specific lock object |
|
102 |
ConstantUtf8 result = CACHE_HOLDER.CACHE.get(s); |
|
103 |
if (result != null) { |
|
104 |
hits++; |
|
105 |
return result; |
|
106 |
} |
|
107 |
result = new ConstantUtf8(s); |
|
108 |
CACHE_HOLDER.CACHE.put(s, result); |
|
109 |
return result; |
|
110 |
} |
|
111 |
} |
|
6 | 112 |
|
46174 | 113 |
/** |
114 |
* @since 6.0 |
|
115 |
*/ |
|
116 |
public static ConstantUtf8 getInstance(final String s) { |
|
117 |
return new ConstantUtf8(s); |
|
118 |
} |
|
6 | 119 |
|
46174 | 120 |
/** |
121 |
* @since 6.0 |
|
122 |
*/ |
|
123 |
public static ConstantUtf8 getInstance (final DataInput input) throws IOException { |
|
124 |
return getInstance(input.readUTF()); |
|
125 |
} |
|
126 |
||
127 |
/** |
|
128 |
* Initialize from another object. |
|
129 |
*/ |
|
130 |
public ConstantUtf8(final ConstantUtf8 c) { |
|
131 |
this(c.getBytes()); |
|
132 |
} |
|
133 |
||
134 |
||
135 |
/** |
|
136 |
* Initialize instance from file data. |
|
137 |
* |
|
138 |
* @param file Input stream |
|
139 |
* @throws IOException |
|
140 |
*/ |
|
141 |
ConstantUtf8(final DataInput file) throws IOException { |
|
142 |
super(Const.CONSTANT_Utf8); |
|
143 |
bytes = file.readUTF(); |
|
144 |
created++; |
|
145 |
} |
|
146 |
||
147 |
||
148 |
/** |
|
149 |
* @param bytes Data |
|
150 |
*/ |
|
151 |
public ConstantUtf8(final String bytes) { |
|
152 |
super(Const.CONSTANT_Utf8); |
|
153 |
if (bytes == null) { |
|
154 |
throw new IllegalArgumentException("bytes must not be null!"); |
|
155 |
} |
|
156 |
this.bytes = bytes; |
|
157 |
created++; |
|
158 |
} |
|
159 |
||
6 | 160 |
|
46174 | 161 |
/** |
162 |
* Called by objects that are traversing the nodes of the tree implicitely |
|
163 |
* defined by the contents of a Java class. I.e., the hierarchy of methods, |
|
164 |
* fields, attributes, etc. spawns a tree of objects. |
|
165 |
* |
|
166 |
* @param v Visitor object |
|
167 |
*/ |
|
168 |
@Override |
|
169 |
public void accept( final Visitor v ) { |
|
170 |
v.visitConstantUtf8(this); |
|
171 |
} |
|
172 |
||
173 |
||
174 |
/** |
|
175 |
* Dump String in Utf8 format to file stream. |
|
176 |
* |
|
177 |
* @param file Output file stream |
|
178 |
* @throws IOException |
|
179 |
*/ |
|
180 |
@Override |
|
181 |
public final void dump( final DataOutputStream file ) throws IOException { |
|
182 |
file.writeByte(super.getTag()); |
|
183 |
file.writeUTF(bytes); |
|
184 |
} |
|
185 |
||
6 | 186 |
|
46174 | 187 |
/** |
188 |
* @return Data converted to string. |
|
189 |
*/ |
|
190 |
public final String getBytes() { |
|
191 |
return bytes; |
|
192 |
} |
|
193 |
||
6 | 194 |
|
46174 | 195 |
/** |
196 |
* @param bytes the raw bytes of this Utf-8 |
|
197 |
* @deprecated (since 6.0) |
|
198 |
*/ |
|
199 |
@java.lang.Deprecated |
|
200 |
public final void setBytes( final String bytes ) { |
|
201 |
throw new UnsupportedOperationException(); |
|
202 |
} |
|
6 | 203 |
|
46174 | 204 |
|
205 |
/** |
|
206 |
* @return String representation |
|
207 |
*/ |
|
208 |
@Override |
|
209 |
public final String toString() { |
|
210 |
return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")"; |
|
211 |
} |
|
6 | 212 |
} |