# HG changeset patch # User Lukas Stadler # Date 1354020184 -3600 # Node ID b6a8f2d23057d706b3afb75b0da219e976525311 # Parent adf5c101bc4b86d192a01e2a0c57c6d0938d09b2 VM support for deferred reads and writes: ScopeDesc, DebugInfo, DebugInfoRecorder diff -r adf5c101bc4b -r b6a8f2d23057 src/share/vm/code/debugInfo.cpp --- a/src/share/vm/code/debugInfo.cpp Tue Nov 27 12:10:41 2012 +0100 +++ b/src/share/vm/code/debugInfo.cpp Tue Nov 27 13:43:04 2012 +0100 @@ -77,7 +77,11 @@ enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1, CONSTANT_OOP_CODE = 2, CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4, - OBJECT_CODE = 5, OBJECT_ID_CODE = 6 }; + OBJECT_CODE = 5, OBJECT_ID_CODE = 6, +#ifdef GRAAL + DEFERRED_READ_CODE = 7, DEFERRED_WRITE_CODE = 8 +#endif // GRAAL +}; ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) { ScopeValue* result = NULL; @@ -89,6 +93,10 @@ case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream); break; case OBJECT_CODE: result = stream->read_object_value(); break; case OBJECT_ID_CODE: result = stream->get_cached_object(); break; +#ifdef GRAAL + case DEFERRED_READ_CODE: result = new DeferredReadValue(stream); break; + case DEFERRED_WRITE_CODE: result = new DeferredWriteValue(stream); break; +#endif // GRAAL default: ShouldNotReachHere(); } return result; @@ -109,6 +117,63 @@ location().print_on(st); } +#ifdef GRAAL + +// DeferredLocationValue + +DeferredLocationValue::DeferredLocationValue(DebugInfoReadStream* stream) { + _base = read_from(stream); + _index = read_from(stream); + _scale = stream->read_int(); + _disp = stream->read_long(); +} + +void DeferredLocationValue::write_on(DebugInfoWriteStream* stream) { + _base->write_on(stream); + _index->write_on(stream); + stream->write_int(_scale); + stream->write_long(_disp); +} + +void DeferredLocationValue::print_on(outputStream* st) const { + _base->print_on(st); + _index->print_on(st); + st->print("%i %i", _scale, _disp); +} + +// DeferredReadValue + +DeferredReadValue::DeferredReadValue(DebugInfoReadStream* stream) +: DeferredLocationValue(stream) { +} + +void DeferredReadValue::write_on(DebugInfoWriteStream* st) { + DeferredLocationValue::write_on(st); +} + +void DeferredReadValue::print_on(outputStream* st) const { + DeferredLocationValue::print_on(st); +} + +// DeferredWriteValue + +DeferredWriteValue::DeferredWriteValue(DebugInfoReadStream* stream) +: DeferredLocationValue(stream) { + _value = read_from(stream); +} + +void DeferredWriteValue::write_on(DebugInfoWriteStream* st) { + DeferredLocationValue::write_on(st); + _value->write_on(st); +} + +void DeferredWriteValue::print_on(outputStream* st) const { + DeferredLocationValue::print_on(st); + _value->print_on(st); +} + +#endif // GRAAL + // ObjectValue void ObjectValue::read_object(DebugInfoReadStream* stream) { diff -r adf5c101bc4b -r b6a8f2d23057 src/share/vm/code/debugInfo.hpp --- a/src/share/vm/code/debugInfo.hpp Tue Nov 27 12:10:41 2012 +0100 +++ b/src/share/vm/code/debugInfo.hpp Tue Nov 27 13:43:04 2012 +0100 @@ -61,6 +61,11 @@ // Serialization of debugging information virtual void write_on(DebugInfoWriteStream* stream) = 0; static ScopeValue* read_from(DebugInfoReadStream* stream); + +#ifdef GRAAL + // Printing + virtual void print_on(outputStream* st) const = 0; +#endif // GRAAL }; @@ -83,6 +88,64 @@ void print_on(outputStream* st) const; }; +#ifdef GRAAL + +class DeferredLocationValue: public ScopeValue { +private: + ScopeValue* _base; + ScopeValue* _index; + jint _scale; + jlong _disp; +public: + DeferredLocationValue(ScopeValue* base, ScopeValue* index, jint scale, jlong disp) + : _base(base), _index(index), _scale(scale), _disp(disp) { } + + ScopeValue* base() { return _base; } + ScopeValue* index() { return _index; } + jint scale() { return _scale; } + jlong disp() { return _disp; } + + // Serialization of debugging information + DeferredLocationValue(DebugInfoReadStream* stream); + void write_on(DebugInfoWriteStream* stream); + + // Printing + void print_on(outputStream* st) const; +}; + + +class DeferredReadValue: public DeferredLocationValue { +public: + DeferredReadValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp) + : DeferredLocationValue(base, index, scale, disp) { } + + // Serialization of debugging information + DeferredReadValue(DebugInfoReadStream* stream); + void write_on(DebugInfoWriteStream* stream); + + // Printing + void print_on(outputStream* st) const; +}; + +class DeferredWriteValue: public DeferredLocationValue { +private: + ScopeValue* _value; +public: + DeferredWriteValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp, ScopeValue* value) + : DeferredLocationValue(base, index, scale, disp), _value(value) { } + + ScopeValue* value() { return _value; } + + // Serialization of debugging information + DeferredWriteValue(DebugInfoReadStream* stream); + void write_on(DebugInfoWriteStream* stream); + + // Printing + void print_on(outputStream* st) const; +}; + +#endif // GRAAL + // An ObjectValue describes an object eliminated by escape analysis. diff -r adf5c101bc4b -r b6a8f2d23057 src/share/vm/code/debugInfoRec.cpp --- a/src/share/vm/code/debugInfoRec.cpp Tue Nov 27 12:10:41 2012 +0100 +++ b/src/share/vm/code/debugInfoRec.cpp Tue Nov 27 13:43:04 2012 +0100 @@ -213,6 +213,29 @@ return result; } +#ifdef GRAAL + +int DebugInformationRecorder::serialize_deferred_writes(GrowableArray* deferred_writes) { + if (deferred_writes == NULL || deferred_writes->is_empty()) return DebugInformationRecorder::serialized_null; + assert(_recording_state == rs_safepoint, "must be recording a safepoint"); + int result = stream()->position(); + assert(result != serialized_null, "sanity"); + stream()->write_int(deferred_writes->length()); + for (int index = 0; index < deferred_writes->length(); index++) { + deferred_writes->at(index)->write_on(stream()); + } + + // (See comment below on DebugInformationRecorder::describe_scope.) + int shared_result = find_sharable_decode_offset(result); + if (shared_result != serialized_null) { + stream()->set_position(result); + result = shared_result; + } + + return result; +} + +#endif // GRAAL #ifndef PRODUCT // These variables are put into one block to reduce relocations @@ -289,7 +312,11 @@ bool return_oop, DebugToken* locals, DebugToken* expressions, - DebugToken* monitors) { + DebugToken* monitors +#ifdef GRAAL + , DebugToken* deferred_writes +#endif // GRAAL + ) { assert(_recording_state != rs_null, "nesting of recording calls"); PcDesc* last_pd = last_pc(); assert(last_pd->pc_offset() == pc_offset, "must be last pc"); @@ -328,6 +355,9 @@ stream()->write_int((intptr_t) locals); stream()->write_int((intptr_t) expressions); stream()->write_int((intptr_t) monitors); +#ifdef GRAAL + stream()->write_int((intptr_t) deferred_writes); +#endif // GRAAL // Here's a tricky bit. We just wrote some bytes. // Wouldn't it be nice to find that we had already @@ -409,6 +439,14 @@ return (DebugToken*) (intptr_t) serialize_monitor_values(monitors); } +#ifdef GRAAL + +DebugToken* DebugInformationRecorder::create_deferred_writes(GrowableArray* deferred_writes) { + assert(!recorders_frozen(), "not frozen yet"); + return (DebugToken*) (intptr_t) serialize_deferred_writes(deferred_writes); +} + +#endif // GRAAL int DebugInformationRecorder::data_size() { debug_only(mark_recorders_frozen()); // mark it "frozen" for asserts diff -r adf5c101bc4b -r b6a8f2d23057 src/share/vm/code/debugInfoRec.hpp --- a/src/share/vm/code/debugInfoRec.hpp Tue Nov 27 12:10:41 2012 +0100 +++ b/src/share/vm/code/debugInfoRec.hpp Tue Nov 27 13:43:04 2012 +0100 @@ -107,7 +107,11 @@ bool return_oop = false, DebugToken* locals = NULL, DebugToken* expressions = NULL, - DebugToken* monitors = NULL); + DebugToken* monitors = NULL +#ifdef GRAAL + , DebugToken* deferred_writes = NULL +#endif // GRAAL + ); void dump_object_pool(GrowableArray* objects); @@ -120,6 +124,9 @@ // helper fuctions for describe_scope to enable sharing DebugToken* create_scope_values(GrowableArray* values); DebugToken* create_monitor_values(GrowableArray* monitors); +#ifdef GRAAL + DebugToken* create_deferred_writes(GrowableArray* deferred_writes); +#endif // GRAAL // returns the size of the generated scopeDescs. int data_size(); @@ -194,6 +201,9 @@ int serialize_monitor_values(GrowableArray* monitors); int serialize_scope_values(GrowableArray* values); +#ifdef GRAAL + int serialize_deferred_writes(GrowableArray* deferred_writes); +#endif // GRAAL int find_sharable_decode_offset(int stream_offset); #ifndef PRODUCT diff -r adf5c101bc4b -r b6a8f2d23057 src/share/vm/code/scopeDesc.cpp --- a/src/share/vm/code/scopeDesc.cpp Tue Nov 27 12:10:41 2012 +0100 +++ b/src/share/vm/code/scopeDesc.cpp Tue Nov 27 13:43:04 2012 +0100 @@ -73,6 +73,9 @@ _locals_decode_offset = DebugInformationRecorder::serialized_null; _expressions_decode_offset = DebugInformationRecorder::serialized_null; _monitors_decode_offset = DebugInformationRecorder::serialized_null; +#ifdef GRAAL + _deferred_writes_decode_offset = DebugInformationRecorder::serialized_null; +#endif // GRAAL } else { // decode header DebugInfoReadStream* stream = stream_at(decode_offset()); @@ -85,6 +88,9 @@ _locals_decode_offset = stream->read_int(); _expressions_decode_offset = stream->read_int(); _monitors_decode_offset = stream->read_int(); +#ifdef GRAAL + _deferred_writes_decode_offset = stream->read_int(); +#endif // GRAAL } } @@ -126,6 +132,25 @@ return result; } +#ifdef GRAAL + +GrowableArray* ScopeDesc::decode_deferred_writes(int decode_offset) { + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; + DebugInfoReadStream* stream = stream_at(decode_offset); + int length = stream->read_int(); + GrowableArray* result = new GrowableArray (length); + for (int index = 0; index < length; index++) { + result->push(new DeferredWriteValue(stream)); + } + return result; +} + +GrowableArray* ScopeDesc::deferred_writes() { + return decode_deferred_writes(_deferred_writes_decode_offset); +} + +#endif // GRAAL + DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const { return new DebugInfoReadStream(_code, decode_offset, _objects); } @@ -225,8 +250,8 @@ } } -#ifdef COMPILER2 - if (DoEscapeAnalysis && is_top() && _objects != NULL) { +#if defined(COMPILER2) || defined(GRAAL) + if (NOT_GRAAL(DoEscapeAnalysis &&) is_top() && _objects != NULL) { tty->print_cr("Objects"); for (int i = 0; i < _objects->length(); i++) { ObjectValue* sv = (ObjectValue*) _objects->at(i); @@ -235,7 +260,20 @@ tty->cr(); } } -#endif // COMPILER2 +#endif // COMPILER2 || GRAAL +#ifdef GRAAL + // deferred writes + { GrowableArray* l = ((ScopeDesc*) this)->deferred_writes(); + if (l != NULL) { + st->print_cr(" Deferred writes"); + for (int index = 0; index < l->length(); index++) { + st->print(" - @%d: ", index); + l->at(index)->print_on(st); + st->cr(); + } + } + } +#endif } #endif diff -r adf5c101bc4b -r b6a8f2d23057 src/share/vm/code/scopeDesc.hpp --- a/src/share/vm/code/scopeDesc.hpp Tue Nov 27 12:10:41 2012 +0100 +++ b/src/share/vm/code/scopeDesc.hpp Tue Nov 27 13:43:04 2012 +0100 @@ -78,6 +78,9 @@ GrowableArray* expressions(); GrowableArray* monitors(); GrowableArray* objects(); +#ifdef GRAAL + GrowableArray* deferred_writes(); +#endif // GRAAL // Stack walking, returns NULL if this is the outer most scope. ScopeDesc* sender() const; @@ -107,6 +110,9 @@ int _locals_decode_offset; int _expressions_decode_offset; int _monitors_decode_offset; +#ifdef GRAAL + int _deferred_writes_decode_offset; +#endif // GRAAL // Object pool GrowableArray* _objects; @@ -119,6 +125,9 @@ GrowableArray* decode_scope_values(int decode_offset); GrowableArray* decode_monitor_values(int decode_offset); GrowableArray* decode_object_values(int decode_offset); +#ifdef GRAAL + GrowableArray* decode_deferred_writes(int decode_offset); +#endif // GRAAL DebugInfoReadStream* stream_at(int decode_offset) const; diff -r adf5c101bc4b -r b6a8f2d23057 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Nov 27 12:10:41 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Nov 27 13:43:04 2012 +0100 @@ -530,9 +530,13 @@ DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); + GrowableArray* deferred_writes = new GrowableArray (); +// deferred_writes->append(new DeferredWriteValue(new LocationValue(Location::new_reg_loc(Location::lng, rax->as_VMReg())), new ConstantIntValue(0), 0, 100, new ConstantIntValue(123))); + DebugToken* deferred_writes_token = _debug_recorder->create_deferred_writes(deferred_writes); + bool 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, deferred_writes_token); } void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) {