Mercurial > hg > graal-jvmci-8
changeset 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 | b9041d4e91c5 |
children | 8470e81631f8 |
files | graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SimpleInfopointOp.java src/share/vm/code/scopeDesc.cpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp src/share/vm/graal/graalJavaAccess.hpp |
diffstat | 7 files changed, 104 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Thu Mar 26 22:26:18 2015 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java Fri Mar 27 00:41:11 2015 -0700 @@ -24,6 +24,8 @@ import java.util.*; +import com.oracle.graal.api.meta.*; + /** * Represents the debugging information for a particular point of execution. This information * includes: @@ -40,6 +42,7 @@ private final BytecodePosition bytecodePosition; private final ReferenceMap referenceMap; + @SuppressWarnings("unused") private final Value[] virtualObjectMapping; private RegisterSaveLayout calleeSaveInfo; /** @@ -48,10 +51,16 @@ * @param codePos the {@linkplain BytecodePosition code position} or {@linkplain BytecodeFrame * frame} info * @param referenceMap the reference map + * @param virtualObjectMapping the mapping of {@link VirtualObject}s to their real values */ - public DebugInfo(BytecodePosition codePos, ReferenceMap referenceMap) { + public DebugInfo(BytecodePosition codePos, ReferenceMap referenceMap, Value[] virtualObjectMapping) { this.bytecodePosition = codePos; this.referenceMap = referenceMap; + this.virtualObjectMapping = virtualObjectMapping; + } + + public DebugInfo(BytecodePosition codePos) { + this(codePos, null, null); } /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Thu Mar 26 22:26:18 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Fri Mar 27 00:41:11 2015 -0700 @@ -130,7 +130,7 @@ * @param canHaveRegisters True if there can be any register map entries. */ public void initDebugInfo(FrameMap frameMap, boolean canHaveRegisters) { - debugInfo = new DebugInfo(topFrame, frameMap.initReferenceMap(canHaveRegisters)); + debugInfo = new DebugInfo(topFrame, frameMap.initReferenceMap(canHaveRegisters), virtualObjects); } /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SimpleInfopointOp.java Thu Mar 26 22:26:18 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/SimpleInfopointOp.java Fri Mar 27 00:41:11 2015 -0700 @@ -39,6 +39,6 @@ @Override public void emitCode(CompilationResultBuilder crb) { - crb.recordInfopoint(crb.asm.position(), new DebugInfo(position, null), reason); + crb.recordInfopoint(crb.asm.position(), new DebugInfo(position), reason); } }
--- a/src/share/vm/code/scopeDesc.cpp Thu Mar 26 22:26:18 2015 +0100 +++ b/src/share/vm/code/scopeDesc.cpp Fri Mar 27 00:41:11 2015 -0700 @@ -232,6 +232,7 @@ for (int i = 0; i < _objects->length(); i++) { ObjectValue* sv = _objects->at(i)->as_ObjectValue(); tty->print(" - %d: ", sv->id()); + tty->print("%s ", java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())->external_name()); sv->print_fields_on(tty); tty->cr(); }
--- a/src/share/vm/graal/graalCodeInstaller.cpp Thu Mar 26 22:26:18 2015 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri Mar 27 00:41:11 2015 -0700 @@ -203,7 +203,7 @@ record_metadata_reference(HotSpotMetaspaceConstantImpl::metaspaceObject(constant), HotSpotMetaspaceConstantImpl::primitive(constant), HotSpotMetaspaceConstantImpl::compressed(constant), oop_recorder); } -ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) { +ScopeValue* CodeInstaller::get_scope_value(oop value, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) { second = NULL; if (value == AbstractValue::ILLEGAL()) { return _illegal_value; @@ -282,7 +282,7 @@ } #endif if (StackSlot::addFrameSize(value)) { - offset += total_frame_size; + offset += _total_frame_size; } ScopeValue* value = new LocationValue(Location::new_stk_loc(locationType, offset)); if (type == T_DOUBLE || (type == T_LONG && !reference)) { @@ -290,7 +290,7 @@ } return value; } else if (value->is_a(JavaConstant::klass())){ - record_metadata_in_constant(value, oop_recorder); + record_metadata_in_constant(value, _oop_recorder); if (value->is_a(PrimitiveConstant::klass())) { assert(!reference, "unexpected primitive constant type"); if(value->is_a(RawConstant::klass())) { @@ -323,40 +323,10 @@ } } } else if (value->is_a(VirtualObject::klass())) { - oop type = VirtualObject::type(value); int id = VirtualObject::id(value); - oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); - Klass* klass = java_lang_Class::as_Klass(javaMirror); - bool isLongArray = klass == Universe::longArrayKlassObj(); - - for (jint i = 0; i < objects->length(); i++) { - ObjectValue* obj = (ObjectValue*) objects->at(i); - if (obj->id() == id) { - return obj; - } - } - - ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror))); - objects->append(sv); - - objArrayOop values = VirtualObject::values(value); - for (jint i = 0; i < values->length(); i++) { - ScopeValue* cur_second = NULL; - oop object = values->obj_at(i); - ScopeValue* value = get_scope_value(object, total_frame_size, objects, cur_second, oop_recorder); - - if (isLongArray && cur_second == NULL) { - // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. - // add an int 0 constant - cur_second = _int_0_scope_value; - } - - if (cur_second != NULL) { - sv->field_values()->append(cur_second); - } - sv->field_values()->append(value); - } - return sv; + ScopeValue* object = objects->at(id); + assert(object != NULL, "missing value"); + return object; } else { value->klass()->print(); value->print(); @@ -365,14 +335,41 @@ return NULL; } -MonitorValue* CodeInstaller::get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, OopRecorder* oop_recorder) { +void CodeInstaller::record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects) { + oop type = VirtualObject::type(value); + int id = VirtualObject::id(value); + oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); + Klass* klass = java_lang_Class::as_Klass(javaMirror); + bool isLongArray = klass == Universe::longArrayKlassObj(); + + objArrayOop values = VirtualObject::values(value); + for (jint i = 0; i < values->length(); i++) { + ScopeValue* cur_second = NULL; + oop object = values->obj_at(i); + ScopeValue* value = get_scope_value(object, objects, cur_second); + + if (isLongArray && cur_second == NULL) { + // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. + // add an int 0 constant + cur_second = _int_0_scope_value; + } + + if (cur_second != NULL) { + sv->field_values()->append(cur_second); + } + assert(value != NULL, "missing value"); + sv->field_values()->append(value); + } +} + +MonitorValue* CodeInstaller::get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects) { guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type MonitorValue"); ScopeValue* second = NULL; - ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), total_frame_size, objects, second, oop_recorder); + ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), objects, second); assert(second == NULL, "monitor cannot occupy two stack slots"); - ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), total_frame_size, objects, second, oop_recorder); + ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), objects, second); assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); assert(lock_data_value->is_location(), "invalid monitor location"); Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); @@ -727,6 +724,44 @@ return true; } +GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(oop debug_info) { + objArrayOop virtualObjects = DebugInfo::virtualObjectMapping(debug_info); + if (virtualObjects == NULL) { + return NULL; + } + GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(virtualObjects->length(), virtualObjects->length(), NULL); + // Create the unique ObjectValues + for (int i = 0; i < virtualObjects->length(); i++) { + oop value = virtualObjects->obj_at(i); + int id = VirtualObject::id(value); + oop type = VirtualObject::type(value); + oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type); + ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror))); + assert(objects->at(id) == NULL, "once"); + objects->at_put(id, sv); + } + // All the values which could be referenced by the VirtualObjects + // exist, so now describe all the VirtualObjects themselves. + for (int i = 0; i < virtualObjects->length(); i++) { + oop value = virtualObjects->obj_at(i); + int id = VirtualObject::id(value); + record_object_value(objects->at(id)->as_ObjectValue(), value, objects); + } + _debug_recorder->dump_object_pool(objects); + return objects; +} + +void CodeInstaller::record_scope(jint pc_offset, oop debug_info) { + oop position = DebugInfo::bytecodePosition(debug_info); + if (position == NULL) { + // Stubs do not record scope info, just oop maps + return; + } + + GrowableArray<ScopeValue*>* objectMapping = record_virtual_objects(debug_info); + record_scope(pc_offset, position, objectMapping); +} + void CodeInstaller::record_scope(jint pc_offset, oop position, GrowableArray<ScopeValue*>* objects) { oop frame = NULL; if (position->is_a(BytecodeFrame::klass())) { @@ -785,21 +820,21 @@ for (jint i = 0; i < values->length(); i++) { ScopeValue* second = NULL; - oop value= values->obj_at(i); + oop value = values->obj_at(i); if (i < local_count) { - ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder); + ScopeValue* first = get_scope_value(value, objects, second); if (second != NULL) { locals->append(second); } locals->append(first); } else if (i < local_count + expression_count) { - ScopeValue* first = get_scope_value(value, _total_frame_size, objects, second, _oop_recorder); + ScopeValue* first = get_scope_value(value, objects, second); if (second != NULL) { expressions->append(second); } expressions->append(first); } else { - monitors->append(get_monitor_value(value, _total_frame_size, objects, _oop_recorder)); + monitors->append(get_monitor_value(value, objects)); } if (second != NULL) { i++; @@ -808,8 +843,6 @@ } } - _debug_recorder->dump_object_pool(objects); - locals_token = _debug_recorder->create_scope_values(locals); expressions_token = _debug_recorder->create_scope_values(expressions); monitors_token = _debug_recorder->create_monitor_values(monitors); @@ -817,7 +850,8 @@ throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE; } - _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token); + _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, + locals_token, expressions_token, monitors_token); } void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { @@ -827,14 +861,7 @@ // address instruction = _instructions->start() + pc_offset; // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); _debug_recorder->add_safepoint(pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); - - oop frame = DebugInfo::bytecodePosition(debug_info); - if (frame != NULL) { - record_scope(pc_offset, frame, new GrowableArray<ScopeValue*>()); - } else { - // Stubs do not record scope info, just oop maps - } - + record_scope(pc_offset, debug_info); _debug_recorder->end_safepoint(pc_offset); } @@ -843,12 +870,7 @@ assert(debug_info != NULL, "debug info expected"); _debug_recorder->add_non_safepoint(pc_offset); - - oop position = DebugInfo::bytecodePosition(debug_info); - if (position != NULL) { - record_scope(pc_offset, position, NULL); - } - + record_scope(pc_offset, debug_info); _debug_recorder->end_non_safepoint(pc_offset); } @@ -873,13 +895,8 @@ jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); if (debug_info != NULL) { - oop frame = DebugInfo::bytecodePosition(debug_info); _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_total_frame_size, _parameter_count, debug_info)); - if (frame != NULL) { - record_scope(next_pc_offset, frame, new GrowableArray<ScopeValue*>()); - } else { - // Stubs do not record scope info, just oop maps - } + record_scope(next_pc_offset, debug_info); } if (foreign_call != NULL) {
--- a/src/share/vm/graal/graalCodeInstaller.hpp Thu Mar 26 22:26:18 2015 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Fri Mar 27 00:41:11 2015 -0700 @@ -114,12 +114,10 @@ static VMReg get_hotspot_reg(jint graalRegisterNumber); static bool is_general_purpose_reg(VMReg hotspotRegister); -protected: +private: + ScopeValue* get_scope_value(oop value, GrowableArray<ScopeValue*>* objects, ScopeValue* &second); + MonitorValue* get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects); - virtual ScopeValue* get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder); - virtual MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, OopRecorder* oop_recorder); - -private: // extract the fields of the CompilationResult void initialize_fields(oop target_method); void initialize_dependencies(oop target_method); @@ -141,7 +139,11 @@ void site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site); void site_Mark(CodeBuffer& buffer, jint pc_offset, oop site); + void record_scope(jint pc_offset, oop debug_info); void record_scope(jint pc_offset, oop code_pos, GrowableArray<ScopeValue*>* objects); + void record_object_value(ObjectValue* sv, oop value, GrowableArray<ScopeValue*>* objects); + + GrowableArray<ScopeValue*>* record_virtual_objects(oop debug_info); void process_exception_handlers(); int estimateStubSpace(int static_call_stubs);
--- a/src/share/vm/graal/graalJavaAccess.hpp Thu Mar 26 22:26:18 2015 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Fri Mar 27 00:41:11 2015 -0700 @@ -159,6 +159,7 @@ oop_field(DebugInfo, bytecodePosition, "Lcom/oracle/graal/api/code/BytecodePosition;") \ oop_field(DebugInfo, referenceMap, "Lcom/oracle/graal/api/code/ReferenceMap;") \ oop_field(DebugInfo, calleeSaveInfo, "Lcom/oracle/graal/api/code/RegisterSaveLayout;") \ + objArrayOop_field(DebugInfo, virtualObjectMapping, "[Lcom/oracle/graal/api/meta/Value;") \ end_class \ start_class(HotSpotReferenceMap) \ oop_field(HotSpotReferenceMap, registerRefMap, "Ljava/util/BitSet;") \