Mercurial > hg > truffle
annotate src/share/vm/ci/ciEnv.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 06f017f7daa7 9afee0b9fc1d |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
2 * Copyright (c) 1999, 2010, 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 ciSymbolKlass* ciEnv::_symbol_klass_instance; | |
72 ciKlassKlass* ciEnv::_klass_klass_instance; | |
73 ciInstanceKlassKlass* ciEnv::_instance_klass_klass_instance; | |
74 ciTypeArrayKlassKlass* ciEnv::_type_array_klass_klass_instance; | |
75 ciObjArrayKlassKlass* ciEnv::_obj_array_klass_klass_instance; | |
76 | |
1142 | 77 #define WK_KLASS_DEFN(name, ignore_s, ignore_o) ciInstanceKlass* ciEnv::_##name = NULL; |
78 WK_KLASSES_DO(WK_KLASS_DEFN) | |
79 #undef WK_KLASS_DEFN | |
0 | 80 |
81 ciSymbol* ciEnv::_unloaded_cisymbol = NULL; | |
82 ciInstanceKlass* ciEnv::_unloaded_ciinstance_klass = NULL; | |
83 ciObjArrayKlass* ciEnv::_unloaded_ciobjarrayklass = NULL; | |
84 | |
85 jobject ciEnv::_ArrayIndexOutOfBoundsException_handle = NULL; | |
86 jobject ciEnv::_ArrayStoreException_handle = NULL; | |
87 jobject ciEnv::_ClassCastException_handle = NULL; | |
88 | |
89 #ifndef PRODUCT | |
90 static bool firstEnv = true; | |
91 #endif /* PRODUCT */ | |
92 | |
93 // ------------------------------------------------------------------ | |
94 // ciEnv::ciEnv | |
95 ciEnv::ciEnv(CompileTask* task, int system_dictionary_modification_counter) { | |
96 VM_ENTRY_MARK; | |
97 | |
98 // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc. | |
99 thread->set_env(this); | |
100 assert(ciEnv::current() == this, "sanity"); | |
101 | |
102 _oop_recorder = NULL; | |
103 _debug_info = NULL; | |
104 _dependencies = NULL; | |
105 _failure_reason = NULL; | |
106 _compilable = MethodCompilable; | |
107 _break_at_compile = false; | |
108 _compiler_data = NULL; | |
109 #ifndef PRODUCT | |
110 assert(!firstEnv, "not initialized properly"); | |
111 #endif /* !PRODUCT */ | |
112 | |
113 _system_dictionary_modification_counter = system_dictionary_modification_counter; | |
114 _num_inlined_bytecodes = 0; | |
115 assert(task == NULL || thread->task() == task, "sanity"); | |
116 _task = task; | |
117 _log = NULL; | |
118 | |
119 // Temporary buffer for creating symbols and such. | |
120 _name_buffer = NULL; | |
121 _name_buffer_len = 0; | |
122 | |
123 _arena = &_ciEnv_arena; | |
124 _factory = new (_arena) ciObjectFactory(_arena, 128); | |
125 | |
126 // Preload commonly referenced system ciObjects. | |
127 | |
128 // During VM initialization, these instances have not yet been created. | |
129 // Assertions ensure that these instances are not accessed before | |
130 // their initialization. | |
131 | |
132 assert(Universe::is_fully_initialized(), "should be complete"); | |
133 | |
134 oop o = Universe::null_ptr_exception_instance(); | |
135 assert(o != NULL, "should have been initialized"); | |
136 _NullPointerException_instance = get_object(o)->as_instance(); | |
137 o = Universe::arithmetic_exception_instance(); | |
138 assert(o != NULL, "should have been initialized"); | |
139 _ArithmeticException_instance = get_object(o)->as_instance(); | |
140 | |
141 _ArrayIndexOutOfBoundsException_instance = NULL; | |
142 _ArrayStoreException_instance = NULL; | |
143 _ClassCastException_instance = NULL; | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
144 _the_null_string = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
145 _the_min_jint_string = NULL; |
0 | 146 } |
147 | |
148 ciEnv::ciEnv(Arena* arena) { | |
149 ASSERT_IN_VM; | |
150 | |
151 // Set up ciEnv::current immediately, for the sake of ciObjectFactory, etc. | |
152 CompilerThread* current_thread = CompilerThread::current(); | |
153 assert(current_thread->env() == NULL, "must be"); | |
154 current_thread->set_env(this); | |
155 assert(ciEnv::current() == this, "sanity"); | |
156 | |
157 _oop_recorder = NULL; | |
158 _debug_info = NULL; | |
159 _dependencies = NULL; | |
160 _failure_reason = NULL; | |
161 _compilable = MethodCompilable_never; | |
162 _break_at_compile = false; | |
163 _compiler_data = NULL; | |
164 #ifndef PRODUCT | |
165 assert(firstEnv, "must be first"); | |
166 firstEnv = false; | |
167 #endif /* !PRODUCT */ | |
168 | |
169 _system_dictionary_modification_counter = 0; | |
170 _num_inlined_bytecodes = 0; | |
171 _task = NULL; | |
172 _log = NULL; | |
173 | |
174 // Temporary buffer for creating symbols and such. | |
175 _name_buffer = NULL; | |
176 _name_buffer_len = 0; | |
177 | |
178 _arena = arena; | |
179 _factory = new (_arena) ciObjectFactory(_arena, 128); | |
180 | |
181 // Preload commonly referenced system ciObjects. | |
182 | |
183 // During VM initialization, these instances have not yet been created. | |
184 // Assertions ensure that these instances are not accessed before | |
185 // their initialization. | |
186 | |
187 assert(Universe::is_fully_initialized(), "must be"); | |
188 | |
189 oop o = Universe::null_ptr_exception_instance(); | |
190 assert(o != NULL, "should have been initialized"); | |
191 _NullPointerException_instance = get_object(o)->as_instance(); | |
192 o = Universe::arithmetic_exception_instance(); | |
193 assert(o != NULL, "should have been initialized"); | |
194 _ArithmeticException_instance = get_object(o)->as_instance(); | |
195 | |
196 _ArrayIndexOutOfBoundsException_instance = NULL; | |
197 _ArrayStoreException_instance = NULL; | |
198 _ClassCastException_instance = NULL; | |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
199 _the_null_string = NULL; |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1059
diff
changeset
|
200 _the_min_jint_string = NULL; |
0 | 201 } |
202 | |
203 ciEnv::~ciEnv() { | |
204 CompilerThread* current_thread = CompilerThread::current(); | |
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 |
237 ciInstance* ciEnv::get_or_create_exception(jobject& handle, symbolHandle name) { | |
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, | |
264 vmSymbolHandles::java_lang_ArrayIndexOutOfBoundsException()); | |
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, | |
272 vmSymbolHandles::java_lang_ArrayStoreException()); | |
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, | |
280 vmSymbolHandles::java_lang_ClassCastException()); | |
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 | |
380 symbolHandle sym(THREAD, name->get_symbolOop()); | |
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. | |
384 sym = oopFactory::new_symbol_handle(sym->as_utf8()+1, | |
385 sym->utf8_length()-2, | |
386 KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass)); | |
387 name = get_object(sym())->as_symbol(); | |
388 } | |
389 | |
390 // Check for prior unloaded klass. The SystemDictionary's answers | |
391 // can vary over time but the compiler needs consistency. | |
392 ciKlass* unloaded_klass = check_get_unloaded_klass(accessing_klass, name); | |
393 if (unloaded_klass != NULL) { | |
394 if (require_local) return NULL; | |
395 return unloaded_klass; | |
396 } | |
397 | |
398 Handle loader(THREAD, (oop)NULL); | |
399 Handle domain(THREAD, (oop)NULL); | |
400 if (accessing_klass != NULL) { | |
401 loader = Handle(THREAD, accessing_klass->loader()); | |
402 domain = Handle(THREAD, accessing_klass->protection_domain()); | |
403 } | |
404 | |
405 // setup up the proper type to return on OOM | |
406 ciKlass* fail_type; | |
407 if (sym->byte_at(0) == '[') { | |
408 fail_type = _unloaded_ciobjarrayklass; | |
409 } else { | |
410 fail_type = _unloaded_ciinstance_klass; | |
411 } | |
412 klassOop found_klass; | |
413 if (!require_local) { | |
414 found_klass = | |
415 SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, | |
416 KILL_COMPILE_ON_FATAL_(fail_type)); | |
417 } else { | |
418 found_klass = | |
419 SystemDictionary::find_instance_or_array_klass(sym, loader, domain, | |
420 KILL_COMPILE_ON_FATAL_(fail_type)); | |
421 } | |
422 | |
423 // If we fail to find an array klass, look again for its element type. | |
424 // The element type may be available either locally or via constraints. | |
425 // In either case, if we can find the element type in the system dictionary, | |
426 // we must build an array type around it. The CI requires array klasses | |
427 // to be loaded if their element klasses are loaded, except when memory | |
428 // is exhausted. | |
429 if (sym->byte_at(0) == '[' && | |
430 (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { | |
431 // We have an unloaded array. | |
432 // Build it on the fly if the element class exists. | |
433 symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1, | |
434 sym->utf8_length()-1, | |
435 KILL_COMPILE_ON_FATAL_(fail_type)); | |
436 // Get element ciKlass recursively. | |
437 ciKlass* elem_klass = | |
438 get_klass_by_name_impl(accessing_klass, | |
439 get_object(elem_sym)->as_symbol(), | |
440 require_local); | |
441 if (elem_klass != NULL && elem_klass->is_loaded()) { | |
442 // Now make an array for it | |
443 return ciObjArrayKlass::make_impl(elem_klass); | |
444 } | |
445 } | |
446 | |
447 if (found_klass != NULL) { | |
448 // Found it. Build a CI handle. | |
449 return get_object(found_klass)->as_klass(); | |
450 } | |
451 | |
452 if (require_local) return NULL; | |
453 // Not yet loaded into the VM, or not governed by loader constraints. | |
454 // Make a CI representative for it. | |
455 return get_unloaded_klass(accessing_klass, name); | |
456 } | |
457 | |
458 // ------------------------------------------------------------------ | |
459 // ciEnv::get_klass_by_name | |
460 ciKlass* ciEnv::get_klass_by_name(ciKlass* accessing_klass, | |
461 ciSymbol* klass_name, | |
462 bool require_local) { | |
463 GUARDED_VM_ENTRY(return get_klass_by_name_impl(accessing_klass, | |
464 klass_name, | |
465 require_local);) | |
466 } | |
467 | |
468 // ------------------------------------------------------------------ | |
469 // ciEnv::get_klass_by_index_impl | |
470 // | |
471 // Implementation of get_klass_by_index. | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
472 ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool, |
0 | 473 int index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
474 bool& is_accessible, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
475 ciInstanceKlass* accessor) { |
0 | 476 EXCEPTION_CONTEXT; |
477 KlassHandle klass (THREAD, constantPoolOopDesc::klass_at_if_loaded(cpool, index)); | |
478 symbolHandle klass_name; | |
479 if (klass.is_null()) { | |
480 // The klass has not been inserted into the constant pool. | |
481 // Try to look it up by name. | |
482 { | |
483 // We have to lock the cpool to keep the oop from being resolved | |
484 // while we are accessing it. | |
485 ObjectLocker ol(cpool, THREAD); | |
486 | |
487 constantTag tag = cpool->tag_at(index); | |
488 if (tag.is_klass()) { | |
489 // The klass has been inserted into the constant pool | |
490 // very recently. | |
491 klass = KlassHandle(THREAD, cpool->resolved_klass_at(index)); | |
492 } else if (tag.is_symbol()) { | |
493 klass_name = symbolHandle(THREAD, cpool->symbol_at(index)); | |
494 } else { | |
495 assert(cpool->tag_at(index).is_unresolved_klass(), "wrong tag"); | |
496 klass_name = symbolHandle(THREAD, cpool->unresolved_klass_at(index)); | |
497 } | |
498 } | |
499 } | |
500 | |
501 if (klass.is_null()) { | |
502 // Not found in constant pool. Use the name to do the lookup. | |
503 ciKlass* k = get_klass_by_name_impl(accessor, | |
504 get_object(klass_name())->as_symbol(), | |
505 false); | |
506 // Calculate accessibility the hard way. | |
507 if (!k->is_loaded()) { | |
508 is_accessible = false; | |
509 } else if (k->loader() != accessor->loader() && | |
510 get_klass_by_name_impl(accessor, k->name(), true) == NULL) { | |
511 // Loaded only remotely. Not linked yet. | |
512 is_accessible = false; | |
513 } else { | |
514 // Linked locally, and we must also check public/private, etc. | |
515 is_accessible = check_klass_accessibility(accessor, k->get_klassOop()); | |
516 } | |
517 return k; | |
518 } | |
519 | |
520 // Check for prior unloaded klass. The SystemDictionary's answers | |
521 // can vary over time but the compiler needs consistency. | |
522 ciSymbol* name = get_object(klass()->klass_part()->name())->as_symbol(); | |
523 ciKlass* unloaded_klass = check_get_unloaded_klass(accessor, name); | |
524 if (unloaded_klass != NULL) { | |
525 is_accessible = false; | |
526 return unloaded_klass; | |
527 } | |
528 | |
529 // It is known to be accessible, since it was found in the constant pool. | |
530 is_accessible = true; | |
531 return get_object(klass())->as_klass(); | |
532 } | |
533 | |
534 // ------------------------------------------------------------------ | |
535 // ciEnv::get_klass_by_index | |
536 // | |
537 // Get a klass from the constant pool. | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
538 ciKlass* ciEnv::get_klass_by_index(constantPoolHandle cpool, |
0 | 539 int index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
540 bool& is_accessible, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
541 ciInstanceKlass* accessor) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
542 GUARDED_VM_ENTRY(return get_klass_by_index_impl(cpool, index, is_accessible, accessor);) |
0 | 543 } |
544 | |
545 // ------------------------------------------------------------------ | |
546 // ciEnv::get_constant_by_index_impl | |
547 // | |
548 // Implementation of get_constant_by_index(). | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
549 ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool, |
1602 | 550 int pool_index, int cache_index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
551 ciInstanceKlass* accessor) { |
1602 | 552 bool ignore_will_link; |
0 | 553 EXCEPTION_CONTEXT; |
1602 | 554 int index = pool_index; |
555 if (cache_index >= 0) { | |
556 assert(index < 0, "only one kind of index at a time"); | |
557 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); | |
558 index = cpc_entry->constant_pool_index(); | |
559 oop obj = cpc_entry->f1(); | |
560 if (obj != NULL) { | |
561 assert(obj->is_instance(), "must be an instance"); | |
562 ciObject* ciobj = get_object(obj); | |
563 return ciConstant(T_OBJECT, ciobj); | |
564 } | |
565 } | |
0 | 566 constantTag tag = cpool->tag_at(index); |
567 if (tag.is_int()) { | |
568 return ciConstant(T_INT, (jint)cpool->int_at(index)); | |
569 } else if (tag.is_long()) { | |
570 return ciConstant((jlong)cpool->long_at(index)); | |
571 } else if (tag.is_float()) { | |
572 return ciConstant((jfloat)cpool->float_at(index)); | |
573 } else if (tag.is_double()) { | |
574 return ciConstant((jdouble)cpool->double_at(index)); | |
575 } 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
|
576 oop string = NULL; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
577 if (cpool->is_pseudo_string_at(index)) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
578 string = cpool->pseudo_string_at(index); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
579 } else { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
580 string = cpool->string_at(index, THREAD); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
581 if (HAS_PENDING_EXCEPTION) { |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
582 CLEAR_PENDING_EXCEPTION; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
583 record_out_of_memory_failure(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
584 return ciConstant(); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
0
diff
changeset
|
585 } |
0 | 586 } |
587 ciObject* constant = get_object(string); | |
588 assert (constant->is_instance(), "must be an instance, or not? "); | |
589 return ciConstant(T_OBJECT, constant); | |
590 } else if (tag.is_klass() || tag.is_unresolved_klass()) { | |
591 // 4881222: allow ldc to take a class type | |
1602 | 592 ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore_will_link, accessor); |
0 | 593 if (HAS_PENDING_EXCEPTION) { |
594 CLEAR_PENDING_EXCEPTION; | |
595 record_out_of_memory_failure(); | |
596 return ciConstant(); | |
597 } | |
598 assert (klass->is_instance_klass() || klass->is_array_klass(), | |
599 "must be an instance or array klass "); | |
1602 | 600 return ciConstant(T_OBJECT, klass->java_mirror()); |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
601 } else if (tag.is_object()) { |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
602 oop obj = cpool->object_at(index); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
603 assert(obj->is_instance(), "must be an instance"); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
604 ciObject* ciobj = get_object(obj); |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
605 return ciConstant(T_OBJECT, ciobj); |
1602 | 606 } else if (tag.is_method_type()) { |
607 // must execute Java code to link this CP entry into cache[i].f1 | |
608 ciSymbol* signature = get_object(cpool->method_type_signature_at(index))->as_symbol(); | |
609 ciObject* ciobj = get_unloaded_method_type_constant(signature); | |
610 return ciConstant(T_OBJECT, ciobj); | |
611 } else if (tag.is_method_handle()) { | |
612 // must execute Java code to link this CP entry into cache[i].f1 | |
613 int ref_kind = cpool->method_handle_ref_kind_at(index); | |
614 int callee_index = cpool->method_handle_klass_index_at(index); | |
615 ciKlass* callee = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor); | |
616 ciSymbol* name = get_object(cpool->method_handle_name_ref_at(index))->as_symbol(); | |
617 ciSymbol* signature = get_object(cpool->method_handle_signature_ref_at(index))->as_symbol(); | |
618 ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); | |
619 return ciConstant(T_OBJECT, ciobj); | |
0 | 620 } else { |
621 ShouldNotReachHere(); | |
622 return ciConstant(); | |
623 } | |
624 } | |
625 | |
626 // ------------------------------------------------------------------ | |
627 // ciEnv::get_constant_by_index | |
628 // | |
629 // Pull a constant out of the constant pool. How appropriate. | |
630 // | |
631 // 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
|
632 ciConstant ciEnv::get_constant_by_index(constantPoolHandle cpool, |
1602 | 633 int pool_index, int cache_index, |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
634 ciInstanceKlass* accessor) { |
1602 | 635 GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, pool_index, cache_index, accessor);) |
0 | 636 } |
637 | |
638 // ------------------------------------------------------------------ | |
639 // ciEnv::get_field_by_index_impl | |
640 // | |
641 // Implementation of get_field_by_index. | |
642 // | |
643 // Implementation note: the results of field lookups are cached | |
644 // in the accessor klass. | |
645 ciField* ciEnv::get_field_by_index_impl(ciInstanceKlass* accessor, | |
646 int index) { | |
647 ciConstantPoolCache* cache = accessor->field_cache(); | |
648 if (cache == NULL) { | |
649 ciField* field = new (arena()) ciField(accessor, index); | |
650 return field; | |
651 } else { | |
652 ciField* field = (ciField*)cache->get(index); | |
653 if (field == NULL) { | |
654 field = new (arena()) ciField(accessor, index); | |
655 cache->insert(index, field); | |
656 } | |
657 return field; | |
658 } | |
659 } | |
660 | |
661 // ------------------------------------------------------------------ | |
662 // ciEnv::get_field_by_index | |
663 // | |
664 // Get a field by index from a klass's constant pool. | |
665 ciField* ciEnv::get_field_by_index(ciInstanceKlass* accessor, | |
666 int index) { | |
667 GUARDED_VM_ENTRY(return get_field_by_index_impl(accessor, index);) | |
668 } | |
669 | |
670 // ------------------------------------------------------------------ | |
671 // ciEnv::lookup_method | |
672 // | |
673 // Perform an appropriate method lookup based on accessor, holder, | |
674 // name, signature, and bytecode. | |
675 methodOop ciEnv::lookup_method(instanceKlass* accessor, | |
676 instanceKlass* holder, | |
677 symbolOop name, | |
678 symbolOop sig, | |
679 Bytecodes::Code bc) { | |
680 EXCEPTION_CONTEXT; | |
681 KlassHandle h_accessor(THREAD, accessor); | |
682 KlassHandle h_holder(THREAD, holder); | |
683 symbolHandle h_name(THREAD, name); | |
684 symbolHandle h_sig(THREAD, sig); | |
685 LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL)); | |
686 methodHandle dest_method; | |
687 switch (bc) { | |
688 case Bytecodes::_invokestatic: | |
689 dest_method = | |
690 LinkResolver::resolve_static_call_or_null(h_holder, h_name, h_sig, h_accessor); | |
691 break; | |
692 case Bytecodes::_invokespecial: | |
693 dest_method = | |
694 LinkResolver::resolve_special_call_or_null(h_holder, h_name, h_sig, h_accessor); | |
695 break; | |
696 case Bytecodes::_invokeinterface: | |
697 dest_method = | |
698 LinkResolver::linktime_resolve_interface_method_or_null(h_holder, h_name, h_sig, | |
699 h_accessor, true); | |
700 break; | |
701 case Bytecodes::_invokevirtual: | |
702 dest_method = | |
703 LinkResolver::linktime_resolve_virtual_method_or_null(h_holder, h_name, h_sig, | |
704 h_accessor, true); | |
705 break; | |
706 default: ShouldNotReachHere(); | |
707 } | |
708 | |
709 return dest_method(); | |
710 } | |
711 | |
712 | |
713 // ------------------------------------------------------------------ | |
714 // ciEnv::get_method_by_index_impl | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
715 ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
716 int index, Bytecodes::Code bc, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
717 ciInstanceKlass* accessor) { |
0 | 718 int holder_index = cpool->klass_ref_index_at(index); |
719 bool holder_is_accessible; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
720 ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); |
0 | 721 ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); |
722 | |
723 // Get the method's name and signature. | |
724 symbolOop name_sym = cpool->name_ref_at(index); | |
1059
389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
jrose
parents:
989
diff
changeset
|
725 symbolOop sig_sym = cpool->signature_ref_at(index); |
0 | 726 |
727 if (holder_is_accessible) { // Our declared holder is loaded. | |
728 instanceKlass* lookup = declared_holder->get_instanceKlass(); | |
729 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); | |
730 if (m != NULL) { | |
731 // We found the method. | |
732 return get_object(m)->as_method(); | |
733 } | |
734 } | |
735 | |
736 // Either the declared holder was not loaded, or the method could | |
737 // not be found. Create a dummy ciMethod to represent the failed | |
738 // lookup. | |
739 | |
740 return get_unloaded_method(declared_holder, | |
741 get_object(name_sym)->as_symbol(), | |
742 get_object(sig_sym)->as_symbol()); | |
743 } | |
744 | |
745 | |
746 // ------------------------------------------------------------------ | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
747 // ciEnv::get_fake_invokedynamic_method_impl |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
748 ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool, |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
749 int index, Bytecodes::Code bc) { |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
750 // Compare the following logic with InterpreterRuntime::resolve_invokedynamic. |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
751 assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
752 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
753 bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
754 if (is_resolved && (oop) cpool->cache()->secondary_entry_at(index)->f1() == NULL) |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
755 // FIXME: code generation could allow for null (unlinked) call site |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
756 is_resolved = false; |
1137
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 // 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
|
759 // 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
|
760 if (!is_resolved) { |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
761 ciInstanceKlass* mh_klass = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
762 ciSymbol* sig_sym = get_object(cpool->signature_ref_at(index))->as_symbol(); |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
763 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
|
764 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
765 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
766 // Get the invoker methodOop from the constant pool. |
1662
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1602
diff
changeset
|
767 oop f1_value = cpool->cache()->main_entry_at(index)->f1(); |
e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
jrose
parents:
1602
diff
changeset
|
768 methodOop signature_invoker = methodOop(f1_value); |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
769 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
|
770 "correct result from LinkResolver::resolve_invokedynamic"); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
771 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1397
diff
changeset
|
772 return get_object(signature_invoker)->as_method(); |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
773 } |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
774 |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
775 |
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
776 // ------------------------------------------------------------------ |
0 | 777 // ciEnv::get_instance_klass_for_declared_method_holder |
778 ciInstanceKlass* ciEnv::get_instance_klass_for_declared_method_holder(ciKlass* method_holder) { | |
779 // For the case of <array>.clone(), the method holder can be a ciArrayKlass | |
780 // instead of a ciInstanceKlass. For that case simply pretend that the | |
781 // declared holder is Object.clone since that's where the call will bottom out. | |
782 // A more correct fix would trickle out through many interfaces in CI, | |
783 // requiring ciInstanceKlass* to become ciKlass* and many more places would | |
784 // require checks to make sure the expected type was found. Given that this | |
785 // only occurs for clone() the more extensive fix seems like overkill so | |
786 // instead we simply smear the array type into Object. | |
787 if (method_holder->is_instance_klass()) { | |
788 return method_holder->as_instance_klass(); | |
789 } else if (method_holder->is_array_klass()) { | |
790 return current()->Object_klass(); | |
791 } else { | |
792 ShouldNotReachHere(); | |
793 } | |
794 return NULL; | |
795 } | |
796 | |
797 | |
798 // ------------------------------------------------------------------ | |
799 // ciEnv::get_method_by_index | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
800 ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
801 int index, Bytecodes::Code bc, |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
802 ciInstanceKlass* accessor) { |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
803 if (bc == Bytecodes::_invokedynamic) { |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
804 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
|
805 } else { |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
806 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
|
807 } |
0 | 808 } |
809 | |
1137
97125851f396
6829187: compiler optimizations required for JSR 292
twisti
parents:
1080
diff
changeset
|
810 |
0 | 811 // ------------------------------------------------------------------ |
812 // ciEnv::name_buffer | |
813 char *ciEnv::name_buffer(int req_len) { | |
814 if (_name_buffer_len < req_len) { | |
815 if (_name_buffer == NULL) { | |
816 _name_buffer = (char*)arena()->Amalloc(sizeof(char)*req_len); | |
817 _name_buffer_len = req_len; | |
818 } else { | |
819 _name_buffer = | |
820 (char*)arena()->Arealloc(_name_buffer, _name_buffer_len, req_len); | |
821 _name_buffer_len = req_len; | |
822 } | |
823 } | |
824 return _name_buffer; | |
825 } | |
826 | |
827 // ------------------------------------------------------------------ | |
828 // ciEnv::is_in_vm | |
829 bool ciEnv::is_in_vm() { | |
830 return JavaThread::current()->thread_state() == _thread_in_vm; | |
831 } | |
832 | |
833 bool ciEnv::system_dictionary_modification_counter_changed() { | |
834 return _system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); | |
835 } | |
836 | |
837 // ------------------------------------------------------------------ | |
838 // ciEnv::check_for_system_dictionary_modification | |
839 // Check for changes to the system dictionary during compilation | |
840 // class loads, evolution, breakpoints | |
841 void ciEnv::check_for_system_dictionary_modification(ciMethod* target) { | |
842 if (failing()) return; // no need for further checks | |
843 | |
844 // Dependencies must be checked when the system dictionary changes. | |
845 // If logging is enabled all violated dependences will be recorded in | |
846 // the log. In debug mode check dependencies even if the system | |
847 // dictionary hasn't changed to verify that no invalid dependencies | |
848 // were inserted. Any violated dependences in this case are dumped to | |
849 // the tty. | |
850 | |
851 bool counter_changed = system_dictionary_modification_counter_changed(); | |
852 bool test_deps = counter_changed; | |
853 DEBUG_ONLY(test_deps = true); | |
854 if (!test_deps) return; | |
855 | |
856 bool print_failures = false; | |
857 DEBUG_ONLY(print_failures = !counter_changed); | |
858 | |
859 bool keep_going = (print_failures || xtty != NULL); | |
860 | |
861 int violated = 0; | |
862 | |
863 for (Dependencies::DepStream deps(dependencies()); deps.next(); ) { | |
864 klassOop witness = deps.check_dependency(); | |
865 if (witness != NULL) { | |
866 ++violated; | |
867 if (print_failures) deps.print_dependency(witness, /*verbose=*/ true); | |
868 // If there's no log and we're not sanity-checking, we're done. | |
869 if (!keep_going) break; | |
870 } | |
871 } | |
872 | |
873 if (violated != 0) { | |
874 assert(counter_changed, "failed dependencies, but counter didn't change"); | |
875 record_failure("concurrent class loading"); | |
876 } | |
877 } | |
878 | |
879 // ------------------------------------------------------------------ | |
880 // ciEnv::register_method | |
881 void ciEnv::register_method(ciMethod* target, | |
882 int entry_bci, | |
883 CodeOffsets* offsets, | |
884 int orig_pc_offset, | |
885 CodeBuffer* code_buffer, | |
886 int frame_words, | |
887 OopMapSet* oop_map_set, | |
888 ExceptionHandlerTable* handler_table, | |
889 ImplicitExceptionTable* inc_table, | |
890 AbstractCompiler* compiler, | |
891 int comp_level, | |
892 bool has_debug_info, | |
893 bool has_unsafe_access) { | |
894 VM_ENTRY_MARK; | |
895 nmethod* nm = NULL; | |
896 { | |
897 // To prevent compile queue updates. | |
898 MutexLocker locker(MethodCompileQueue_lock, THREAD); | |
899 | |
900 // Prevent SystemDictionary::add_to_hierarchy from running | |
901 // and invalidating our dependencies until we install this method. | |
902 MutexLocker ml(Compile_lock); | |
903 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
904 // 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
|
905 if (!failing() && |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
906 ( (!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
|
907 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
|
908 (!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
|
909 JvmtiExport::can_access_local_variables()) || |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
910 (!jvmti_can_post_on_exceptions() && |
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1142
diff
changeset
|
911 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
|
912 record_failure("Jvmti state change invalidated dependencies"); |
0 | 913 } |
914 | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
915 // 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
|
916 if (!failing() && |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
917 ( (!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
|
918 (!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
|
919 (!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
|
920 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
|
921 } |
0 | 922 |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
923 if (!failing()) { |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
924 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
|
925 // 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
|
926 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
|
927 } |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
928 |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
929 // 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
|
930 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
|
931 |
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
470
diff
changeset
|
932 // 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
|
933 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
|
934 } |
0 | 935 |
936 methodHandle method(THREAD, target->get_methodOop()); | |
937 | |
938 if (failing()) { | |
939 // While not a true deoptimization, it is a preemptive decompile. | |
940 methodDataOop mdo = method()->method_data(); | |
941 if (mdo != NULL) { | |
942 mdo->inc_decompile_count(); | |
943 } | |
944 | |
945 // All buffers in the CodeBuffer are allocated in the CodeCache. | |
946 // If the code buffer is created on each compile attempt | |
947 // as in C2, then it must be freed. | |
948 code_buffer->free_blob(); | |
949 return; | |
950 } | |
951 | |
952 assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry"); | |
953 assert(offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry"); | |
954 | |
955 nm = nmethod::new_nmethod(method, | |
956 compile_id(), | |
957 entry_bci, | |
958 offsets, | |
959 orig_pc_offset, | |
960 debug_info(), dependencies(), code_buffer, | |
961 frame_words, oop_map_set, | |
962 handler_table, inc_table, | |
963 compiler, comp_level); | |
964 | |
965 // Free codeBlobs | |
966 code_buffer->free_blob(); | |
967 | |
968 // stress test 6243940 by immediately making the method | |
969 // non-entrant behind the system's back. This has serious | |
970 // side effects on the code cache and is not meant for | |
971 // general stress testing | |
972 if (nm != NULL && StressNonEntrant) { | |
973 MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag); | |
974 NativeJump::patch_verified_entry(nm->entry_point(), nm->verified_entry_point(), | |
975 SharedRuntime::get_handle_wrong_method_stub()); | |
976 } | |
977 | |
978 if (nm == NULL) { | |
979 // The CodeCache is full. Print out warning and disable compilation. | |
980 record_failure("code cache is full"); | |
1202 | 981 { |
982 MutexUnlocker ml(Compile_lock); | |
983 MutexUnlocker locker(MethodCompileQueue_lock); | |
984 CompileBroker::handle_full_code_cache(); | |
0 | 985 } |
986 } else { | |
987 NOT_PRODUCT(nm->set_has_debug_info(has_debug_info); ) | |
988 nm->set_has_unsafe_access(has_unsafe_access); | |
989 | |
990 // Record successful registration. | |
991 // (Put nm into the task handle *before* publishing to the Java heap.) | |
992 if (task() != NULL) task()->set_code(nm); | |
993 | |
994 if (entry_bci == InvocationEntryBci) { | |
1783 | 995 if (TieredCompilation) { |
996 // If there is an old version we're done with it | |
997 nmethod* old = method->code(); | |
998 if (TraceMethodReplacement && old != NULL) { | |
999 ResourceMark rm; | |
1000 char *method_name = method->name_and_sig_as_C_string(); | |
1001 tty->print_cr("Replacing method %s", method_name); | |
1002 } | |
1003 if (old != NULL ) { | |
1004 old->make_not_entrant(); | |
1005 } | |
0 | 1006 } |
1007 if (TraceNMethodInstalls ) { | |
1008 ResourceMark rm; | |
1009 char *method_name = method->name_and_sig_as_C_string(); | |
1010 ttyLocker ttyl; | |
1011 tty->print_cr("Installing method (%d) %s ", | |
1012 comp_level, | |
1013 method_name); | |
1014 } | |
1015 // Allow the code to be executed | |
1016 method->set_code(method, nm); | |
1017 } else { | |
1018 if (TraceNMethodInstalls ) { | |
1019 ResourceMark rm; | |
1020 char *method_name = method->name_and_sig_as_C_string(); | |
1021 ttyLocker ttyl; | |
1022 tty->print_cr("Installing osr method (%d) %s @ %d", | |
1023 comp_level, | |
1024 method_name, | |
1025 entry_bci); | |
1026 } | |
1027 instanceKlass::cast(method->method_holder())->add_osr_nmethod(nm); | |
1028 | |
1029 } | |
1030 } | |
1031 } | |
1032 // JVMTI -- compiled method notification (must be done outside lock) | |
1033 if (nm != NULL) { | |
1034 nm->post_compiled_method_load_event(); | |
1035 } | |
1036 | |
1037 } | |
1038 | |
1039 | |
1040 // ------------------------------------------------------------------ | |
1041 // ciEnv::find_system_klass | |
1042 ciKlass* ciEnv::find_system_klass(ciSymbol* klass_name) { | |
1043 VM_ENTRY_MARK; | |
1044 return get_klass_by_name_impl(NULL, klass_name, false); | |
1045 } | |
1046 | |
1047 // ------------------------------------------------------------------ | |
1048 // ciEnv::comp_level | |
1049 int ciEnv::comp_level() { | |
1783 | 1050 if (task() == NULL) return CompLevel_highest_tier; |
0 | 1051 return task()->comp_level(); |
1052 } | |
1053 | |
1054 // ------------------------------------------------------------------ | |
1055 // ciEnv::compile_id | |
1056 uint ciEnv::compile_id() { | |
1057 if (task() == NULL) return 0; | |
1058 return task()->compile_id(); | |
1059 } | |
1060 | |
1061 // ------------------------------------------------------------------ | |
1062 // ciEnv::notice_inlined_method() | |
1063 void ciEnv::notice_inlined_method(ciMethod* method) { | |
1064 _num_inlined_bytecodes += method->code_size(); | |
1065 } | |
1066 | |
1067 // ------------------------------------------------------------------ | |
1068 // ciEnv::num_inlined_bytecodes() | |
1069 int ciEnv::num_inlined_bytecodes() const { | |
1070 return _num_inlined_bytecodes; | |
1071 } | |
1072 | |
1073 // ------------------------------------------------------------------ | |
1074 // ciEnv::record_failure() | |
1075 void ciEnv::record_failure(const char* reason) { | |
1076 if (log() != NULL) { | |
1077 log()->elem("failure reason='%s'", reason); | |
1078 } | |
1079 if (_failure_reason == NULL) { | |
1080 // Record the first failure reason. | |
1081 _failure_reason = reason; | |
1082 } | |
1083 } | |
1084 | |
1085 // ------------------------------------------------------------------ | |
1086 // ciEnv::record_method_not_compilable() | |
1087 void ciEnv::record_method_not_compilable(const char* reason, bool all_tiers) { | |
1088 int new_compilable = | |
1089 all_tiers ? MethodCompilable_never : MethodCompilable_not_at_tier ; | |
1090 | |
1091 // Only note transitions to a worse state | |
1092 if (new_compilable > _compilable) { | |
1093 if (log() != NULL) { | |
1094 if (all_tiers) { | |
1095 log()->elem("method_not_compilable"); | |
1096 } else { | |
1097 log()->elem("method_not_compilable_at_tier"); | |
1098 } | |
1099 } | |
1100 _compilable = new_compilable; | |
1101 | |
1102 // Reset failure reason; this one is more important. | |
1103 _failure_reason = NULL; | |
1104 record_failure(reason); | |
1105 } | |
1106 } | |
1107 | |
1108 // ------------------------------------------------------------------ | |
1109 // ciEnv::record_out_of_memory_failure() | |
1110 void ciEnv::record_out_of_memory_failure() { | |
1111 // If memory is low, we stop compiling methods. | |
1112 record_method_not_compilable("out of memory"); | |
1113 } |