|
1 /* |
|
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 #include "precompiled.hpp" |
|
25 #include "code/compiledIC.hpp" |
|
26 #include "compiler/compileBroker.hpp" |
|
27 #include "compiler/disassembler.hpp" |
|
28 #include "oops/oop.inline.hpp" |
|
29 #include "oops/objArrayOop.inline.hpp" |
|
30 #include "runtime/javaCalls.hpp" |
|
31 #include "jvmci/jvmciEnv.hpp" |
|
32 #include "jvmci/jvmciCompiler.hpp" |
|
33 #include "jvmci/jvmciCodeInstaller.hpp" |
|
34 #include "jvmci/jvmciJavaClasses.hpp" |
|
35 #include "jvmci/jvmciCompilerToVM.hpp" |
|
36 #include "jvmci/jvmciRuntime.hpp" |
|
37 #include "asm/register.hpp" |
|
38 #include "classfile/vmSymbols.hpp" |
|
39 #include "code/vmreg.hpp" |
|
40 |
|
41 #ifdef TARGET_ARCH_x86 |
|
42 # include "vmreg_x86.inline.hpp" |
|
43 #endif |
|
44 #ifdef TARGET_ARCH_sparc |
|
45 # include "vmreg_sparc.inline.hpp" |
|
46 #endif |
|
47 #ifdef TARGET_ARCH_zero |
|
48 # include "vmreg_zero.inline.hpp" |
|
49 #endif |
|
50 #ifdef TARGET_ARCH_arm |
|
51 # include "vmreg_arm.inline.hpp" |
|
52 #endif |
|
53 #ifdef TARGET_ARCH_ppc |
|
54 # include "vmreg_ppc.inline.hpp" |
|
55 #endif |
|
56 |
|
57 |
|
58 // frequently used constants |
|
59 // Allocate them with new so they are never destroyed (otherwise, a |
|
60 // forced exit could destroy these objects while they are still in |
|
61 // use). |
|
62 ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL); |
|
63 ConstantIntValue* CodeInstaller::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1); |
|
64 ConstantIntValue* CodeInstaller::_int_0_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0); |
|
65 ConstantIntValue* CodeInstaller::_int_1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1); |
|
66 ConstantIntValue* CodeInstaller::_int_2_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2); |
|
67 LocationValue* CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location()); |
|
68 |
|
69 Method* getMethodFromHotSpotMethod(oop hotspot_method) { |
|
70 assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass()), "sanity"); |
|
71 return CompilerToVM::asMethod(hotspot_method); |
|
72 } |
|
73 |
|
74 VMReg getVMRegFromLocation(oop location, int total_frame_size) { |
|
75 oop reg = code_Location::reg(location); |
|
76 jint offset = code_Location::offset(location); |
|
77 |
|
78 if (reg != NULL) { |
|
79 // register |
|
80 jint number = code_Register::number(reg); |
|
81 VMReg vmReg = CodeInstaller::get_hotspot_reg(number); |
|
82 assert(offset % 4 == 0, "must be aligned"); |
|
83 return vmReg->next(offset / 4); |
|
84 } else { |
|
85 // stack slot |
|
86 assert(offset % 4 == 0, "must be aligned"); |
|
87 return VMRegImpl::stack2reg(offset / 4); |
|
88 } |
|
89 } |
|
90 |
|
91 // creates a HotSpot oop map out of the byte arrays provided by DebugInfo |
|
92 OopMap* CodeInstaller::create_oop_map(oop debug_info) { |
|
93 oop reference_map = DebugInfo::referenceMap(debug_info); |
|
94 if (HotSpotReferenceMap::maxRegisterSize(reference_map) > 16) { |
|
95 _has_wide_vector = true; |
|
96 } |
|
97 OopMap* map = new OopMap(_total_frame_size, _parameter_count); |
|
98 objArrayOop objects = HotSpotReferenceMap::objects(reference_map); |
|
99 objArrayOop derivedBase = HotSpotReferenceMap::derivedBase(reference_map); |
|
100 typeArrayOop sizeInBytes = HotSpotReferenceMap::sizeInBytes(reference_map); |
|
101 for (int i = 0; i < objects->length(); i++) { |
|
102 oop location = objects->obj_at(i); |
|
103 oop baseLocation = derivedBase->obj_at(i); |
|
104 int bytes = sizeInBytes->int_at(i); |
|
105 |
|
106 VMReg vmReg = getVMRegFromLocation(location, _total_frame_size); |
|
107 if (baseLocation != NULL) { |
|
108 // derived oop |
|
109 assert(bytes == 8, "derived oop can't be compressed"); |
|
110 VMReg baseReg = getVMRegFromLocation(baseLocation, _total_frame_size); |
|
111 map->set_derived_oop(vmReg, baseReg); |
|
112 } else if (bytes == 8) { |
|
113 // wide oop |
|
114 map->set_oop(vmReg); |
|
115 } else { |
|
116 // narrow oop |
|
117 assert(bytes == 4, "wrong size"); |
|
118 map->set_narrowoop(vmReg); |
|
119 } |
|
120 } |
|
121 |
|
122 oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); |
|
123 if (callee_save_info != NULL) { |
|
124 objArrayOop registers = RegisterSaveLayout::registers(callee_save_info); |
|
125 typeArrayOop slots = RegisterSaveLayout::slots(callee_save_info); |
|
126 for (jint i = 0; i < slots->length(); i++) { |
|
127 oop jvmci_reg = registers->obj_at(i); |
|
128 jint jvmci_reg_number = code_Register::number(jvmci_reg); |
|
129 VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number); |
|
130 // HotSpot stack slots are 4 bytes |
|
131 jint jvmci_slot = slots->int_at(i); |
|
132 jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word; |
|
133 VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot); |
|
134 map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg); |
|
135 #ifdef _LP64 |
|
136 // (copied from generate_oop_map() in c1_Runtime1_x86.cpp) |
|
137 VMReg hotspot_slot_hi_as_reg = VMRegImpl::stack2reg(hotspot_slot + 1); |
|
138 map->set_callee_saved(hotspot_slot_hi_as_reg, hotspot_reg->next()); |
|
139 #endif |
|
140 } |
|
141 } |
|
142 return map; |
|
143 } |
|
144 |
|
145 static void record_metadata_reference(oop obj, jlong prim, jboolean compressed, OopRecorder* oop_recorder) { |
|
146 if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) { |
|
147 Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj)); |
|
148 if (compressed) { |
|
149 assert(Klass::decode_klass((narrowKlass) prim) == klass, err_msg("%s @ " INTPTR_FORMAT " != " PTR64_FORMAT, klass->name()->as_C_string(), p2i(klass), prim)); |
|
150 } else { |
|
151 assert((Klass*) prim == klass, err_msg("%s @ " INTPTR_FORMAT " != " PTR64_FORMAT, klass->name()->as_C_string(), p2i(klass), prim)); |
|
152 } |
|
153 int index = oop_recorder->find_index(klass); |
|
154 TRACE_jvmci_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string()); |
|
155 } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) { |
|
156 Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj); |
|
157 assert(!compressed, err_msg("unexpected compressed method pointer %s @ " INTPTR_FORMAT " = " PTR64_FORMAT, method->name()->as_C_string(), p2i(method), prim)); |
|
158 int index = oop_recorder->find_index(method); |
|
159 TRACE_jvmci_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string()); |
|
160 } else { |
|
161 assert(java_lang_String::is_instance(obj), |
|
162 err_msg("unexpected metadata reference (%s) for constant " JLONG_FORMAT " (" PTR64_FORMAT ")", obj->klass()->name()->as_C_string(), prim, prim)); |
|
163 } |
|
164 } |
|
165 |
|
166 // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectTypeImpl.klass()). |
|
167 static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) { |
|
168 if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { |
|
169 oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant); |
|
170 jlong prim = HotSpotMetaspaceConstantImpl::primitive(constant); |
|
171 assert(obj != NULL, "must have an object"); |
|
172 assert(prim != 0, "must have a primitive value"); |
|
173 |
|
174 record_metadata_reference(obj, prim, false, oop_recorder); |
|
175 } |
|
176 } |
|
177 |
|
178 static void record_metadata_in_patch(Handle& constant, OopRecorder* oop_recorder) { |
|
179 record_metadata_reference(HotSpotMetaspaceConstantImpl::metaspaceObject(constant), HotSpotMetaspaceConstantImpl::primitive(constant), HotSpotMetaspaceConstantImpl::compressed(constant), oop_recorder); |
|
180 } |
|
181 |
|
182 Location::Type CodeInstaller::get_oop_type(oop value) { |
|
183 oop lirKind = Value::lirKind(value); |
|
184 oop platformKind = LIRKind::platformKind(lirKind); |
|
185 assert(LIRKind::referenceMask(lirKind) == 1, "unexpected referenceMask"); |
|
186 |
|
187 if (platformKind == word_kind()) { |
|
188 return Location::oop; |
|
189 } else { |
|
190 return Location::narrowoop; |
|
191 } |
|
192 } |
|
193 |
|
194 ScopeValue* CodeInstaller::get_scope_value(oop value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) { |
|
195 second = NULL; |
|
196 if (value == Value::ILLEGAL()) { |
|
197 assert(type == T_ILLEGAL, "expected legal value"); |
|
198 return _illegal_value; |
|
199 } else if (value->is_a(RegisterValue::klass())) { |
|
200 oop reg = RegisterValue::reg(value); |
|
201 jint number = code_Register::number(reg); |
|
202 VMReg hotspotRegister = get_hotspot_reg(number); |
|
203 if (is_general_purpose_reg(hotspotRegister)) { |
|
204 Location::Type locationType; |
|
205 if (type == T_OBJECT) { |
|
206 locationType = get_oop_type(value); |
|
207 } else if (type == T_LONG) { |
|
208 locationType = Location::lng; |
|
209 } else { |
|
210 assert(type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN, "unexpected type in cpu register"); |
|
211 locationType = Location::int_in_long; |
|
212 } |
|
213 ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister)); |
|
214 if (type == T_LONG) { |
|
215 second = value; |
|
216 } |
|
217 return value; |
|
218 } else { |
|
219 assert(type == T_FLOAT || type == T_DOUBLE, "only float and double expected in xmm register"); |
|
220 Location::Type locationType; |
|
221 if (type == T_FLOAT) { |
|
222 // this seems weird, but the same value is used in c1_LinearScan |
|
223 locationType = Location::normal; |
|
224 } else { |
|
225 locationType = Location::dbl; |
|
226 } |
|
227 ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, hotspotRegister)); |
|
228 if (type == T_DOUBLE) { |
|
229 second = value; |
|
230 } |
|
231 return value; |
|
232 } |
|
233 } else if (value->is_a(StackSlot::klass())) { |
|
234 jint offset = StackSlot::offset(value); |
|
235 if (StackSlot::addFrameSize(value)) { |
|
236 offset += _total_frame_size; |
|
237 } |
|
238 |
|
239 Location::Type locationType; |
|
240 if (type == T_OBJECT) { |
|
241 locationType = get_oop_type(value); |
|
242 } else if (type == T_LONG) { |
|
243 locationType = Location::lng; |
|
244 } else if (type == T_DOUBLE) { |
|
245 locationType = Location::dbl; |
|
246 } else { |
|
247 assert(type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN, "unexpected type in stack slot"); |
|
248 locationType = Location::normal; |
|
249 } |
|
250 ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset)); |
|
251 if (type == T_DOUBLE || type == T_LONG) { |
|
252 second = value; |
|
253 } |
|
254 return value; |
|
255 } else if (value->is_a(JavaConstant::klass())) { |
|
256 record_metadata_in_constant(value, _oop_recorder); |
|
257 if (value->is_a(PrimitiveConstant::klass())) { |
|
258 if (value->is_a(RawConstant::klass())) { |
|
259 jlong prim = PrimitiveConstant::primitive(value); |
|
260 return new ConstantLongValue(prim); |
|
261 } else { |
|
262 assert(type == JVMCIRuntime::kindToBasicType(JavaKind::typeChar(PrimitiveConstant::kind(value))), "primitive constant type doesn't match"); |
|
263 if (type == T_INT || type == T_FLOAT) { |
|
264 jint prim = (jint)PrimitiveConstant::primitive(value); |
|
265 switch (prim) { |
|
266 case -1: return _int_m1_scope_value; |
|
267 case 0: return _int_0_scope_value; |
|
268 case 1: return _int_1_scope_value; |
|
269 case 2: return _int_2_scope_value; |
|
270 default: return new ConstantIntValue(prim); |
|
271 } |
|
272 } else { |
|
273 assert(type == T_LONG || type == T_DOUBLE, "unexpected primitive constant type"); |
|
274 jlong prim = PrimitiveConstant::primitive(value); |
|
275 second = _int_1_scope_value; |
|
276 return new ConstantLongValue(prim); |
|
277 } |
|
278 } |
|
279 } else { |
|
280 assert(type == T_OBJECT, "unexpected object constant"); |
|
281 if (value->is_a(NullConstant::klass()) || value->is_a(HotSpotCompressedNullConstant::klass())) { |
|
282 return _oop_null_scope_value; |
|
283 } else { |
|
284 assert(value->is_a(HotSpotObjectConstantImpl::klass()), "unexpected constant type"); |
|
285 oop obj = HotSpotObjectConstantImpl::object(value); |
|
286 assert(obj != NULL, "null value must be in NullConstant"); |
|
287 return new ConstantOopWriteValue(JNIHandles::make_local(obj)); |
|
288 } |
|
289 } |
|
290 } else if (value->is_a(VirtualObject::klass())) { |
|
291 assert(type == T_OBJECT, "unexpected virtual object"); |
|
292 int id = VirtualObject::id(value); |
|
293 ScopeValue* object = objects->at(id); |
|
294 assert(object != NULL, "missing value"); |
|
295 return object; |
|
296 } else { |
|
297 value->klass()->print(); |
|
298 value->print(); |
|
299 } |
|
300 ShouldNotReachHere(); |
|
301 return NULL; |
|
302 } |
|
303 |
|
304 void CodeInstaller::record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects) { |
|
305 oop type = VirtualObject::type(value); |
|
306 int id = VirtualObject::id(value); |
|
307 oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); |
|
308 Klass* klass = java_lang_Class::as_Klass(javaMirror); |
|
309 bool isLongArray = klass == Universe::longArrayKlassObj(); |
|
310 |
|
311 objArrayOop values = VirtualObject::values(value); |
|
312 objArrayOop slotKinds = VirtualObject::slotKinds(value); |
|
313 for (jint i = 0; i < values->length(); i++) { |
|
314 ScopeValue* cur_second = NULL; |
|
315 oop object = values->obj_at(i); |
|
316 oop kind = slotKinds->obj_at(i); |
|
317 BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind)); |
|
318 ScopeValue* value = get_scope_value(object, type, objects, cur_second); |
|
319 |
|
320 if (isLongArray && cur_second == NULL) { |
|
321 // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. |
|
322 // add an int 0 constant |
|
323 cur_second = _int_0_scope_value; |
|
324 } |
|
325 |
|
326 if (cur_second != NULL) { |
|
327 sv->field_values()->append(cur_second); |
|
328 } |
|
329 assert(value != NULL, "missing value"); |
|
330 sv->field_values()->append(value); |
|
331 } |
|
332 } |
|
333 |
|
334 MonitorValue* CodeInstaller::get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects) { |
|
335 guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type StackLockValue"); |
|
336 |
|
337 ScopeValue* second = NULL; |
|
338 ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), T_OBJECT, objects, second); |
|
339 assert(second == NULL, "monitor cannot occupy two stack slots"); |
|
340 |
|
341 ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), T_LONG, objects, second); |
|
342 assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); |
|
343 assert(lock_data_value->is_location(), "invalid monitor location"); |
|
344 Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); |
|
345 |
|
346 bool eliminated = false; |
|
347 if (StackLockValue::eliminated(value)) { |
|
348 eliminated = true; |
|
349 } |
|
350 |
|
351 return new MonitorValue(owner_value, lock_data_loc, eliminated); |
|
352 } |
|
353 |
|
354 void CodeInstaller::initialize_dependencies(oop compiled_code, OopRecorder* recorder) { |
|
355 JavaThread* thread = JavaThread::current(); |
|
356 CompilerThread* compilerThread = thread->is_Compiler_thread() ? thread->as_CompilerThread() : NULL; |
|
357 _oop_recorder = recorder; |
|
358 _dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != NULL ? compilerThread->log() : NULL); |
|
359 objArrayHandle assumptions = HotSpotCompiledCode::assumptions(compiled_code); |
|
360 if (!assumptions.is_null()) { |
|
361 int length = assumptions->length(); |
|
362 for (int i = 0; i < length; ++i) { |
|
363 Handle assumption = assumptions->obj_at(i); |
|
364 if (!assumption.is_null()) { |
|
365 if (assumption->klass() == Assumptions_NoFinalizableSubclass::klass()) { |
|
366 assumption_NoFinalizableSubclass(assumption); |
|
367 } else if (assumption->klass() == Assumptions_ConcreteSubtype::klass()) { |
|
368 assumption_ConcreteSubtype(assumption); |
|
369 } else if (assumption->klass() == Assumptions_LeafType::klass()) { |
|
370 assumption_LeafType(assumption); |
|
371 } else if (assumption->klass() == Assumptions_ConcreteMethod::klass()) { |
|
372 assumption_ConcreteMethod(assumption); |
|
373 } else if (assumption->klass() == Assumptions_CallSiteTargetValue::klass()) { |
|
374 assumption_CallSiteTargetValue(assumption); |
|
375 } else { |
|
376 assumption->print(); |
|
377 fatal("unexpected Assumption subclass"); |
|
378 } |
|
379 } |
|
380 } |
|
381 } |
|
382 objArrayHandle methods = HotSpotCompiledCode::methods(compiled_code); |
|
383 if (!methods.is_null()) { |
|
384 int length = methods->length(); |
|
385 for (int i = 0; i < length; ++i) { |
|
386 Handle method_handle = methods->obj_at(i); |
|
387 methodHandle method = getMethodFromHotSpotMethod(method_handle()); |
|
388 |
|
389 _dependencies->assert_evol_method(method()); |
|
390 } |
|
391 } |
|
392 } |
|
393 |
|
394 RelocBuffer::~RelocBuffer() { |
|
395 if (_buffer != NULL) { |
|
396 FREE_C_HEAP_ARRAY(char, _buffer); |
|
397 } |
|
398 } |
|
399 |
|
400 address RelocBuffer::begin() const { |
|
401 if (_buffer != NULL) { |
|
402 return (address) _buffer; |
|
403 } |
|
404 return (address) _static_buffer; |
|
405 } |
|
406 |
|
407 void RelocBuffer::set_size(size_t bytes) { |
|
408 assert(bytes <= _size, "can't grow in size!"); |
|
409 _size = bytes; |
|
410 } |
|
411 |
|
412 void RelocBuffer::ensure_size(size_t bytes) { |
|
413 assert(_buffer == NULL, "can only be used once"); |
|
414 assert(_size == 0, "can only be used once"); |
|
415 if (bytes >= RelocBuffer::stack_size) { |
|
416 _buffer = NEW_C_HEAP_ARRAY(char, bytes, mtInternal); |
|
417 } |
|
418 _size = bytes; |
|
419 } |
|
420 |
|
421 JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle& compiled_code, CodeMetadata& metadata) { |
|
422 CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata"); |
|
423 jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); |
|
424 initialize_dependencies(JNIHandles::resolve(compiled_code_obj), NULL); |
|
425 |
|
426 // Get instructions and constants CodeSections early because we need it. |
|
427 _instructions = buffer.insts(); |
|
428 _constants = buffer.consts(); |
|
429 |
|
430 initialize_fields(target(), JNIHandles::resolve(compiled_code_obj)); |
|
431 if (!initialize_buffer(buffer)) { |
|
432 return JVMCIEnv::code_too_large; |
|
433 } |
|
434 process_exception_handlers(); |
|
435 |
|
436 _debug_recorder->pcs_size(); // ehm, create the sentinel record |
|
437 |
|
438 assert(_debug_recorder->pcs_length() >= 2, "must be at least 2"); |
|
439 |
|
440 metadata.set_pc_desc(_debug_recorder->pcs(), _debug_recorder->pcs_length()); |
|
441 metadata.set_scopes(_debug_recorder->stream()->buffer(), _debug_recorder->data_size()); |
|
442 metadata.set_exception_table(&_exception_handler_table); |
|
443 |
|
444 RelocBuffer* reloc_buffer = metadata.get_reloc_buffer(); |
|
445 |
|
446 reloc_buffer->ensure_size(buffer.total_relocation_size()); |
|
447 size_t size = (size_t) buffer.copy_relocations_to(reloc_buffer->begin(), (CodeBuffer::csize_t) reloc_buffer->size(), true); |
|
448 reloc_buffer->set_size(size); |
|
449 return JVMCIEnv::ok; |
|
450 } |
|
451 |
|
452 // constructor used to create a method |
|
453 JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Handle target, Handle& compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log) { |
|
454 CodeBuffer buffer("JVMCI Compiler CodeBuffer"); |
|
455 jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); |
|
456 OopRecorder* recorder = new OopRecorder(&_arena, true); |
|
457 initialize_dependencies(JNIHandles::resolve(compiled_code_obj), recorder); |
|
458 |
|
459 // Get instructions and constants CodeSections early because we need it. |
|
460 _instructions = buffer.insts(); |
|
461 _constants = buffer.consts(); |
|
462 |
|
463 initialize_fields(target(), JNIHandles::resolve(compiled_code_obj)); |
|
464 JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer); |
|
465 if (result != JVMCIEnv::ok) { |
|
466 return result; |
|
467 } |
|
468 process_exception_handlers(); |
|
469 |
|
470 int stack_slots = _total_frame_size / HeapWordSize; // conversion to words |
|
471 |
|
472 if (!compiled_code->is_a(HotSpotCompiledNmethod::klass())) { |
|
473 oop stubName = HotSpotCompiledCode::name(compiled_code_obj); |
|
474 char* name = strdup(java_lang_String::as_utf8_string(stubName)); |
|
475 cb = RuntimeStub::new_runtime_stub(name, |
|
476 &buffer, |
|
477 CodeOffsets::frame_never_safe, |
|
478 stack_slots, |
|
479 _debug_recorder->_oopmaps, |
|
480 false); |
|
481 result = JVMCIEnv::ok; |
|
482 } else { |
|
483 nmethod* nm = NULL; |
|
484 methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code)); |
|
485 jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code); |
|
486 jint id = HotSpotCompiledNmethod::id(compiled_code); |
|
487 bool has_unsafe_access = HotSpotCompiledNmethod::hasUnsafeAccess(compiled_code) == JNI_TRUE; |
|
488 JVMCIEnv* env = (JVMCIEnv*) (address) HotSpotCompiledNmethod::jvmciEnv(compiled_code); |
|
489 if (id == -1) { |
|
490 // Make sure a valid compile_id is associated with every compile |
|
491 id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci); |
|
492 } |
|
493 result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, |
|
494 stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, |
|
495 compiler, _debug_recorder, _dependencies, env, id, |
|
496 has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log); |
|
497 cb = nm; |
|
498 } |
|
499 |
|
500 if (cb != NULL) { |
|
501 // Make sure the pre-calculated constants section size was correct. |
|
502 guarantee((cb->code_begin() - cb->content_begin()) >= _constants_size, err_msg("%d < %d", (int)(cb->code_begin() - cb->content_begin()), _constants_size)); |
|
503 } |
|
504 return result; |
|
505 } |
|
506 |
|
507 void CodeInstaller::initialize_fields(oop target, oop compiled_code) { |
|
508 if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) { |
|
509 Handle hotspotJavaMethod = HotSpotCompiledNmethod::method(compiled_code); |
|
510 methodHandle method = getMethodFromHotSpotMethod(hotspotJavaMethod()); |
|
511 _parameter_count = method->size_of_parameters(); |
|
512 TRACE_jvmci_2("installing code for %s", method->name_and_sig_as_C_string()); |
|
513 } else { |
|
514 // Must be a HotSpotCompiledRuntimeStub. |
|
515 // Only used in OopMap constructor for non-product builds |
|
516 _parameter_count = 0; |
|
517 } |
|
518 _sites_handle = JNIHandles::make_local(HotSpotCompiledCode::sites(compiled_code)); |
|
519 _exception_handlers_handle = JNIHandles::make_local(HotSpotCompiledCode::exceptionHandlers(compiled_code)); |
|
520 |
|
521 _code_handle = JNIHandles::make_local(HotSpotCompiledCode::targetCode(compiled_code)); |
|
522 _code_size = HotSpotCompiledCode::targetCodeSize(compiled_code); |
|
523 _total_frame_size = HotSpotCompiledCode::totalFrameSize(compiled_code); |
|
524 _custom_stack_area_offset = HotSpotCompiledCode::customStackAreaOffset(compiled_code); |
|
525 |
|
526 // Pre-calculate the constants section size. This is required for PC-relative addressing. |
|
527 _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code)); |
|
528 guarantee(HotSpotCompiledCode::dataSectionAlignment(compiled_code) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); |
|
529 _constants_size = data_section()->length(); |
|
530 |
|
531 _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code)); |
|
532 |
|
533 #ifndef PRODUCT |
|
534 _comments_handle = JNIHandles::make_local(HotSpotCompiledCode::comments(compiled_code)); |
|
535 #endif |
|
536 |
|
537 _next_call_type = INVOKE_INVALID; |
|
538 |
|
539 _has_wide_vector = false; |
|
540 |
|
541 oop arch = TargetDescription::arch(target); |
|
542 _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch)); |
|
543 } |
|
544 |
|
545 int CodeInstaller::estimate_stubs_size() { |
|
546 // Return size for all stubs. |
|
547 int static_call_stubs = 0; |
|
548 objArrayOop sites = this->sites(); |
|
549 for (int i = 0; i < sites->length(); i++) { |
|
550 oop site = sites->obj_at(i); |
|
551 if (site->is_a(CompilationResult_Mark::klass())) { |
|
552 oop id_obj = CompilationResult_Mark::id(site); |
|
553 if (id_obj != NULL) { |
|
554 assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); |
|
555 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); |
|
556 if (id == INVOKESTATIC || id == INVOKESPECIAL) { |
|
557 static_call_stubs++; |
|
558 } |
|
559 } |
|
560 } |
|
561 } |
|
562 return static_call_stubs * CompiledStaticCall::to_interp_stub_size(); |
|
563 } |
|
564 |
|
565 // perform data and call relocation on the CodeBuffer |
|
566 JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer) { |
|
567 objArrayHandle sites = this->sites(); |
|
568 int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo)); |
|
569 |
|
570 // Allocate enough space in the stub section for the static call |
|
571 // stubs. Stubs have extra relocs but they are managed by the stub |
|
572 // section itself so they don't need to be accounted for in the |
|
573 // locs_buffer above. |
|
574 int stubs_size = estimate_stubs_size(); |
|
575 int total_size = round_to(_code_size, buffer.insts()->alignment()) + round_to(_constants_size, buffer.consts()->alignment()) + round_to(stubs_size, buffer.stubs()->alignment()); |
|
576 |
|
577 if (total_size > JVMCINMethodSizeLimit) { |
|
578 return JVMCIEnv::code_too_large; |
|
579 } |
|
580 |
|
581 buffer.initialize(total_size, locs_buffer_size); |
|
582 if (buffer.blob() == NULL) { |
|
583 return JVMCIEnv::cache_full; |
|
584 } |
|
585 buffer.initialize_stubs_size(stubs_size); |
|
586 buffer.initialize_consts_size(_constants_size); |
|
587 |
|
588 _debug_recorder = new DebugInformationRecorder(_oop_recorder); |
|
589 _debug_recorder->set_oopmaps(new OopMapSet()); |
|
590 |
|
591 buffer.initialize_oop_recorder(_oop_recorder); |
|
592 |
|
593 // copy the constant data into the newly created CodeBuffer |
|
594 address end_data = _constants->start() + _constants_size; |
|
595 memcpy(_constants->start(), data_section()->base(T_BYTE), _constants_size); |
|
596 _constants->set_end(end_data); |
|
597 |
|
598 // copy the code into the newly created CodeBuffer |
|
599 address end_pc = _instructions->start() + _code_size; |
|
600 guarantee(_instructions->allocates2(end_pc), "initialize should have reserved enough space for all the code"); |
|
601 memcpy(_instructions->start(), code()->base(T_BYTE), _code_size); |
|
602 _instructions->set_end(end_pc); |
|
603 |
|
604 for (int i = 0; i < data_section_patches()->length(); i++) { |
|
605 Handle patch = data_section_patches()->obj_at(i); |
|
606 Handle reference = CompilationResult_DataPatch::reference(patch); |
|
607 assert(reference->is_a(CompilationResult_ConstantReference::klass()), err_msg("patch in data section must be a ConstantReference")); |
|
608 Handle constant = CompilationResult_ConstantReference::constant(reference); |
|
609 if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { |
|
610 record_metadata_in_patch(constant, _oop_recorder); |
|
611 } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) { |
|
612 Handle obj = HotSpotObjectConstantImpl::object(constant); |
|
613 jobject value = JNIHandles::make_local(obj()); |
|
614 int oop_index = _oop_recorder->find_index(value); |
|
615 |
|
616 address dest = _constants->start() + CompilationResult_Site::pcOffset(patch); |
|
617 if (HotSpotObjectConstantImpl::compressed(constant)) { |
|
618 #ifdef _LP64 |
|
619 _constants->relocate(dest, oop_Relocation::spec(oop_index), relocInfo::narrow_oop_in_const); |
|
620 #else |
|
621 fatal("unexpected compressed oop in 32-bit mode"); |
|
622 #endif |
|
623 } else { |
|
624 _constants->relocate(dest, oop_Relocation::spec(oop_index)); |
|
625 } |
|
626 } else { |
|
627 ShouldNotReachHere(); |
|
628 } |
|
629 } |
|
630 jint last_pc_offset = -1; |
|
631 for (int i = 0; i < sites->length(); i++) { |
|
632 { |
|
633 No_Safepoint_Verifier no_safepoint; |
|
634 oop site = sites->obj_at(i); |
|
635 jint pc_offset = CompilationResult_Site::pcOffset(site); |
|
636 |
|
637 if (site->is_a(CompilationResult_Call::klass())) { |
|
638 TRACE_jvmci_4("call at %i", pc_offset); |
|
639 site_Call(buffer, pc_offset, site); |
|
640 } else if (site->is_a(CompilationResult_Infopoint::klass())) { |
|
641 // three reasons for infopoints denote actual safepoints |
|
642 oop reason = CompilationResult_Infopoint::reason(site); |
|
643 if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) { |
|
644 TRACE_jvmci_4("safepoint at %i", pc_offset); |
|
645 site_Safepoint(buffer, pc_offset, site); |
|
646 } else { |
|
647 // if the infopoint is not an actual safepoint, it must have one of the other reasons |
|
648 // (safeguard against new safepoint types that require handling above) |
|
649 assert(InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason, ""); |
|
650 site_Infopoint(buffer, pc_offset, site); |
|
651 } |
|
652 } else if (site->is_a(CompilationResult_DataPatch::klass())) { |
|
653 TRACE_jvmci_4("datapatch at %i", pc_offset); |
|
654 site_DataPatch(buffer, pc_offset, site); |
|
655 } else if (site->is_a(CompilationResult_Mark::klass())) { |
|
656 TRACE_jvmci_4("mark at %i", pc_offset); |
|
657 site_Mark(buffer, pc_offset, site); |
|
658 } else { |
|
659 fatal("unexpected Site subclass"); |
|
660 } |
|
661 last_pc_offset = pc_offset; |
|
662 } |
|
663 if (CodeInstallSafepointChecks && SafepointSynchronize::do_call_back()) { |
|
664 // this is a hacky way to force a safepoint check but nothing else was jumping out at me. |
|
665 ThreadToNativeFromVM ttnfv(JavaThread::current()); |
|
666 } |
|
667 } |
|
668 |
|
669 #ifndef PRODUCT |
|
670 if (comments() != NULL) { |
|
671 No_Safepoint_Verifier no_safepoint; |
|
672 for (int i = 0; i < comments()->length(); i++) { |
|
673 oop comment = comments()->obj_at(i); |
|
674 assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce"); |
|
675 jint offset = HotSpotCompiledCode_Comment::pcOffset(comment); |
|
676 char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment)); |
|
677 buffer.block_comment(offset, text); |
|
678 } |
|
679 } |
|
680 #endif |
|
681 return JVMCIEnv::ok; |
|
682 } |
|
683 |
|
684 void CodeInstaller::assumption_NoFinalizableSubclass(Handle assumption) { |
|
685 Handle receiverType_handle = Assumptions_NoFinalizableSubclass::receiverType(assumption()); |
|
686 Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(receiverType_handle)); |
|
687 _dependencies->assert_has_no_finalizable_subclasses(receiverType); |
|
688 } |
|
689 |
|
690 void CodeInstaller::assumption_ConcreteSubtype(Handle assumption) { |
|
691 Handle context_handle = Assumptions_ConcreteSubtype::context(assumption()); |
|
692 Handle subtype_handle = Assumptions_ConcreteSubtype::subtype(assumption()); |
|
693 Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle)); |
|
694 Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(subtype_handle)); |
|
695 |
|
696 assert(context->is_abstract(), ""); |
|
697 _dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype); |
|
698 } |
|
699 |
|
700 void CodeInstaller::assumption_LeafType(Handle assumption) { |
|
701 Handle context_handle = Assumptions_LeafType::context(assumption()); |
|
702 Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle)); |
|
703 |
|
704 _dependencies->assert_leaf_type(context); |
|
705 } |
|
706 |
|
707 void CodeInstaller::assumption_ConcreteMethod(Handle assumption) { |
|
708 Handle impl_handle = Assumptions_ConcreteMethod::impl(assumption()); |
|
709 Handle context_handle = Assumptions_ConcreteMethod::context(assumption()); |
|
710 |
|
711 methodHandle impl = getMethodFromHotSpotMethod(impl_handle()); |
|
712 Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle)); |
|
713 |
|
714 _dependencies->assert_unique_concrete_method(context, impl()); |
|
715 } |
|
716 |
|
717 void CodeInstaller::assumption_CallSiteTargetValue(Handle assumption) { |
|
718 Handle callSite = Assumptions_CallSiteTargetValue::callSite(assumption()); |
|
719 Handle methodHandle = Assumptions_CallSiteTargetValue::methodHandle(assumption()); |
|
720 |
|
721 _dependencies->assert_call_site_target_value(callSite(), methodHandle()); |
|
722 } |
|
723 |
|
724 void CodeInstaller::process_exception_handlers() { |
|
725 if (exception_handlers() != NULL) { |
|
726 objArrayOop handlers = exception_handlers(); |
|
727 for (int i = 0; i < handlers->length(); i++) { |
|
728 oop exc = handlers->obj_at(i); |
|
729 jint pc_offset = CompilationResult_Site::pcOffset(exc); |
|
730 jint handler_offset = CompilationResult_ExceptionHandler::handlerPos(exc); |
|
731 |
|
732 // Subtable header |
|
733 _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0)); |
|
734 |
|
735 // Subtable entry |
|
736 _exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0)); |
|
737 } |
|
738 } |
|
739 } |
|
740 |
|
741 // If deoptimization happens, the interpreter should reexecute these bytecodes. |
|
742 // This function mainly helps the compilers to set up the reexecute bit. |
|
743 static bool bytecode_should_reexecute(Bytecodes::Code code) { |
|
744 switch (code) { |
|
745 case Bytecodes::_invokedynamic: |
|
746 case Bytecodes::_invokevirtual: |
|
747 case Bytecodes::_invokeinterface: |
|
748 case Bytecodes::_invokespecial: |
|
749 case Bytecodes::_invokestatic: |
|
750 return false; |
|
751 default: |
|
752 return true; |
|
753 } |
|
754 return true; |
|
755 } |
|
756 |
|
757 GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(oop debug_info) { |
|
758 objArrayOop virtualObjects = DebugInfo::virtualObjectMapping(debug_info); |
|
759 if (virtualObjects == NULL) { |
|
760 return NULL; |
|
761 } |
|
762 GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(virtualObjects->length(), virtualObjects->length(), NULL); |
|
763 // Create the unique ObjectValues |
|
764 for (int i = 0; i < virtualObjects->length(); i++) { |
|
765 oop value = virtualObjects->obj_at(i); |
|
766 int id = VirtualObject::id(value); |
|
767 oop type = VirtualObject::type(value); |
|
768 oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); |
|
769 ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror))); |
|
770 assert(objects->at(id) == NULL, "once"); |
|
771 objects->at_put(id, sv); |
|
772 } |
|
773 // All the values which could be referenced by the VirtualObjects |
|
774 // exist, so now describe all the VirtualObjects themselves. |
|
775 for (int i = 0; i < virtualObjects->length(); i++) { |
|
776 oop value = virtualObjects->obj_at(i); |
|
777 int id = VirtualObject::id(value); |
|
778 record_object_value(objects->at(id)->as_ObjectValue(), value, objects); |
|
779 } |
|
780 _debug_recorder->dump_object_pool(objects); |
|
781 return objects; |
|
782 } |
|
783 |
|
784 void CodeInstaller::record_scope(jint pc_offset, oop debug_info) { |
|
785 oop position = DebugInfo::bytecodePosition(debug_info); |
|
786 if (position == NULL) { |
|
787 // Stubs do not record scope info, just oop maps |
|
788 return; |
|
789 } |
|
790 |
|
791 GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info); |
|
792 record_scope(pc_offset, position, objectMapping); |
|
793 } |
|
794 |
|
795 void CodeInstaller::record_scope(jint pc_offset, oop position, GrowableArray<ScopeValue*>* objects) { |
|
796 oop frame = NULL; |
|
797 if (position->is_a(BytecodeFrame::klass())) { |
|
798 frame = position; |
|
799 } |
|
800 oop caller_frame = BytecodePosition::caller(position); |
|
801 if (caller_frame != NULL) { |
|
802 record_scope(pc_offset, caller_frame, objects); |
|
803 } |
|
804 |
|
805 oop hotspot_method = BytecodePosition::method(position); |
|
806 Method* method = getMethodFromHotSpotMethod(hotspot_method); |
|
807 jint bci = BytecodePosition::bci(position); |
|
808 if (bci == BytecodeFrame::BEFORE_BCI()) { |
|
809 bci = SynchronizationEntryBCI; |
|
810 } |
|
811 |
|
812 TRACE_jvmci_2("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string()); |
|
813 |
|
814 bool reexecute = false; |
|
815 if (frame != NULL) { |
|
816 if (bci == SynchronizationEntryBCI){ |
|
817 reexecute = false; |
|
818 } else { |
|
819 Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci)); |
|
820 reexecute = bytecode_should_reexecute(code); |
|
821 if (frame != NULL) { |
|
822 reexecute = (BytecodeFrame::duringCall(frame) == JNI_FALSE); |
|
823 } |
|
824 } |
|
825 } |
|
826 |
|
827 DebugToken* locals_token = NULL; |
|
828 DebugToken* expressions_token = NULL; |
|
829 DebugToken* monitors_token = NULL; |
|
830 bool throw_exception = false; |
|
831 |
|
832 if (frame != NULL) { |
|
833 jint local_count = BytecodeFrame::numLocals(frame); |
|
834 jint expression_count = BytecodeFrame::numStack(frame); |
|
835 jint monitor_count = BytecodeFrame::numLocks(frame); |
|
836 objArrayOop values = BytecodeFrame::values(frame); |
|
837 objArrayOop slotKinds = BytecodeFrame::slotKinds(frame); |
|
838 |
|
839 assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); |
|
840 assert(local_count + expression_count == slotKinds->length(), "unexpected slotKinds length"); |
|
841 |
|
842 GrowableArray<ScopeValue*>* locals = local_count > 0 ? new GrowableArray<ScopeValue*> (local_count) : NULL; |
|
843 GrowableArray<ScopeValue*>* expressions = expression_count > 0 ? new GrowableArray<ScopeValue*> (expression_count) : NULL; |
|
844 GrowableArray<MonitorValue*>* monitors = monitor_count > 0 ? new GrowableArray<MonitorValue*> (monitor_count) : NULL; |
|
845 |
|
846 TRACE_jvmci_2("Scope at bci %d with %d values", bci, values->length()); |
|
847 TRACE_jvmci_2("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count); |
|
848 |
|
849 for (jint i = 0; i < values->length(); i++) { |
|
850 ScopeValue* second = NULL; |
|
851 oop value = values->obj_at(i); |
|
852 if (i < local_count) { |
|
853 oop kind = slotKinds->obj_at(i); |
|
854 BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind)); |
|
855 ScopeValue* first = get_scope_value(value, type, objects, second); |
|
856 if (second != NULL) { |
|
857 locals->append(second); |
|
858 } |
|
859 locals->append(first); |
|
860 } else if (i < local_count + expression_count) { |
|
861 oop kind = slotKinds->obj_at(i); |
|
862 BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(kind)); |
|
863 ScopeValue* first = get_scope_value(value, type, objects, second); |
|
864 if (second != NULL) { |
|
865 expressions->append(second); |
|
866 } |
|
867 expressions->append(first); |
|
868 } else { |
|
869 monitors->append(get_monitor_value(value, objects)); |
|
870 } |
|
871 if (second != NULL) { |
|
872 i++; |
|
873 assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL"); |
|
874 assert(values->obj_at(i) == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); |
|
875 } |
|
876 } |
|
877 |
|
878 locals_token = _debug_recorder->create_scope_values(locals); |
|
879 expressions_token = _debug_recorder->create_scope_values(expressions); |
|
880 monitors_token = _debug_recorder->create_monitor_values(monitors); |
|
881 |
|
882 throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE; |
|
883 } |
|
884 |
|
885 _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, |
|
886 locals_token, expressions_token, monitors_token); |
|
887 } |
|
888 |
|
889 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { |
|
890 oop debug_info = CompilationResult_Infopoint::debugInfo(site); |
|
891 assert(debug_info != NULL, "debug info expected"); |
|
892 |
|
893 // address instruction = _instructions->start() + pc_offset; |
|
894 // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); |
|
895 _debug_recorder->add_safepoint(pc_offset, create_oop_map(debug_info)); |
|
896 record_scope(pc_offset, debug_info); |
|
897 _debug_recorder->end_safepoint(pc_offset); |
|
898 } |
|
899 |
|
900 void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site) { |
|
901 oop debug_info = CompilationResult_Infopoint::debugInfo(site); |
|
902 assert(debug_info != NULL, "debug info expected"); |
|
903 |
|
904 _debug_recorder->add_non_safepoint(pc_offset); |
|
905 record_scope(pc_offset, debug_info); |
|
906 _debug_recorder->end_non_safepoint(pc_offset); |
|
907 } |
|
908 |
|
909 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { |
|
910 oop target = CompilationResult_Call::target(site); |
|
911 InstanceKlass* target_klass = InstanceKlass::cast(target->klass()); |
|
912 |
|
913 oop hotspot_method = NULL; // JavaMethod |
|
914 oop foreign_call = NULL; |
|
915 |
|
916 if (target_klass->is_subclass_of(SystemDictionary::HotSpotForeignCallTarget_klass())) { |
|
917 foreign_call = target; |
|
918 } else { |
|
919 hotspot_method = target; |
|
920 } |
|
921 |
|
922 oop debug_info = CompilationResult_Call::debugInfo(site); |
|
923 |
|
924 assert(!!hotspot_method ^ !!foreign_call, "Call site needs exactly one type"); |
|
925 |
|
926 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); |
|
927 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); |
|
928 |
|
929 if (debug_info != NULL) { |
|
930 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(debug_info)); |
|
931 record_scope(next_pc_offset, debug_info); |
|
932 } |
|
933 |
|
934 if (foreign_call != NULL) { |
|
935 jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call); |
|
936 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination); |
|
937 } else { // method != NULL |
|
938 assert(hotspot_method != NULL, "unexpected JavaMethod"); |
|
939 assert(debug_info != NULL, "debug info expected"); |
|
940 |
|
941 TRACE_jvmci_3("method call"); |
|
942 CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset); |
|
943 if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) { |
|
944 // Need a static call stub for transitions from compiled to interpreted. |
|
945 CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset); |
|
946 } |
|
947 } |
|
948 |
|
949 _next_call_type = INVOKE_INVALID; |
|
950 |
|
951 if (debug_info != NULL) { |
|
952 _debug_recorder->end_safepoint(next_pc_offset); |
|
953 } |
|
954 } |
|
955 |
|
956 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { |
|
957 oop reference = CompilationResult_DataPatch::reference(site); |
|
958 if (reference->is_a(CompilationResult_ConstantReference::klass())) { |
|
959 Handle constant = CompilationResult_ConstantReference::constant(reference); |
|
960 if (constant->is_a(HotSpotObjectConstantImpl::klass())) { |
|
961 pd_patch_OopConstant(pc_offset, constant); |
|
962 } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { |
|
963 record_metadata_in_patch(constant, _oop_recorder); |
|
964 } else if (constant->is_a(HotSpotSentinelConstant::klass())) { |
|
965 fatal("sentinel constant unsupported"); |
|
966 } else { |
|
967 fatal("unknown constant type in data patch"); |
|
968 } |
|
969 } else if (reference->is_a(CompilationResult_DataSectionReference::klass())) { |
|
970 int data_offset = CompilationResult_DataSectionReference::offset(reference); |
|
971 assert(0 <= data_offset && data_offset < _constants_size, err_msg("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size)); |
|
972 pd_patch_DataSectionReference(pc_offset, data_offset); |
|
973 } else { |
|
974 fatal("unknown data patch type"); |
|
975 } |
|
976 } |
|
977 |
|
978 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { |
|
979 oop id_obj = CompilationResult_Mark::id(site); |
|
980 |
|
981 if (id_obj != NULL) { |
|
982 assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); |
|
983 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); |
|
984 |
|
985 address pc = _instructions->start() + pc_offset; |
|
986 |
|
987 switch (id) { |
|
988 case UNVERIFIED_ENTRY: |
|
989 _offsets.set_value(CodeOffsets::Entry, pc_offset); |
|
990 break; |
|
991 case VERIFIED_ENTRY: |
|
992 _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset); |
|
993 break; |
|
994 case OSR_ENTRY: |
|
995 _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset); |
|
996 break; |
|
997 case EXCEPTION_HANDLER_ENTRY: |
|
998 _offsets.set_value(CodeOffsets::Exceptions, pc_offset); |
|
999 break; |
|
1000 case DEOPT_HANDLER_ENTRY: |
|
1001 _offsets.set_value(CodeOffsets::Deopt, pc_offset); |
|
1002 break; |
|
1003 case INVOKEVIRTUAL: |
|
1004 case INVOKEINTERFACE: |
|
1005 case INLINE_INVOKE: |
|
1006 case INVOKESTATIC: |
|
1007 case INVOKESPECIAL: |
|
1008 _next_call_type = (MarkId) id; |
|
1009 _invoke_mark_pc = pc; |
|
1010 break; |
|
1011 case POLL_NEAR: |
|
1012 case POLL_FAR: |
|
1013 case POLL_RETURN_NEAR: |
|
1014 case POLL_RETURN_FAR: |
|
1015 pd_relocate_poll(pc, id); |
|
1016 break; |
|
1017 case CARD_TABLE_ADDRESS: |
|
1018 case HEAP_TOP_ADDRESS: |
|
1019 case HEAP_END_ADDRESS: |
|
1020 case NARROW_KLASS_BASE_ADDRESS: |
|
1021 case CRC_TABLE_ADDRESS: |
|
1022 break; |
|
1023 default: |
|
1024 ShouldNotReachHere(); |
|
1025 break; |
|
1026 } |
|
1027 } |
|
1028 } |
|
1029 |