comparison src/share/vm/graal/graalCodeInstaller.cpp @ 20044:c1f116cd4b67

Speed up debug info generation for virtual objects
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Fri, 27 Mar 2015 00:41:11 -0700
parents deab43a789ad
children 92fc95e8667d
comparison
equal deleted inserted replaced
20043:b9041d4e91c5 20044:c1f116cd4b67
201 201
202 static void record_metadata_in_patch(Handle& constant, OopRecorder* oop_recorder) { 202 static void record_metadata_in_patch(Handle& constant, OopRecorder* oop_recorder) {
203 record_metadata_reference(HotSpotMetaspaceConstantImpl::metaspaceObject(constant), HotSpotMetaspaceConstantImpl::primitive(constant), HotSpotMetaspaceConstantImpl::compressed(constant), oop_recorder); 203 record_metadata_reference(HotSpotMetaspaceConstantImpl::metaspaceObject(constant), HotSpotMetaspaceConstantImpl::primitive(constant), HotSpotMetaspaceConstantImpl::compressed(constant), oop_recorder);
204 } 204 }
205 205
206 ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) { 206 ScopeValue* CodeInstaller::get_scope_value(oop value, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) {
207 second = NULL; 207 second = NULL;
208 if (value == AbstractValue::ILLEGAL()) { 208 if (value == AbstractValue::ILLEGAL()) {
209 return _illegal_value; 209 return _illegal_value;
210 } 210 }
211 211
280 if(offset >= 0) { 280 if(offset >= 0) {
281 offset += 128; 281 offset += 128;
282 } 282 }
283 #endif 283 #endif
284 if (StackSlot::addFrameSize(value)) { 284 if (StackSlot::addFrameSize(value)) {
285 offset += total_frame_size; 285 offset += _total_frame_size;
286 } 286 }
287 ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset)); 287 ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset));
288 if (type == T_DOUBLE || (type == T_LONG && !reference)) { 288 if (type == T_DOUBLE || (type == T_LONG && !reference)) {
289 second = value; 289 second = value;
290 } 290 }
291 return value; 291 return value;
292 } else if (value->is_a(JavaConstant::klass())){ 292 } else if (value->is_a(JavaConstant::klass())){
293 record_metadata_in_constant(value, oop_recorder); 293 record_metadata_in_constant(value, _oop_recorder);
294 if (value->is_a(PrimitiveConstant::klass())) { 294 if (value->is_a(PrimitiveConstant::klass())) {
295 assert(!reference, "unexpected primitive constant type"); 295 assert(!reference, "unexpected primitive constant type");
296 if(value->is_a(RawConstant::klass())) { 296 if(value->is_a(RawConstant::klass())) {
297 jlong prim = PrimitiveConstant::primitive(value); 297 jlong prim = PrimitiveConstant::primitive(value);
298 return new ConstantLongValue(prim); 298 return new ConstantLongValue(prim);
321 assert(obj != NULL, "null value must be in NullConstant"); 321 assert(obj != NULL, "null value must be in NullConstant");
322 return new ConstantOopWriteValue(JNIHandles::make_local(obj)); 322 return new ConstantOopWriteValue(JNIHandles::make_local(obj));
323 } 323 }
324 } 324 }
325 } else if (value->is_a(VirtualObject::klass())) { 325 } else if (value->is_a(VirtualObject::klass())) {
326 oop type = VirtualObject::type(value);
327 int id = VirtualObject::id(value); 326 int id = VirtualObject::id(value);
328 oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); 327 ScopeValue* object = objects->at(id);
329 Klass* klass = java_lang_Class::as_Klass(javaMirror); 328 assert(object != NULL, "missing value");
330 bool isLongArray = klass == Universe::longArrayKlassObj(); 329 return object;
331
332 for (jint i = 0; i < objects->length(); i++) {
333 ObjectValue* obj = (ObjectValue*) objects->at(i);
334 if (obj->id() == id) {
335 return obj;
336 }
337 }
338
339 ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror)));
340 objects->append(sv);
341
342 objArrayOop values = VirtualObject::values(value);
343 for (jint i = 0; i < values->length(); i++) {
344 ScopeValue* cur_second = NULL;
345 oop object = values->obj_at(i);
346 ScopeValue* value = get_scope_value(object, total_frame_size, objects, cur_second, oop_recorder);
347
348 if (isLongArray && cur_second == NULL) {
349 // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
350 // add an int 0 constant
351 cur_second = _int_0_scope_value;
352 }
353
354 if (cur_second != NULL) {
355 sv->field_values()->append(cur_second);
356 }
357 sv->field_values()->append(value);
358 }
359 return sv;
360 } else { 330 } else {
361 value->klass()->print(); 331 value->klass()->print();
362 value->print(); 332 value->print();
363 } 333 }
364 ShouldNotReachHere(); 334 ShouldNotReachHere();
365 return NULL; 335 return NULL;
366 } 336 }
367 337
368 MonitorValue* CodeInstaller::get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, OopRecorder* oop_recorder) { 338 void CodeInstaller::record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects) {
339 oop type = VirtualObject::type(value);
340 int id = VirtualObject::id(value);
341 oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type);
342 Klass* klass = java_lang_Class::as_Klass(javaMirror);
343 bool isLongArray = klass == Universe::longArrayKlassObj();
344
345 objArrayOop values = VirtualObject::values(value);
346 for (jint i = 0; i < values->length(); i++) {
347 ScopeValue* cur_second = NULL;
348 oop object = values->obj_at(i);
349 ScopeValue* value = get_scope_value(object, objects, cur_second);
350
351 if (isLongArray && cur_second == NULL) {
352 // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
353 // add an int 0 constant
354 cur_second = _int_0_scope_value;
355 }
356
357 if (cur_second != NULL) {
358 sv->field_values()->append(cur_second);
359 }
360 assert(value != NULL, "missing value");
361 sv->field_values()->append(value);
362 }
363 }
364
365 MonitorValue* CodeInstaller::get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects) {
369 guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type MonitorValue"); 366 guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type MonitorValue");
370 367
371 ScopeValue* second = NULL; 368 ScopeValue* second = NULL;
372 ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), total_frame_size, objects, second, oop_recorder); 369 ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), objects, second);
373 assert(second == NULL, "monitor cannot occupy two stack slots"); 370 assert(second == NULL, "monitor cannot occupy two stack slots");
374 371
375 ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), total_frame_size, objects, second, oop_recorder); 372 ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), objects, second);
376 assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); 373 assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
377 assert(lock_data_value->is_location(), "invalid monitor location"); 374 assert(lock_data_value->is_location(), "invalid monitor location");
378 Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); 375 Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
379 376
380 bool eliminated = false; 377 bool eliminated = false;
725 return true; 722 return true;
726 } 723 }
727 return true; 724 return true;
728 } 725 }
729 726
727 GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(oop debug_info) {
728 objArrayOop virtualObjects = DebugInfo::virtualObjectMapping(debug_info);
729 if (virtualObjects == NULL) {
730 return NULL;
731 }
732 GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(virtualObjects->length(), virtualObjects->length(), NULL);
733 // Create the unique ObjectValues
734 for (int i = 0; i < virtualObjects->length(); i++) {
735 oop value = virtualObjects->obj_at(i);
736 int id = VirtualObject::id(value);
737 oop type = VirtualObject::type(value);
738 oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type);
739 ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror)));
740 assert(objects->at(id) == NULL, "once");
741 objects->at_put(id, sv);
742 }
743 // All the values which could be referenced by the VirtualObjects
744 // exist, so now describe all the VirtualObjects themselves.
745 for (int i = 0; i < virtualObjects->length(); i++) {
746 oop value = virtualObjects->obj_at(i);
747 int id = VirtualObject::id(value);
748 record_object_value(objects->at(id)->as_ObjectValue(), value, objects);
749 }
750 _debug_recorder->dump_object_pool(objects);
751 return objects;
752 }
753
754 void CodeInstaller::record_scope(jint pc_offset, oop debug_info) {
755 oop position = DebugInfo::bytecodePosition(debug_info);
756 if (position == NULL) {
757 // Stubs do not record scope info, just oop maps
758 return;
759 }
760
761 GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info);
762 record_scope(pc_offset, position, objectMapping);
763 }
764
730 void CodeInstaller::record_scope(jint pc_offset, oop position, GrowableArray<ScopeValue*>* objects) { 765 void CodeInstaller::record_scope(jint pc_offset, oop position, GrowableArray<ScopeValue*>* objects) {
731 oop frame = NULL; 766 oop frame = NULL;
732 if (position->is_a(BytecodeFrame::klass())) { 767 if (position->is_a(BytecodeFrame::klass())) {
733 frame = position; 768 frame = position;
734 } 769 }
783 tty->print_cr("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count); 818 tty->print_cr("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);
784 } 819 }
785 820
786 for (jint i = 0; i < values->length(); i++) { 821 for (jint i = 0; i < values->length(); i++) {
787 ScopeValue* second = NULL; 822 ScopeValue* second = NULL;
788 oop value= values->obj_at(i); 823 oop value = values->obj_at(i);
789 if (i < local_count) { 824 if (i < local_count) {
790 ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder); 825 ScopeValue* first = get_scope_value(value, objects, second);
791 if (second != NULL) { 826 if (second != NULL) {
792 locals->append(second); 827 locals->append(second);
793 } 828 }
794 locals->append(first); 829 locals->append(first);
795 } else if (i < local_count + expression_count) { 830 } else if (i < local_count + expression_count) {
796 ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder); 831 ScopeValue* first = get_scope_value(value, objects, second);
797 if (second != NULL) { 832 if (second != NULL) {
798 expressions->append(second); 833 expressions->append(second);
799 } 834 }
800 expressions->append(first); 835 expressions->append(first);
801 } else { 836 } else {
802 monitors->append(get_monitor_value(value, _total_frame_size, objects, _oop_recorder)); 837 monitors->append(get_monitor_value(value, objects));
803 } 838 }
804 if (second != NULL) { 839 if (second != NULL) {
805 i++; 840 i++;
806 assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL"); 841 assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL");
807 assert(values->obj_at(i) == AbstractValue::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); 842 assert(values->obj_at(i) == AbstractValue::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL");
808 } 843 }
809 } 844 }
810 845
811 _debug_recorder->dump_object_pool(objects);
812
813 locals_token = _debug_recorder->create_scope_values(locals); 846 locals_token = _debug_recorder->create_scope_values(locals);
814 expressions_token = _debug_recorder->create_scope_values(expressions); 847 expressions_token = _debug_recorder->create_scope_values(expressions);
815 monitors_token = _debug_recorder->create_monitor_values(monitors); 848 monitors_token = _debug_recorder->create_monitor_values(monitors);
816 849
817 throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE; 850 throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
818 } 851 }
819 852
820 _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token); 853 _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false,
854 locals_token, expressions_token, monitors_token);
821 } 855 }
822 856
823 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { 857 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {
824 oop debug_info = CompilationResult_Infopoint::debugInfo(site); 858 oop debug_info = CompilationResult_Infopoint::debugInfo(site);
825 assert(debug_info != NULL, "debug info expected"); 859 assert(debug_info != NULL, "debug info expected");
826 860
827 // address instruction = _instructions->start() + pc_offset; 861 // address instruction = _instructions->start() + pc_offset;
828 // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); 862 // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
829 _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); 863 _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
830 864 record_scope(pc_offset, debug_info);
831 oop frame = DebugInfo::bytecodePosition(debug_info);
832 if (frame != NULL) {
833 record_scope(pc_offset, frame, new GrowableArray<ScopeValue*>());
834 } else {
835 // Stubs do not record scope info, just oop maps
836 }
837
838 _debug_recorder->end_safepoint(pc_offset); 865 _debug_recorder->end_safepoint(pc_offset);
839 } 866 }
840 867
841 void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site) { 868 void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, oop site) {
842 oop debug_info = CompilationResult_Infopoint::debugInfo(site); 869 oop debug_info = CompilationResult_Infopoint::debugInfo(site);
843 assert(debug_info != NULL, "debug info expected"); 870 assert(debug_info != NULL, "debug info expected");
844 871
845 _debug_recorder->add_non_safepoint(pc_offset); 872 _debug_recorder->add_non_safepoint(pc_offset);
846 873 record_scope(pc_offset, debug_info);
847 oop position = DebugInfo::bytecodePosition(debug_info);
848 if (position != NULL) {
849 record_scope(pc_offset, position, NULL);
850 }
851
852 _debug_recorder->end_non_safepoint(pc_offset); 874 _debug_recorder->end_non_safepoint(pc_offset);
853 } 875 }
854 876
855 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { 877 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) {
856 oop target = CompilationResult_Call::target(site); 878 oop target = CompilationResult_Call::target(site);
871 893
872 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); 894 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
873 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); 895 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method);
874 896
875 if (debug_info != NULL) { 897 if (debug_info != NULL) {
876 oop frame = DebugInfo::bytecodePosition(debug_info);
877 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); 898 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info));
878 if (frame != NULL) { 899 record_scope(next_pc_offset, debug_info);
879 record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>());
880 } else {
881 // Stubs do not record scope info, just oop maps
882 }
883 } 900 }
884 901
885 if (foreign_call != NULL) { 902 if (foreign_call != NULL) {
886 jlong foreign_call_destination = HotSpotForeignCallLinkageImpl::address(foreign_call); 903 jlong foreign_call_destination = HotSpotForeignCallLinkageImpl::address(foreign_call);
887 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination); 904 CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination);