Mercurial > hg > graal-compiler
comparison src/share/vm/classfile/javaAssertions.cpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | 4ce7240d622c |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a61af66fc99e |
---|---|
1 /* | |
2 * Copyright 2000-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_javaAssertions.cpp.incl" | |
27 | |
28 bool JavaAssertions::_userDefault = false; | |
29 bool JavaAssertions::_sysDefault = false; | |
30 JavaAssertions::OptionList* JavaAssertions::_classes = 0; | |
31 JavaAssertions::OptionList* JavaAssertions::_packages = 0; | |
32 | |
33 JavaAssertions::OptionList::OptionList(const char* name, bool enabled, | |
34 OptionList* next) { | |
35 assert(name != 0, "need a name"); | |
36 _name = name; | |
37 _enabled = enabled; | |
38 _next = next; | |
39 } | |
40 | |
41 int JavaAssertions::OptionList::count(OptionList* p) { | |
42 int rc; | |
43 for (rc = 0; p != 0; p = p->next(), ++rc) /* empty */; | |
44 return rc; | |
45 } | |
46 | |
47 void JavaAssertions::addOption(const char* name, bool enable) { | |
48 assert(name != 0, "must have a name"); | |
49 | |
50 // Copy the name. The storage needs to exist for the the lifetime of the vm; | |
51 // it is never freed, so will be leaked (along with other option strings - | |
52 // e.g., bootclasspath) if a process creates/destroys multiple VMs. | |
53 int len = (int)strlen(name); | |
54 char *name_copy = NEW_C_HEAP_ARRAY(char, len + 1); | |
55 strcpy(name_copy, name); | |
56 | |
57 // Figure out which list the new item should go on. Names that end in "..." | |
58 // go on the package tree list. | |
59 OptionList** head = &_classes; | |
60 if (len >= 3 && strcmp(name_copy + len - 3, "...") == 0) { | |
61 // Delete the "...". | |
62 len -= 3; | |
63 name_copy[len] = '\0'; | |
64 head = &_packages; | |
65 } | |
66 | |
67 // Convert class/package names to internal format. Will have to convert back | |
68 // when copying to java in createJavaAssertionStatusDirectives, but that | |
69 // should happen only once. Alternative would require that | |
70 // JVM_DesiredAssertionStatus pass the external_name() to | |
71 // JavaAssertion::enabled(), but that is done once per loaded class. | |
72 for (int i = 0; i < len; ++i) { | |
73 if (name_copy[i] == '.') name_copy[i] = '/'; | |
74 } | |
75 | |
76 if (TraceJavaAssertions) { | |
77 tty->print_cr("JavaAssertions: adding %s %s=%d", | |
78 head == &_classes ? "class" : "package", | |
79 name_copy[0] != '\0' ? name_copy : "'default'", | |
80 enable); | |
81 } | |
82 | |
83 // Prepend a new item to the list. Items added later take precedence, so | |
84 // prepending allows us to stop searching the list after the first match. | |
85 *head = new OptionList(name_copy, enable, *head); | |
86 } | |
87 | |
88 oop JavaAssertions::createAssertionStatusDirectives(TRAPS) { | |
89 symbolHandle asd_sym = vmSymbolHandles::java_lang_AssertionStatusDirectives(); | |
90 klassOop k = SystemDictionary::resolve_or_fail(asd_sym, true, CHECK_NULL); | |
91 instanceKlassHandle asd_klass (THREAD, k); | |
92 asd_klass->initialize(CHECK_NULL); | |
93 Handle h = asd_klass->allocate_instance_handle(CHECK_NULL); | |
94 | |
95 int len; | |
96 typeArrayOop t; | |
97 len = OptionList::count(_packages); | |
98 objArrayOop pn = oopFactory::new_objArray(SystemDictionary::string_klass(), len, CHECK_NULL); | |
99 objArrayHandle pkgNames (THREAD, pn); | |
100 t = oopFactory::new_typeArray(T_BOOLEAN, len, CHECK_NULL); | |
101 typeArrayHandle pkgEnabled(THREAD, t); | |
102 fillJavaArrays(_packages, len, pkgNames, pkgEnabled, CHECK_NULL); | |
103 | |
104 len = OptionList::count(_classes); | |
105 objArrayOop cn = oopFactory::new_objArray(SystemDictionary::string_klass(), len, CHECK_NULL); | |
106 objArrayHandle classNames (THREAD, cn); | |
107 t = oopFactory::new_typeArray(T_BOOLEAN, len, CHECK_NULL); | |
108 typeArrayHandle classEnabled(THREAD, t); | |
109 fillJavaArrays(_classes, len, classNames, classEnabled, CHECK_NULL); | |
110 | |
111 java_lang_AssertionStatusDirectives::set_packages(h(), pkgNames()); | |
112 java_lang_AssertionStatusDirectives::set_packageEnabled(h(), pkgEnabled()); | |
113 java_lang_AssertionStatusDirectives::set_classes(h(), classNames()); | |
114 java_lang_AssertionStatusDirectives::set_classEnabled(h(), classEnabled()); | |
115 java_lang_AssertionStatusDirectives::set_deflt(h(), userClassDefault()); | |
116 return h(); | |
117 } | |
118 | |
119 void JavaAssertions::fillJavaArrays(const OptionList* p, int len, | |
120 objArrayHandle names, typeArrayHandle enabled, TRAPS) { | |
121 // Fill in the parallel names and enabled (boolean) arrays. Start at the end | |
122 // of the array and work backwards, so the order of items in the arrays | |
123 // matches the order on the command line (the list is in reverse order, since | |
124 // it was created by prepending successive items from the command line). | |
125 int index; | |
126 for (index = len - 1; p != 0; p = p->next(), --index) { | |
127 assert(index >= 0, "length does not match list"); | |
128 Handle s = java_lang_String::create_from_str(p->name(), CHECK); | |
129 s = java_lang_String::char_converter(s, '/', '.', CHECK); | |
130 names->obj_at_put(index, s()); | |
131 enabled->bool_at_put(index, p->enabled()); | |
132 } | |
133 assert(index == -1, "length does not match list"); | |
134 } | |
135 | |
136 inline JavaAssertions::OptionList* | |
137 JavaAssertions::match_class(const char* classname) { | |
138 for (OptionList* p = _classes; p != 0; p = p->next()) { | |
139 if (strcmp(p->name(), classname) == 0) { | |
140 return p; | |
141 } | |
142 } | |
143 return 0; | |
144 } | |
145 | |
146 JavaAssertions::OptionList* | |
147 JavaAssertions::match_package(const char* classname) { | |
148 // Search the package list for any items that apply to classname. Each | |
149 // sub-package in classname is checked, from most-specific to least, until one | |
150 // is found. | |
151 if (_packages == 0) return 0; | |
152 | |
153 // Find the length of the "most-specific" package in classname. If classname | |
154 // does not include a package, length will be 0 which will match items for the | |
155 // default package (from options "-ea:..." or "-da:..."). | |
156 size_t len = strlen(classname); | |
157 for (/* empty */; len > 0 && classname[len] != '/'; --len) /* empty */; | |
158 | |
159 do { | |
160 assert(len == 0 || classname[len] == '/', "not a package name"); | |
161 for (OptionList* p = _packages; p != 0; p = p->next()) { | |
162 if (strncmp(p->name(), classname, len) == 0 && p->name()[len] == '\0') { | |
163 return p; | |
164 } | |
165 } | |
166 | |
167 // Find the length of the next package, taking care to avoid decrementing | |
168 // past 0 (len is unsigned). | |
169 while (len > 0 && classname[--len] != '/') /* empty */; | |
170 } while (len > 0); | |
171 | |
172 return 0; | |
173 } | |
174 | |
175 inline void JavaAssertions::trace(const char* name, | |
176 const char* typefound, const char* namefound, bool enabled) { | |
177 if (TraceJavaAssertions) { | |
178 tty->print_cr("JavaAssertions: search for %s found %s %s=%d", | |
179 name, typefound, namefound[0] != '\0' ? namefound : "'default'", enabled); | |
180 } | |
181 } | |
182 | |
183 bool JavaAssertions::enabled(const char* classname, bool systemClass) { | |
184 assert(classname != 0, "must have a classname"); | |
185 | |
186 // This will be slow if the number of assertion options on the command line is | |
187 // large--it traverses two lists, one of them multiple times. Could use a | |
188 // single n-ary tree instead of lists if someone ever notices. | |
189 | |
190 // First check options that apply to classes. If we find a match we're done. | |
191 OptionList* p; | |
192 if (p = match_class(classname)) { | |
193 trace(classname, "class", p->name(), p->enabled()); | |
194 return p->enabled(); | |
195 } | |
196 | |
197 // Now check packages, from most specific to least. | |
198 if (p = match_package(classname)) { | |
199 trace(classname, "package", p->name(), p->enabled()); | |
200 return p->enabled(); | |
201 } | |
202 | |
203 // No match. Return the default status. | |
204 bool result = systemClass ? systemClassDefault() : userClassDefault(); | |
205 trace(classname, systemClass ? "system" : "user", "default", result); | |
206 return result; | |
207 } |