Mercurial > hg > truffle
annotate src/share/vm/ci/ciEnv.cpp @ 3762:5c0a3c1858b1
7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359
Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675.
Reviewed-by: brutisso
author | ysr |
---|---|
date | Thu, 02 Jun 2011 10:23:36 -0700 |
parents | 08ccee2c4dbf |
children | 81d815b05abb |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2263
diff
changeset
|
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
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:
1507
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "ci/ciConstant.hpp" | |
27 #include "ci/ciEnv.hpp" | |
28 #include "ci/ciField.hpp" | |
29 #include "ci/ciInstance.hpp" | |
30 #include "ci/ciInstanceKlass.hpp" | |
31 #include "ci/ciInstanceKlassKlass.hpp" | |
32 #include "ci/ciMethod.hpp" | |
33 #include "ci/ciNullObject.hpp" | |
34 #include "ci/ciObjArrayKlassKlass.hpp" | |
35 #include "ci/ciTypeArrayKlassKlass.hpp" | |
36 #include "ci/ciUtilities.hpp" | |
37 #include "classfile/systemDictionary.hpp" | |
38 #include "classfile/vmSymbols.hpp" | |
39 #include "code/scopeDesc.hpp" | |
40 #include "compiler/compileBroker.hpp" | |
41 #include "compiler/compileLog.hpp" | |
42 #include "compiler/compilerOracle.hpp" | |
43 #include "gc_interface/collectedHeap.inline.hpp" | |
44 #include "interpreter/linkResolver.hpp" | |
45 #include "memory/allocation.inline.hpp" | |
46 #include "memory/oopFactory.hpp" | |
47 #include "memory/universe.inline.hpp" | |
48 #include "oops/methodDataOop.hpp" | |
49 #include "oops/objArrayKlass.hpp" | |
50 #include "oops/oop.inline.hpp" | |
51 #include "oops/oop.inline2.hpp" | |
52 #include "prims/jvmtiExport.hpp" | |
53 #include "runtime/init.hpp" | |
54 #include "runtime/reflection.hpp" | |
55 #include "runtime/sharedRuntime.hpp" | |
56 #include "utilities/dtrace.hpp" | |
57 #ifdef COMPILER1 | |
58 #include "c1/c1_Runtime1.hpp" | |
59 #endif | |
60 #ifdef COMPILER2 | |
61 #include "opto/runtime.hpp" | |
62 #endif | |
0 | 63 |
64 // ciEnv | |
65 // | |
66 // This class is the top level broker for requests from the compiler | |
67 // to the VM. | |
68 | |
69 ciObject* ciEnv::_null_object_instance; | |
70 ciMethodKlass* ciEnv::_method_klass_instance; | |
71 ciKlassKlass* ciEnv::_klass_klass_instance; | |
72 ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance; | |
73 ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance; | |
74 ciObjArrayKlassKlass* ciEnv::_obj_array_klass_klass_instance; | |
75 | |
1142 | 76 #define WK_KLASS_DEFN(name, ignore_s, ignore_o) ciInstanceKlass* ciEnv::_##name = NULL; |
77 WK_KLASSES_DO(WK_KLASS_DEFN) | |
78 #undef WK_KLASS_DEFN | |
0 | 79 |
80 ciSymbol* ciEnv::_unloaded_cisymbol = NULL; | |
81 ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL; | |
82 ciObjArrayKlass* ciEnv::_unloaded_ciobjarrayklass = NULL; | |
83 | |
84 jobject ciEnv::_ArrayIndexOutOfBoundsException_handle = NULL; | |
85 jobject ciEnv::_ArrayStoreException_handle = NULL; | |
86 jobject ciEnv::_ClassCastException_handle = NULL; | |
87 | |
88 #ifndef PRODUCT | |
89 static bool firstEnv = true; | |
90 #endif /* PRODUCT */ | |
91 | |
92 // ------------------------------------------------------------------ | |
93 // ciEnv::ciEnv | |
94 ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) { | |
95 VM_ENTRY_MARK; | |
96 | |
97 // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc. | |
98 thread->set_env(this); | |
99 assert(ciEnv::current() == this, "sanity"); | |
100 | |
101 _oop_recorder = NULL; | |
102 _debug_info = NULL; | |
103 _dependencies = NULL; | |
104 _failure_reason = NULL; | |
105 _compilable = MethodCompilable; | |
106 _break_at_compile = false; | |
107 _compiler_data = NULL; | |
108 #ifndef PRODUCT | |
109 assert(!firstEnv, "not initialized properly"); | |
110 #endif /* !PRODUCT */ | |
111 | |
112 _system_dictionary_modification_counter = system_dictionary_modification_counter; | |
113 _num_inlined_bytecodes = 0; | |
114 assert(task == NULL || thread->task() == task, "sanity"); | |
115 _task = task; | |
116 _log = NULL; | |
117 | |
118 // Temporary buffer for creating symbols and such. | |
119 _name_buffer = NULL; | |
120 _name_buffer_len = 0; | |
121 | |
122 _arena = &_ciEnv_arena; | |
123 _factory = new (_arena) ciObjectFactory(_arena, 128); | |
124 | |
125 // Preload commonly referenced system ciObjects. | |
126 | |
127 // During VM initialization, these instances have not yet been created. | |
128 // Assertions ensure that these instances are not accessed before | |
129 // their initialization. | |
130 | |
131 assert(Universe::is_fully_initialized(), "should be complete"); | |
132 | |
133 oop o = Universe::null_ptr_exception_instance(); | |
134 assert(o != NULL, "should have been initialized"); | |
135 _NullPointerException_instance = get_object(o)->as_instance(); | |
136 o = Universe::arithmetic_exception_instance(); | |
137 assert(o != NULL, "should have been initialized"); | |
138 _ArithmeticException_instance = get_object(o)->as_instance(); | |
139 | |
140 _ArrayIndexOutOfBoundsException_instance = NULL; | |
141 _ArrayStoreException_instance = NULL; | |
142 _ClassCastException_instance = NULL; | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
143 _the_null_string = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
144 _the_min_jint_string = NULL; |
0 | 145 } |
146 | |
147 ciEnv::ciEnv(Arena* arena) { | |
148 ASSERT_IN_VM; | |
149 | |
150 // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc. | |
151 CompilerThread* current_thread = CompilerThread::current(); | |
152 assert(current_thread->env() == NULL, "must be"); | |
153 current_thread->set_env(this); | |
154 assert(ciEnv::current() == this, "sanity"); | |
155 | |
156 _oop_recorder = NULL; | |
157 _debug_info = NULL; | |
158 _dependencies = NULL; | |
159 _failure_reason = NULL; | |
160 _compilable = MethodCompilable_never; | |
161 _break_at_compile = false; | |
162 _compiler_data = NULL; | |
163 #ifndef PRODUCT | |
164 assert(firstEnv, "must be first"); | |
165 firstEnv = false; | |
166 #endif /* !PRODUCT */ | |
167 | |
168 _system_dictionary_modification_counter = 0; | |
169 _num_inlined_bytecodes = 0; | |
170 _task = NULL; | |
171 _log = NULL; | |
172 | |
173 // Temporary buffer for creating symbols and such. | |
174 _name_buffer = NULL; | |
175 _name_buffer_len = 0; | |
176 | |
177 _arena = arena; | |
178 _factory = new (_arena) ciObjectFactory(_arena, 128); | |
179 | |
180 // Preload commonly referenced system ciObjects. | |
181 | |
182 // During VM initialization, these instances have not yet been created. | |
183 // Assertions ensure that these instances are not accessed before | |
184 // their initialization. | |
185 | |
186 assert(Universe::is_fully_initialized(), "must be"); | |
187 | |
188 oop o = Universe::null_ptr_exception_instance(); | |
189 assert(o != NULL, "should have been initialized"); | |
190 _NullPointerException_instance = get_object(o)->as_instance(); | |
191 o = Universe::arithmetic_exception_instance(); | |
192 assert(o != NULL, "should have been initialized"); | |
193 _ArithmeticException_instance = get_object(o)->as_instance(); | |
194 | |
195 _ArrayIndexOutOfBoundsException_instance = NULL; | |
196 _ArrayStoreException_instance = NULL; | |
197 _ClassCastException_instance = NULL; | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
198 _the_null_string = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
199 _the_min_jint_string = NULL; |
0 | 200 } |
201 | |
202 ciEnv::~ciEnv() { | |
203 CompilerThread* current_thread = CompilerThread::current(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
204 _factory->remove_symbols(); |
0 | 205 current_thread->set_env(NULL); |
206 } | |
207 | |
208 // ------------------------------------------------------------------ | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
209 // Cache Jvmti state |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
210 void ciEnv::cache_jvmti_state() { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
211 VM_ENTRY_MARK; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
212 // Get Jvmti capabilities under lock to get consistant values. |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
213 MutexLocker mu(JvmtiThreadState_lock); |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
214 _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
215 _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
216 _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions(); |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
217 } |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
218 |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
219 // ------------------------------------------------------------------ |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
220 // Cache DTrace flags |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
221 void ciEnv::cache_dtrace_flags() { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
222 // Need lock? |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
223 _dtrace_extended_probes = ExtendedDTraceProbes; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
224 if (_dtrace_extended_probes) { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
225 _dtrace_monitor_probes = true; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
226 _dtrace_method_probes = true; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
227 _dtrace_alloc_probes = true; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
228 } else { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
229 _dtrace_monitor_probes = DTraceMonitorProbes; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
230 _dtrace_method_probes = DTraceMethodProbes; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
231 _dtrace_alloc_probes = DTraceAllocProbes; |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
232 } |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
233 } |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
234 |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
235 // ------------------------------------------------------------------ |
0 | 236 // helper for lazy exception creation |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
237 ciInstance* ciEnv::get_or_create_exception(jobject& handle, Symbol* name) { |
0 | 238 VM_ENTRY_MARK; |
239 if (handle == NULL) { | |
240 // Cf. universe.cpp, creation of Universe::_null_ptr_exception_instance. | |
241 klassOop k = SystemDictionary::find(name, Handle(), Handle(), THREAD); | |
242 jobject objh = NULL; | |
243 if (!HAS_PENDING_EXCEPTION && k != NULL) { | |
244 oop obj = instanceKlass::cast(k)->allocate_permanent_instance(THREAD); | |
245 if (!HAS_PENDING_EXCEPTION) | |
246 objh = JNIHandles::make_global(obj); | |
247 } | |
248 if (HAS_PENDING_EXCEPTION) { | |
249 CLEAR_PENDING_EXCEPTION; | |
250 } else { | |
251 handle = objh; | |
252 } | |
253 } | |
254 oop obj = JNIHandles::resolve(handle); | |
255 return obj == NULL? NULL: get_object(obj)->as_instance(); | |
256 } | |
257 | |
258 // ------------------------------------------------------------------ | |
259 // ciEnv::ArrayIndexOutOfBoundsException_instance, etc. | |
260 ciInstance* ciEnv::ArrayIndexOutOfBoundsException_instance() { | |
261 if (_ArrayIndexOutOfBoundsException_instance == NULL) { | |
262 _ArrayIndexOutOfBoundsException_instance | |
263 = get_or_create_exception(_ArrayIndexOutOfBoundsException_handle, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
264 vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); |
0 | 265 } |
266 return _ArrayIndexOutOfBoundsException_instance; | |
267 } | |
268 ciInstance* ciEnv::ArrayStoreException_instance() { | |
269 if (_ArrayStoreException_instance == NULL) { | |
270 _ArrayStoreException_instance | |
271 = get_or_create_exception(_ArrayStoreException_handle, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
272 vmSymbols::java_lang_ArrayStoreException()); |
0 | 273 } |
274 return _ArrayStoreException_instance; | |
275 } | |
276 ciInstance* ciEnv::ClassCastException_instance() { | |
277 if (_ClassCastException_instance == NULL) { | |
278 _ClassCastException_instance | |
279 = get_or_create_exception(_ClassCastException_handle, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
280 vmSymbols::java_lang_ClassCastException()); |
0 | 281 } |
282 return _ClassCastException_instance; | |
283 } | |
284 | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
285 ciInstance* ciEnv::the_null_string() { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
286 if (_the_null_string == NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
287 VM_ENTRY_MARK; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
288 _the_null_string = get_object(Universe::the_null_string())->as_instance(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
289 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
290 return _the_null_string; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
291 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
292 |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
293 ciInstance* ciEnv::the_min_jint_string() { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
294 if (_the_min_jint_string == NULL) { |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
295 VM_ENTRY_MARK; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
296 _the_min_jint_string = get_object(Universe::the_min_jint_string())->as_instance(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
297 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
298 return _the_min_jint_string; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
299 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
300 |
0 | 301 // ------------------------------------------------------------------ |
302 // ciEnv::get_method_from_handle | |
303 ciMethod* ciEnv::get_method_from_handle(jobject method) { | |
304 VM_ENTRY_MARK; | |
305 return get_object(JNIHandles::resolve(method))->as_method(); | |
306 } | |
307 | |
308 // ------------------------------------------------------------------ | |
309 // ciEnv::make_array | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
310 ciArray* ciEnv::make_system_array(GrowableArray<ciObject*>* objects) { |
0 | 311 VM_ENTRY_MARK; |
312 int length = objects->length(); | |
313 objArrayOop a = oopFactory::new_system_objArray(length, THREAD); | |
314 if (HAS_PENDING_EXCEPTION) { | |
315 CLEAR_PENDING_EXCEPTION; | |
316 record_out_of_memory_failure(); | |
317 return NULL; | |
318 } | |
319 for (int i = 0; i < length; i++) { | |
320 a->obj_at_put(i, objects->at(i)->get_oop()); | |
321 } | |
322 assert(a->is_perm(), ""); | |
323 return get_object(a)->as_array(); | |
324 } | |
325 | |
326 | |
327 // ------------------------------------------------------------------ | |
328 // ciEnv::array_element_offset_in_bytes | |
329 int ciEnv::array_element_offset_in_bytes(ciArray* a_h, ciObject* o_h) { | |
330 VM_ENTRY_MARK; | |
331 objArrayOop a = (objArrayOop)a_h->get_oop(); | |
332 assert(a->is_objArray(), ""); | |
333 int length = a->length(); | |
334 oop o = o_h->get_oop(); | |
335 for (int i = 0; i < length; i++) { | |
336 if (a->obj_at(i) == o) return i; | |
337 } | |
338 return -1; | |
339 } | |
340 | |
341 | |
342 // ------------------------------------------------------------------ | |
343 // ciEnv::check_klass_accessiblity | |
344 // | |
345 // Note: the logic of this method should mirror the logic of | |
346 // constantPoolOopDesc::verify_constant_pool_resolve. | |
347 bool ciEnv::check_klass_accessibility(ciKlass* accessing_klass, | |
348 klassOop resolved_klass) { | |
349 if (accessing_klass == NULL || !accessing_klass->is_loaded()) { | |
350 return true; | |
351 } | |
352 if (accessing_klass->is_obj_array()) { | |
353 accessing_klass = accessing_klass->as_obj_array_klass()->base_element_klass(); | |
354 } | |
355 if (!accessing_klass->is_instance_klass()) { | |
356 return true; | |
357 } | |
358 | |
359 if (resolved_klass->klass_part()->oop_is_objArray()) { | |
360 // Find the element klass, if this is an array. | |
361 resolved_klass = objArrayKlass::cast(resolved_klass)->bottom_klass(); | |
362 } | |
363 if (resolved_klass->klass_part()->oop_is_instance()) { | |
364 return Reflection::verify_class_access(accessing_klass->get_klassOop(), | |
365 resolved_klass, | |
366 true); | |
367 } | |
368 return true; | |
369 } | |
370 | |
371 // ------------------------------------------------------------------ | |
372 // ciEnv::get_klass_by_name_impl | |
373 ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, | |
374 ciSymbol* name, | |
375 bool require_local) { | |
376 ASSERT_IN_VM; | |
377 EXCEPTION_CONTEXT; | |
378 | |
379 // Now we need to check the SystemDictionary | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
380 Symbol* sym = name->get_symbol(); |
0 | 381 if (sym->byte_at(0) == 'L' && |
382 sym->byte_at(sym->utf8_length()-1) == ';') { | |
383 // This is a name from a signature. Strip off the trimmings. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
384 // Call recursive to keep scope of strippedsym. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
385 TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
386 sym->utf8_length()-2, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
387 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
388 ciSymbol* strippedname = get_symbol(strippedsym); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
389 return get_klass_by_name_impl(accessing_klass, strippedname, require_local); |
0 | 390 } |
391 | |
392 // Check for prior unloaded klass. The SystemDictionary's answers | |
393 // can vary over time but the compiler needs consistency. | |
394 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); | |
395 if (unloaded_klass != NULL) { | |
396 if (require_local) return NULL; | |
397 return unloaded_klass; | |
398 } | |
399 | |
400 Handle loader(THREAD, (oop)NULL); | |
401 Handle domain(THREAD, (oop)NULL); | |
402 if (accessing_klass != NULL) { | |
403 loader = Handle(THREAD, accessing_klass->loader()); | |
404 domain = Handle(THREAD, accessing_klass->protection_domain()); | |
405 } | |
406 | |
407 // setup up the proper type to return on OOM | |
408 ciKlass* fail_type; | |
409 if (sym->byte_at(0) == '[') { | |
410 fail_type = _unloaded_ciobjarrayklass; | |
411 } else { | |
412 fail_type = _unloaded_ciinstance_klass; | |
413 } | |
2147
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
1972
diff
changeset
|
414 KlassHandle found_klass; |
2244
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
415 { |
2263
5841dc1964f0
7021531: lock ordering problems after fix for 6354181
never
parents:
2244
diff
changeset
|
416 ttyUnlocker ttyul; // release tty lock to avoid ordering problems |
2244
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
417 MutexLocker ml(Compile_lock); |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
418 klassOop kls; |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
419 if (!require_local) { |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
420 kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
421 KILL_COMPILE_ON_FATAL_(fail_type)); |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
422 } else { |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
423 kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
424 KILL_COMPILE_ON_FATAL_(fail_type)); |
4f26f535a225
6354181: nsk.logging.stress.threads.scmhml001 fails assertion in "src/share/vm/oops/instanceKlass.cpp, 111"
never
parents:
2177
diff
changeset
|
425 } |
2147
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
1972
diff
changeset
|
426 found_klass = KlassHandle(THREAD, kls); |
0 | 427 } |
428 | |
429 // If we fail to find an array klass, look again for its element type. | |
430 // The element type may be available either locally or via constraints. | |
431 // In either case, if we can find the element type in the system dictionary, | |
432 // we must build an array type around it. The CI requires array klasses | |
433 // to be loaded if their element klasses are loaded, except when memory | |
434 // is exhausted. | |
435 if (sym->byte_at(0) == '[' && | |
436 (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { | |
437 // We have an unloaded array. | |
438 // Build it on the fly if the element class exists. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
439 TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
440 sym->utf8_length()-1, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
441 KILL_COMPILE_ON_FATAL_(fail_type)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
442 |
0 | 443 // Get element ciKlass recursively. |
444 ciKlass* elem_klass = | |
445 get_klass_by_name_impl(accessing_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
446 get_symbol(elem_sym), |
0 | 447 require_local); |
448 if (elem_klass != NULL && elem_klass->is_loaded()) { | |
449 // Now make an array for it | |
450 return ciObjArrayKlass::make_impl(elem_klass); | |
451 } | |
452 } | |
453 | |
2147
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
1972
diff
changeset
|
454 if (found_klass() != NULL) { |
0 | 455 // Found it. Build a CI handle. |
2147
9afee0b9fc1d
7012505: BreakpointWithFullGC.sh fails with Internal Error (src/share/vm/oops/methodOop.cpp:220)
kamg
parents:
1972
diff
changeset
|
456 return get_object(found_klass())->as_klass(); |
0 | 457 } |
458 | |
459 if (require_local) return NULL; | |
460 // Not yet loaded into the VM, or not governed by loader constraints. | |
461 // Make a CI representative for it. | |
462 return get_unloaded_klass(accessing_klass, name); | |
463 } | |
464 | |
465 // ------------------------------------------------------------------ | |
466 // ciEnv::get_klass_by_name | |
467 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass, | |
468 ciSymbol* klass_name, | |
469 bool require_local) { | |
470 GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass, | |
471 klass_name, | |
472 require_local);) | |
473 } | |
474 | |
475 // ------------------------------------------------------------------ | |
476 // ciEnv::get_klass_by_index_impl | |
477 // | |
478 // Implementation of get_klass_by_index. | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
479 ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool, |
0 | 480 int index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
481 bool& is_accessible, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
482 ciInstanceKlass* accessor) { |
0 | 483 EXCEPTION_CONTEXT; |
484 KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
485 Symbol* klass_name = NULL; |
0 | 486 if (klass.is_null()) { |
487 // The klass has not been inserted into the constant pool. | |
488 // Try to look it up by name. | |
489 { | |
490 // We have to lock the cpool to keep the oop from being resolved | |
491 // while we are accessing it. | |
492 ObjectLocker ol(cpool, THREAD); | |
493 | |
494 constantTag tag = cpool->tag_at(index); | |
495 if (tag.is_klass()) { | |
496 // The klass has been inserted into the constant pool | |
497 // very recently. | |
498 klass = KlassHandle(THREAD, cpool->resolved_klass_at(index)); | |
499 } else if (tag.is_symbol()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
500 klass_name = cpool->symbol_at(index); |
0 | 501 } else { |
502 assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag"); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
503 klass_name = cpool->unresolved_klass_at(index); |
0 | 504 } |
505 } | |
506 } | |
507 | |
508 if (klass.is_null()) { | |
509 // Not found in constant pool. Use the name to do the lookup. | |
510 ciKlass* k = get_klass_by_name_impl(accessor, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
511 get_symbol(klass_name), |
0 | 512 false); |
513 // Calculate accessibility the hard way. | |
514 if (!k->is_loaded()) { | |
515 is_accessible = false; | |
516 } else if (k->loader() != accessor->loader() && | |
517 get_klass_by_name_impl(accessor, k->name(), true) == NULL) { | |
518 // Loaded only remotely. Not linked yet. | |
519 is_accessible = false; | |
520 } else { | |
521 // Linked locally, and we must also check public/private, etc. | |
522 is_accessible = check_klass_accessibility(accessor, k->get_klassOop()); | |
523 } | |
524 return k; | |
525 } | |
526 | |
527 // Check for prior unloaded klass. The SystemDictionary's answers | |
528 // can vary over time but the compiler needs consistency. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
529 ciSymbol* name = get_symbol(klass()->klass_part()->name()); |
0 | 530 ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name); |
531 if (unloaded_klass != NULL) { | |
532 is_accessible = false; | |
533 return unloaded_klass; | |
534 } | |
535 | |
536 // It is known to be accessible, since it was found in the constant pool. | |
537 is_accessible = true; | |
538 return get_object(klass())->as_klass(); | |
539 } | |
540 | |
541 // ------------------------------------------------------------------ | |
542 // ciEnv::get_klass_by_index | |
543 // | |
544 // Get a klass from the constant pool. | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
545 ciKlass* ciEnv::get_klass_by_index(constantPoolHandle cpool, |
0 | 546 int index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
547 bool& is_accessible, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
548 ciInstanceKlass* accessor) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
549 GUARDED_VM_ENTRY(return get_klass_by_index_impl(cpool, index, is_accessible, accessor);) |
0 | 550 } |
551 | |
552 // ------------------------------------------------------------------ | |
553 // ciEnv::get_constant_by_index_impl | |
554 // | |
555 // Implementation of get_constant_by_index(). | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
556 ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool, |
1602 | 557 int pool_index, int cache_index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
558 ciInstanceKlass* accessor) { |
1602 | 559 bool ignore_will_link; |
0 | 560 EXCEPTION_CONTEXT; |
1602 | 561 int index = pool_index; |
562 if (cache_index >= 0) { | |
563 assert(index < 0, "only one kind of index at a time"); | |
564 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); | |
565 index = cpc_entry->constant_pool_index(); | |
566 oop obj = cpc_entry->f1(); | |
567 if (obj != NULL) { | |
568 assert(obj->is_instance(), "must be an instance"); | |
569 ciObject* ciobj = get_object(obj); | |
570 return ciConstant(T_OBJECT, ciobj); | |
571 } | |
572 } | |
0 | 573 constantTag tag = cpool->tag_at(index); |
574 if (tag.is_int()) { | |
575 return ciConstant(T_INT, (jint)cpool->int_at(index)); | |
576 } else if (tag.is_long()) { | |
577 return ciConstant((jlong)cpool->long_at(index)); | |
578 } else if (tag.is_float()) { | |
579 return ciConstant((jfloat)cpool->float_at(index)); | |
580 } else if (tag.is_double()) { | |
581 return ciConstant((jdouble)cpool->double_at(index)); | |
582 } else if (tag.is_string() || tag.is_unresolved_string()) { | |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
583 oop string = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
584 if (cpool->is_pseudo_string_at(index)) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
585 string = cpool->pseudo_string_at(index); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
586 } else { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
587 string = cpool->string_at(index, THREAD); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
588 if (HAS_PENDING_EXCEPTION) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
589 CLEAR_PENDING_EXCEPTION; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
590 record_out_of_memory_failure(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
591 return ciConstant(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
592 } |
0 | 593 } |
594 ciObject* constant = get_object(string); | |
595 assert (constant->is_instance(), "must be an instance, or not? "); | |
596 return ciConstant(T_OBJECT, constant); | |
597 } else if (tag.is_klass() || tag.is_unresolved_klass()) { | |
598 // 4881222: allow ldc to take a class type | |
1602 | 599 ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore_will_link, accessor); |
0 | 600 if (HAS_PENDING_EXCEPTION) { |
601 CLEAR_PENDING_EXCEPTION; | |
602 record_out_of_memory_failure(); | |
603 return ciConstant(); | |
604 } | |
605 assert (klass->is_instance_klass() || klass->is_array_klass(), | |
606 "must be an instance or array klass "); | |
1602 | 607 return ciConstant(T_OBJECT, klass->java_mirror()); |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
608 } else if (tag.is_object()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
609 oop obj = cpool->object_at(index); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
610 assert(obj->is_instance(), "must be an instance"); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
611 ciObject* ciobj = get_object(obj); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
612 return ciConstant(T_OBJECT, ciobj); |
1602 | 613 } else if (tag.is_method_type()) { |
614 // must execute Java code to link this CP entry into cache[i].f1 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
615 ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); |
1602 | 616 ciObject* ciobj = get_unloaded_method_type_constant(signature); |
617 return ciConstant(T_OBJECT, ciobj); | |
618 } else if (tag.is_method_handle()) { | |
619 // must execute Java code to link this CP entry into cache[i].f1 | |
620 int ref_kind = cpool->method_handle_ref_kind_at(index); | |
621 int callee_index = cpool->method_handle_klass_index_at(index); | |
622 ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
623 ciSymbol* name = get_symbol(cpool->method_handle_name_ref_at(index)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
624 ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index)); |
1602 | 625 ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); |
626 return ciConstant(T_OBJECT, ciobj); | |
0 | 627 } else { |
628 ShouldNotReachHere(); | |
629 return ciConstant(); | |
630 } | |
631 } | |
632 | |
633 // ------------------------------------------------------------------ | |
634 // ciEnv::get_constant_by_index | |
635 // | |
636 // Pull a constant out of the constant pool. How appropriate. | |
637 // | |
638 // Implementation note: this query is currently in no way cached. | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
639 ciConstant ciEnv::get_constant_by_index(constantPoolHandle cpool, |
1602 | 640 int pool_index, int cache_index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
641 ciInstanceKlass* accessor) { |
1602 | 642 GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, pool_index, cache_index, accessor);) |
0 | 643 } |
644 | |
645 // ------------------------------------------------------------------ | |
646 // ciEnv::get_field_by_index_impl | |
647 // | |
648 // Implementation of get_field_by_index. | |
649 // | |
650 // Implementation note: the results of field lookups are cached | |
651 // in the accessor klass. | |
652 ciField* ciEnv::get_field_by_index_impl(ciInstanceKlass* accessor, | |
653 int index) { | |
654 ciConstantPoolCache* cache = accessor->field_cache(); | |
655 if (cache == NULL) { | |
656 ciField* field = new (arena()) ciField(accessor, index); | |
657 return field; | |
658 } else { | |
659 ciField* field = (ciField*)cache->get(index); | |
660 if (field == NULL) { | |
661 field = new (arena()) ciField(accessor, index); | |
662 cache->insert(index, field); | |
663 } | |
664 return field; | |
665 } | |
666 } | |
667 | |
668 // ------------------------------------------------------------------ | |
669 // ciEnv::get_field_by_index | |
670 // | |
671 // Get a field by index from a klass's constant pool. | |
672 ciField* ciEnv::get_field_by_index(ciInstanceKlass* accessor, | |
673 int index) { | |
674 GUARDED_VM_ENTRY(return get_field_by_index_impl(accessor, index);) | |
675 } | |
676 | |
677 // ------------------------------------------------------------------ | |
678 // ciEnv::lookup_method | |
679 // | |
680 // Perform an appropriate method lookup based on accessor, holder, | |
681 // name, signature, and bytecode. | |
682 methodOop ciEnv::lookup_method(instanceKlass* accessor, | |
683 instanceKlass* holder, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
684 Symbol* name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
685 Symbol* sig, |
0 | 686 Bytecodes::Code bc) { |
687 EXCEPTION_CONTEXT; | |
688 KlassHandle h_accessor(THREAD, accessor); | |
689 KlassHandle h_holder(THREAD, holder); | |
690 LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); | |
691 methodHandle dest_method; | |
692 switch (bc) { | |
693 case Bytecodes::_invokestatic: | |
694 dest_method = | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
695 LinkResolver::resolve_static_call_or_null(h_holder, name, sig, h_accessor); |
0 | 696 break; |
697 case Bytecodes::_invokespecial: | |
698 dest_method = | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
699 LinkResolver::resolve_special_call_or_null(h_holder, name, sig, h_accessor); |
0 | 700 break; |
701 case Bytecodes::_invokeinterface: | |
702 dest_method = | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
703 LinkResolver::linktime_resolve_interface_method_or_null(h_holder, name, sig, |
0 | 704 h_accessor, true); |
705 break; | |
706 case Bytecodes::_invokevirtual: | |
707 dest_method = | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
708 LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, name, sig, |
0 | 709 h_accessor, true); |
710 break; | |
711 default: ShouldNotReachHere(); | |
712 } | |
713 | |
714 return dest_method(); | |
715 } | |
716 | |
717 | |
718 // ------------------------------------------------------------------ | |
719 // ciEnv::get_method_by_index_impl | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
720 ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
721 int index, Bytecodes::Code bc, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
722 ciInstanceKlass* accessor) { |
0 | 723 int holder_index = cpool->klass_ref_index_at(index); |
724 bool holder_is_accessible; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
725 ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); |
0 | 726 ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); |
727 | |
728 // Get the method's name and signature. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
729 Symbol* name_sym = cpool->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
730 Symbol* sig_sym = cpool->signature_ref_at(index); |
0 | 731 |
732 if (holder_is_accessible) { // Our declared holder is loaded. | |
733 instanceKlass* lookup = declared_holder->get_instanceKlass(); | |
734 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); | |
735 if (m != NULL) { | |
736 // We found the method. | |
737 return get_object(m)->as_method(); | |
738 } | |
739 } | |
740 | |
741 // Either the declared holder was not loaded, or the method could | |
742 // not be found. Create a dummy ciMethod to represent the failed | |
743 // lookup. | |
744 | |
745 return get_unloaded_method(declared_holder, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
746 get_symbol(name_sym), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
747 get_symbol(sig_sym)); |
0 | 748 } |
749 | |
750 | |
751 // ------------------------------------------------------------------ | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
752 // ciEnv::get_fake_invokedynamic_method_impl |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
753 ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool, |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
754 int index, Bytecodes::Code bc) { |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
755 // Compare the following logic with InterpreterRuntime::resolve_invokedynamic. |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
756 assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
757 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
758 bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc); |
3279
08ccee2c4dbf
6993078: JSR 292 too many pushes: Lesp points into register window
twisti
parents:
2426
diff
changeset
|
759 if (is_resolved && cpool->cache()->secondary_entry_at(index)->is_f1_null()) |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
760 // FIXME: code generation could allow for null (unlinked) call site |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
761 is_resolved = false; |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
762 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
763 // Call site might not be resolved yet. We could create a real invoker method from the |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
764 // compiler, but it is simpler to stop the code path here with an unlinked method. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
765 if (!is_resolved) { |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
766 ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2147
diff
changeset
|
767 ciSymbol* sig_sym = get_symbol(cpool->signature_ref_at(index)); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
768 return get_unloaded_method(mh_klass, ciSymbol::invokeExact_name(), sig_sym); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
769 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
770 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
771 // Get the invoker methodOop from the constant pool. |
1662
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1602
diff
changeset
|
772 oop f1_value = cpool->cache()->main_entry_at(index)->f1(); |
3279
08ccee2c4dbf
6993078: JSR 292 too many pushes: Lesp points into register window
twisti
parents:
2426
diff
changeset
|
773 methodOop signature_invoker = (methodOop) f1_value; |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
774 assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
775 "correct result from LinkResolver::resolve_invokedynamic"); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
776 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
777 return get_object(signature_invoker)->as_method(); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
778 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
779 |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
780 |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
781 // ------------------------------------------------------------------ |
0 | 782 // ciEnv::get_instance_klass_for_declared_method_holder |
783 ciInstanceKlass* ciEnv::get_instance_klass_for_declared_method_holder(ciKlass* method_holder) { | |
784 // For the case of <array>.clone(), the method holder can be a ciArrayKlass | |
785 // instead of a ciInstanceKlass. For that case simply pretend that the | |
786 // declared holder is Object.clone since that's where the call will bottom out. | |
787 // A more correct fix would trickle out through many interfaces in CI, | |
788 // requiring ciInstanceKlass* to become ciKlass* and many more places would | |
789 // require checks to make sure the expected type was found. Given that this | |
790 // only occurs for clone() the more extensive fix seems like overkill so | |
791 // instead we simply smear the array type into Object. | |
792 if (method_holder->is_instance_klass()) { | |
793 return method_holder->as_instance_klass(); | |
794 } else if (method_holder->is_array_klass()) { | |
795 return current()->Object_klass(); | |
796 } else { | |
797 ShouldNotReachHere(); | |
798 } | |
799 return NULL; | |
800 } | |
801 | |
802 | |
803 // ------------------------------------------------------------------ | |
804 // ciEnv::get_method_by_index | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
805 ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
806 int index, Bytecodes::Code bc, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
807 ciInstanceKlass* accessor) { |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
808 if (bc == Bytecodes::_invokedynamic) { |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
809 GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc);) |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
810 } else { |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
811 GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);) |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
812 } |
0 | 813 } |
814 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
815 |
0 | 816 // ------------------------------------------------------------------ |
817 // ciEnv::name_buffer | |
818 char *ciEnv::name_buffer(int req_len) { | |
819 if (_name_buffer_len < req_len) { | |
820 if (_name_buffer == NULL) { | |
821 _name_buffer = (char*)arena()->Amalloc(sizeof(char)*req_len); | |
822 _name_buffer_len = req_len; | |
823 } else { | |
824 _name_buffer = | |
825 (char*)arena()->Arealloc(_name_buffer, _name_buffer_len, req_len); | |
826 _name_buffer_len = req_len; | |
827 } | |
828 } | |
829 return _name_buffer; | |
830 } | |
831 | |
832 // ------------------------------------------------------------------ | |
833 // ciEnv::is_in_vm | |
834 bool ciEnv::is_in_vm() { | |
835 return JavaThread::current()->thread_state() == _thread_in_vm; | |
836 } | |
837 | |
838 bool ciEnv::system_dictionary_modification_counter_changed() { | |
839 return _system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); | |
840 } | |
841 | |
842 // ------------------------------------------------------------------ | |
843 // ciEnv::check_for_system_dictionary_modification | |
844 // Check for changes to the system dictionary during compilation | |
845 // class loads, evolution, breakpoints | |
846 void ciEnv::check_for_system_dictionary_modification(ciMethod* target) { | |
847 if (failing()) return; // no need for further checks | |
848 | |
849 // Dependencies must be checked when the system dictionary changes. | |
850 // If logging is enabled all violated dependences will be recorded in | |
851 // the log. In debug mode check dependencies even if the system | |
852 // dictionary hasn't changed to verify that no invalid dependencies | |
853 // were inserted. Any violated dependences in this case are dumped to | |
854 // the tty. | |
855 | |
856 bool counter_changed = system_dictionary_modification_counter_changed(); | |
857 bool test_deps = counter_changed; | |
858 DEBUG_ONLY(test_deps = true); | |
859 if (!test_deps) return; | |
860 | |
861 bool print_failures = false; | |
862 DEBUG_ONLY(print_failures = !counter_changed); | |
863 | |
864 bool keep_going = (print_failures || xtty != NULL); | |
865 | |
866 int violated = 0; | |
867 | |
868 for (Dependencies::DepStream deps(dependencies()); deps.next(); ) { | |
869 klassOop witness = deps.check_dependency(); | |
870 if (witness != NULL) { | |
871 ++violated; | |
872 if (print_failures) deps.print_dependency(witness, /*verbose=*/ true); | |
873 // If there's no log and we're not sanity-checking, we're done. | |
874 if (!keep_going) break; | |
875 } | |
876 } | |
877 | |
878 if (violated != 0) { | |
879 assert(counter_changed, "failed dependencies, but counter didn't change"); | |
880 record_failure("concurrent class loading"); | |
881 } | |
882 } | |
883 | |
884 // ------------------------------------------------------------------ | |
885 // ciEnv::register_method | |
886 void ciEnv::register_method(ciMethod* target, | |
887 int entry_bci, | |
888 CodeOffsets* offsets, | |
889 int orig_pc_offset, | |
890 CodeBuffer* code_buffer, | |
891 int frame_words, | |
892 OopMapSet* oop_map_set, | |
893 ExceptionHandlerTable* handler_table, | |
894 ImplicitExceptionTable* inc_table, | |
895 AbstractCompiler* compiler, | |
896 int comp_level, | |
897 bool has_debug_info, | |
898 bool has_unsafe_access) { | |
899 VM_ENTRY_MARK; | |
900 nmethod* nm = NULL; | |
901 { | |
902 // To prevent compile queue updates. | |
903 MutexLocker locker(MethodCompileQueue_lock, THREAD); | |
904 | |
905 // Prevent SystemDictionary::add_to_hierarchy from running | |
906 // and invalidating our dependencies until we install this method. | |
907 MutexLocker ml(Compile_lock); | |
908 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
909 // Change in Jvmti state may invalidate compilation. |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
910 if (!failing() && |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
911 ( (!jvmti_can_hotswap_or_post_breakpoint() && |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
912 JvmtiExport::can_hotswap_or_post_breakpoint()) || |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
913 (!jvmti_can_access_local_variables() && |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
914 JvmtiExport::can_access_local_variables()) || |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
915 (!jvmti_can_post_on_exceptions() && |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
916 JvmtiExport::can_post_on_exceptions()) )) { |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
917 record_failure("Jvmti state change invalidated dependencies"); |
0 | 918 } |
919 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
920 // Change in DTrace flags may invalidate compilation. |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
921 if (!failing() && |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
922 ( (!dtrace_extended_probes() && ExtendedDTraceProbes) || |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
923 (!dtrace_method_probes() && DTraceMethodProbes) || |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
924 (!dtrace_alloc_probes() && DTraceAllocProbes) )) { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
925 record_failure("DTrace flags change invalidated dependencies"); |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
926 } |
0 | 927 |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
928 if (!failing()) { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
929 if (log() != NULL) { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
930 // Log the dependencies which this compilation declares. |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
931 dependencies()->log_all_dependencies(); |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
932 } |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
933 |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
934 // Encode the dependencies now, so we can check them right away. |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
935 dependencies()->encode_content_bytes(); |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
936 |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
937 // Check for {class loads, evolution, breakpoints} during compilation |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
938 check_for_system_dictionary_modification(target); |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
939 } |
0 | 940 |
941 methodHandle method(THREAD, target->get_methodOop()); | |
942 | |
943 if (failing()) { | |
944 // While not a true deoptimization, it is a preemptive decompile. | |
945 methodDataOop mdo = method()->method_data(); | |
946 if (mdo != NULL) { | |
947 mdo->inc_decompile_count(); | |
948 } | |
949 | |
950 // All buffers in the CodeBuffer are allocated in the CodeCache. | |
951 // If the code buffer is created on each compile attempt | |
952 // as in C2, then it must be freed. | |
953 code_buffer->free_blob(); | |
954 return; | |
955 } | |
956 | |
957 assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry"); | |
958 assert(offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry"); | |
959 | |
960 nm = nmethod::new_nmethod(method, | |
961 compile_id(), | |
962 entry_bci, | |
963 offsets, | |
964 orig_pc_offset, | |
965 debug_info(), dependencies(), code_buffer, | |
966 frame_words, oop_map_set, | |
967 handler_table, inc_table, | |
968 compiler, comp_level); | |
969 | |
970 // Free codeBlobs | |
971 code_buffer->free_blob(); | |
972 | |
973 // stress test 6243940 by immediately making the method | |
974 // non-entrant behind the system's back. This has serious | |
975 // side effects on the code cache and is not meant for | |
976 // general stress testing | |
977 if (nm != NULL && StressNonEntrant) { | |
978 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); | |
979 NativeJump::patch_verified_entry(nm->entry_point(), nm->verified_entry_point(), | |
980 SharedRuntime::get_handle_wrong_method_stub()); | |
981 } | |
982 | |
983 if (nm == NULL) { | |
984 // The CodeCache is full. Print out warning and disable compilation. | |
985 record_failure("code cache is full"); | |
1202 | 986 { |
987 MutexUnlocker ml(Compile_lock); | |
988 MutexUnlocker locker(MethodCompileQueue_lock); | |
989 CompileBroker::handle_full_code_cache(); | |
0 | 990 } |
991 } else { | |
992 NOT_PRODUCT(nm->set_has_debug_info(has_debug_info); ) | |
993 nm->set_has_unsafe_access(has_unsafe_access); | |
994 | |
995 // Record successful registration. | |
996 // (Put nm into the task handle *before* publishing to the Java heap.) | |
997 if (task() != NULL) task()->set_code(nm); | |
998 | |
999 if (entry_bci == InvocationEntryBci) { | |
1783 | 1000 if (TieredCompilation) { |
1001 // If there is an old version we're done with it | |
1002 nmethod* old = method->code(); | |
1003 if (TraceMethodReplacement && old != NULL) { | |
1004 ResourceMark rm; | |
1005 char *method_name = method->name_and_sig_as_C_string(); | |
1006 tty->print_cr("Replacing method %s", method_name); | |
1007 } | |
1008 if (old != NULL ) { | |
1009 old->make_not_entrant(); | |
1010 } | |
0 | 1011 } |
1012 if (TraceNMethodInstalls ) { | |
1013 ResourceMark rm; | |
1014 char *method_name = method->name_and_sig_as_C_string(); | |
1015 ttyLocker ttyl; | |
1016 tty->print_cr("Installing method (%d) %s ", | |
1017 comp_level, | |
1018 method_name); | |
1019 } | |
1020 // Allow the code to be executed | |
1021 method->set_code(method, nm); | |
1022 } else { | |
1023 if (TraceNMethodInstalls ) { | |
1024 ResourceMark rm; | |
1025 char *method_name = method->name_and_sig_as_C_string(); | |
1026 ttyLocker ttyl; | |
1027 tty->print_cr("Installing osr method (%d) %s @ %d", | |
1028 comp_level, | |
1029 method_name, | |
1030 entry_bci); | |
1031 } | |
1032 instanceKlass::cast(method->method_holder())->add_osr_nmethod(nm); | |
1033 | |
1034 } | |
1035 } | |
1036 } | |
1037 // JVMTI -- compiled method notification (must be done outside lock) | |
1038 if (nm != NULL) { | |
1039 nm->post_compiled_method_load_event(); | |
1040 } | |
1041 | |
1042 } | |
1043 | |
1044 | |
1045 // ------------------------------------------------------------------ | |
1046 // ciEnv::find_system_klass | |
1047 ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) { | |
1048 VM_ENTRY_MARK; | |
1049 return get_klass_by_name_impl(NULL, klass_name, false); | |
1050 } | |
1051 | |
1052 // ------------------------------------------------------------------ | |
1053 // ciEnv::comp_level | |
1054 int ciEnv::comp_level() { | |
1783 | 1055 if (task() == NULL) return CompLevel_highest_tier; |
0 | 1056 return task()->comp_level(); |
1057 } | |
1058 | |
1059 // ------------------------------------------------------------------ | |
1060 // ciEnv::compile_id | |
1061 uint ciEnv::compile_id() { | |
1062 if (task() == NULL) return 0; | |
1063 return task()->compile_id(); | |
1064 } | |
1065 | |
1066 // ------------------------------------------------------------------ | |
1067 // ciEnv::notice_inlined_method() | |
1068 void ciEnv::notice_inlined_method(ciMethod* method) { | |
1069 _num_inlined_bytecodes += method->code_size(); | |
1070 } | |
1071 | |
1072 // ------------------------------------------------------------------ | |
1073 // ciEnv::num_inlined_bytecodes() | |
1074 int ciEnv::num_inlined_bytecodes() const { | |
1075 return _num_inlined_bytecodes; | |
1076 } | |
1077 | |
1078 // ------------------------------------------------------------------ | |
1079 // ciEnv::record_failure() | |
1080 void ciEnv::record_failure(const char* reason) { | |
1081 if (log() != NULL) { | |
1082 log()->elem("failure reason='%s'", reason); | |
1083 } | |
1084 if (_failure_reason == NULL) { | |
1085 // Record the first failure reason. | |
1086 _failure_reason = reason; | |
1087 } | |
1088 } | |
1089 | |
1090 // ------------------------------------------------------------------ | |
1091 // ciEnv::record_method_not_compilable() | |
1092 void ciEnv::record_method_not_compilable(const char* reason, bool all_tiers) { | |
1093 int new_compilable = | |
1094 all_tiers ? MethodCompilable_never : MethodCompilable_not_at_tier ; | |
1095 | |
1096 // Only note transitions to a worse state | |
1097 if (new_compilable > _compilable) { | |
1098 if (log() != NULL) { | |
1099 if (all_tiers) { | |
1100 log()->elem("method_not_compilable"); | |
1101 } else { | |
1102 log()->elem("method_not_compilable_at_tier"); | |
1103 } | |
1104 } | |
1105 _compilable = new_compilable; | |
1106 | |
1107 // Reset failure reason; this one is more important. | |
1108 _failure_reason = NULL; | |
1109 record_failure(reason); | |
1110 } | |
1111 } | |
1112 | |
1113 // ------------------------------------------------------------------ | |
1114 // ciEnv::record_out_of_memory_failure() | |
1115 void ciEnv::record_out_of_memory_failure() { | |
1116 // If memory is low, we stop compiling methods. | |
1117 record_method_not_compilable("out of memory"); | |
1118 } |