annotate src/share/tools/MakeDeps/DirectoryTree.java @ 1716:be3f9c242c9d

6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
author ysr
date Mon, 16 Aug 2010 15:58:42 -0700
parents c18cbe5936b8
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 /** Encapsulates a notion of a directory tree. Designed to allow fast
a61af66fc99e Initial load
duke
parents:
diff changeset
26 querying of full paths for unique filenames in the hierarchy. */
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import java.io.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 import java.util.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 public class DirectoryTree {
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33 /** The root of the read directoryTree */
a61af66fc99e Initial load
duke
parents:
diff changeset
34 private Node rootNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 /** Subdirs to ignore; Vector of Strings */
a61af66fc99e Initial load
duke
parents:
diff changeset
37 private Vector subdirsToIgnore;
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 /** This maps file names to Lists of nodes. */
a61af66fc99e Initial load
duke
parents:
diff changeset
40 private Hashtable nameToNodeListTable;
a61af66fc99e Initial load
duke
parents:
diff changeset
41
a61af66fc99e Initial load
duke
parents:
diff changeset
42 /** Output "."'s as directories are read. Defaults to false. */
a61af66fc99e Initial load
duke
parents:
diff changeset
43 private boolean verbose;
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 public DirectoryTree() {
a61af66fc99e Initial load
duke
parents:
diff changeset
46 subdirsToIgnore = new Vector();
a61af66fc99e Initial load
duke
parents:
diff changeset
47 verbose = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 }
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 /** Takes an absolute path to the root directory of this
a61af66fc99e Initial load
duke
parents:
diff changeset
51 DirectoryTree. Throws IllegalArgumentException if the given
a61af66fc99e Initial load
duke
parents:
diff changeset
52 string represents a plain file or nonexistent directory. */
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 public DirectoryTree(String baseDirectory) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 this();
a61af66fc99e Initial load
duke
parents:
diff changeset
56 readDirectory(baseDirectory);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 public void addSubdirToIgnore(String subdir) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 subdirsToIgnore.add(subdir);
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 /** Output "."'s to System.out as directories are read. Defaults
a61af66fc99e Initial load
duke
parents:
diff changeset
64 to false. */
a61af66fc99e Initial load
duke
parents:
diff changeset
65 public void setVerbose(boolean newValue) {
a61af66fc99e Initial load
duke
parents:
diff changeset
66 verbose = newValue;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 public boolean getVerbose() {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 return verbose;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 public String getRootNodeName() {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 return rootNode.getName();
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 /** Takes an absolute path to the root directory of this
a61af66fc99e Initial load
duke
parents:
diff changeset
78 DirectoryTree. Throws IllegalArgumentException if the given
a61af66fc99e Initial load
duke
parents:
diff changeset
79 string represents a plain file or nonexistent directory. */
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 public void readDirectory(String baseDirectory)
a61af66fc99e Initial load
duke
parents:
diff changeset
82 throws IllegalArgumentException {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 File root = new File(baseDirectory);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (!root.isDirectory()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85 throw new IllegalArgumentException("baseDirectory \"" +
a61af66fc99e Initial load
duke
parents:
diff changeset
86 baseDirectory +
a61af66fc99e Initial load
duke
parents:
diff changeset
87 "\" does not exist or " +
a61af66fc99e Initial load
duke
parents:
diff changeset
88 "is not a directory");
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 root = root.getCanonicalFile();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93 catch (IOException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 throw new RuntimeException(e.toString());
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 rootNode = new Node(root);
a61af66fc99e Initial load
duke
parents:
diff changeset
97 readDirectory(rootNode, root);
a61af66fc99e Initial load
duke
parents:
diff changeset
98 }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 /** Queries the DirectoryTree for a file or directory name. Takes
a61af66fc99e Initial load
duke
parents:
diff changeset
101 only the name of the file or directory itself (i.e., no parent
a61af66fc99e Initial load
duke
parents:
diff changeset
102 directory information should be in the passed name). Returns a
a61af66fc99e Initial load
duke
parents:
diff changeset
103 List of DirectoryTreeNodes specifying the full paths of all of
a61af66fc99e Initial load
duke
parents:
diff changeset
104 the files or directories of this name in the DirectoryTree.
a61af66fc99e Initial load
duke
parents:
diff changeset
105 Returns null if the directory tree has not been read from disk
a61af66fc99e Initial load
duke
parents:
diff changeset
106 yet or if the file was not found in the tree. */
a61af66fc99e Initial load
duke
parents:
diff changeset
107 public List findFile(String name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 if (rootNode == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 if (nameToNodeListTable == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 nameToNodeListTable = new Hashtable();
a61af66fc99e Initial load
duke
parents:
diff changeset
114 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 buildNameToNodeListTable(rootNode);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 } catch (IOException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 e.printStackTrace();
a61af66fc99e Initial load
duke
parents:
diff changeset
118 return null;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 return (List) nameToNodeListTable.get(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 private void buildNameToNodeListTable(Node curNode)
a61af66fc99e Initial load
duke
parents:
diff changeset
126 throws IOException {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 String fullName = curNode.getName();
a61af66fc99e Initial load
duke
parents:
diff changeset
128 String parent = curNode.getParent();
a61af66fc99e Initial load
duke
parents:
diff changeset
129 String separator = System.getProperty("file.separator");
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 if (parent != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if (!fullName.startsWith(parent)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 throw new RuntimeException(
a61af66fc99e Initial load
duke
parents:
diff changeset
134 "Internal error: parent of file name \"" + fullName +
a61af66fc99e Initial load
duke
parents:
diff changeset
135 "\" does not match file name \"" + parent + "\""
a61af66fc99e Initial load
duke
parents:
diff changeset
136 );
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 int len = parent.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
140 if (!parent.endsWith(separator)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 len += separator.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 String fileName = fullName.substring(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 if (fileName == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 throw new RuntimeException(
a61af66fc99e Initial load
duke
parents:
diff changeset
148 "Internal error: file name was empty"
a61af66fc99e Initial load
duke
parents:
diff changeset
149 );
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 List nodeList = (List) nameToNodeListTable.get(fileName);
a61af66fc99e Initial load
duke
parents:
diff changeset
153 if (nodeList == null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 nodeList = new Vector();
a61af66fc99e Initial load
duke
parents:
diff changeset
155 nameToNodeListTable.put(fileName, nodeList);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 nodeList.add(curNode);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if (curNode != rootNode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 throw new RuntimeException(
a61af66fc99e Initial load
duke
parents:
diff changeset
162 "Internal error: parent of file + \"" + fullName + "\"" +
a61af66fc99e Initial load
duke
parents:
diff changeset
163 " was null"
a61af66fc99e Initial load
duke
parents:
diff changeset
164 );
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 if (curNode.isDirectory()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 Iterator iter = curNode.getChildren();
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if (iter != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 while (iter.hasNext()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 buildNameToNodeListTable((Node) iter.next());
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 /** Reads all of the files in the given directory and adds them as
a61af66fc99e Initial load
duke
parents:
diff changeset
179 children of the directory tree node. Requires that the passed
a61af66fc99e Initial load
duke
parents:
diff changeset
180 node represents a directory. */
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 private void readDirectory(Node parentNode, File parentDir) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 File[] children = parentDir.listFiles();
a61af66fc99e Initial load
duke
parents:
diff changeset
184 if (children == null)
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 System.out.print(".");
a61af66fc99e Initial load
duke
parents:
diff changeset
188 System.out.flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 for (int i = 0; i < children.length; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 File child = children[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
192 children[i] = null;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 boolean isDir = child.isDirectory();
a61af66fc99e Initial load
duke
parents:
diff changeset
194 boolean mustSkip = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 if (isDir) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 for (Iterator iter = subdirsToIgnore.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
197 iter.hasNext(); ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 if (child.getName().equals((String) iter.next())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 mustSkip = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if (!mustSkip) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 Node childNode = new Node(child);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 parentNode.addChild(childNode);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if (isDir) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 readDirectory(childNode, child);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 private class Node implements DirectoryTreeNode {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 private File file;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 private Vector children;
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 /** file must be a canonical file */
a61af66fc99e Initial load
duke
parents:
diff changeset
219 Node(File file) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 this.file = file;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 children = new Vector();
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 public boolean isFile() {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 return file.isFile();
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 public boolean isDirectory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 return file.isDirectory();
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 public String getName() {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 return file.getPath();
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 public String getParent() {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 return file.getParent();
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 public void addChild(Node n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 children.add(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 public Iterator getChildren() throws IllegalArgumentException {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 return children.iterator();
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247
a61af66fc99e Initial load
duke
parents:
diff changeset
248 public int getNumChildren() throws IllegalArgumentException {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 return children.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 public DirectoryTreeNode getChild(int i)
a61af66fc99e Initial load
duke
parents:
diff changeset
253 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 return (DirectoryTreeNode) children.get(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }