2929#include " gc/shared/collectedHeap.hpp"
3030#include " memory/universe.hpp"
3131#include " oops/oop.inline.hpp"
32+ #include " runtime/stackValue.hpp"
3233#include " runtime/handles.inline.hpp"
3334#include " runtime/interfaceSupport.inline.hpp"
3435#include " runtime/javaThread.hpp"
@@ -80,6 +81,20 @@ ScopeValue* DebugInfoReadStream::read_object_value(bool is_auto_box) {
8081 return result;
8182}
8283
84+ ScopeValue* DebugInfoReadStream::read_object_merge_value () {
85+ int id = read_int ();
86+ #ifdef ASSERT
87+ assert (_obj_pool != nullptr , " object pool does not exist" );
88+ for (int i = _obj_pool->length () - 1 ; i >= 0 ; i--) {
89+ assert (_obj_pool->at (i)->as_ObjectValue ()->id () != id, " should not be read twice" );
90+ }
91+ #endif
92+ ObjectMergeValue* result = new ObjectMergeValue (id);
93+ _obj_pool->push (result);
94+ result->read_object (this );
95+ return result;
96+ }
97+
8398ScopeValue* DebugInfoReadStream::get_cached_object () {
8499 int id = read_int ();
85100 assert (_obj_pool != nullptr , " object pool does not exist" );
@@ -98,7 +113,8 @@ ScopeValue* DebugInfoReadStream::get_cached_object() {
98113enum { LOCATION_CODE = 0 , CONSTANT_INT_CODE = 1 , CONSTANT_OOP_CODE = 2 ,
99114 CONSTANT_LONG_CODE = 3 , CONSTANT_DOUBLE_CODE = 4 ,
100115 OBJECT_CODE = 5 , OBJECT_ID_CODE = 6 ,
101- AUTO_BOX_OBJECT_CODE = 7 , MARKER_CODE = 8 };
116+ AUTO_BOX_OBJECT_CODE = 7 , MARKER_CODE = 8 ,
117+ OBJECT_MERGE_CODE = 9 };
102118
103119ScopeValue* ScopeValue::read_from (DebugInfoReadStream* stream) {
104120 ScopeValue* result = nullptr ;
@@ -110,6 +126,7 @@ ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) {
110126 case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue (stream); break ;
111127 case OBJECT_CODE: result = stream->read_object_value (false /* is_auto_box*/ ); break ;
112128 case AUTO_BOX_OBJECT_CODE: result = stream->read_object_value (true /* is_auto_box*/ ); break ;
129+ case OBJECT_MERGE_CODE: result = stream->read_object_merge_value (); break ;
113130 case OBJECT_ID_CODE: result = stream->get_cached_object (); break ;
114131 case MARKER_CODE: result = new MarkerValue (); break ;
115132 default : ShouldNotReachHere ();
@@ -149,6 +166,7 @@ void ObjectValue::set_value(oop value) {
149166}
150167
151168void ObjectValue::read_object (DebugInfoReadStream* stream) {
169+ _is_root = stream->read_bool ();
152170 _klass = read_from (stream);
153171 assert (_klass->is_constant_oop (), " should be constant java mirror oop" );
154172 int length = stream->read_int ();
@@ -166,6 +184,7 @@ void ObjectValue::write_on(DebugInfoWriteStream* stream) {
166184 set_visited (true );
167185 stream->write_int (is_auto_box () ? AUTO_BOX_OBJECT_CODE : OBJECT_CODE);
168186 stream->write_int (_id);
187+ stream->write_bool (_is_root);
169188 _klass->write_on (stream);
170189 int length = _field_values.length ();
171190 stream->write_int (length);
@@ -176,21 +195,106 @@ void ObjectValue::write_on(DebugInfoWriteStream* stream) {
176195}
177196
178197void ObjectValue::print_on (outputStream* st) const {
179- st->print (" %s[%d]" , is_auto_box () ? " box_obj" : " obj" , _id);
198+ st->print (" %s[%d]" , is_auto_box () ? " box_obj" : is_object_merge () ? " merge_obj " : " obj" , _id);
180199}
181200
182201void ObjectValue::print_fields_on (outputStream* st) const {
183202#ifndef PRODUCT
184- if (_field_values.length () > 0 ) {
185- _field_values.at (0 )->print_on (st);
186- }
187- for (int i = 1 ; i < _field_values.length (); i++) {
188- st->print (" , " );
189- _field_values.at (i)->print_on (st);
203+ if (is_object_merge ()) {
204+ ObjectMergeValue* omv = (ObjectMergeValue*)this ;
205+ st->print (" selector=\" " );
206+ omv->selector ()->print_on (st);
207+ st->print (" \" " );
208+ ScopeValue* merge_pointer = omv->merge_pointer ();
209+ if (!(merge_pointer->is_object () && merge_pointer->as_ObjectValue ()->value ()() == nullptr ) &&
210+ !(merge_pointer->is_constant_oop () && merge_pointer->as_ConstantOopReadValue ()->value ()() == nullptr )) {
211+ st->print (" , merge_pointer=\" " );
212+ merge_pointer->print_on (st);
213+ st->print (" \" " );
214+ }
215+ GrowableArray<ScopeValue*>* possible_objects = omv->possible_objects ();
216+ st->print (" , candidate_objs=[%d" , possible_objects->at (0 )->as_ObjectValue ()->id ());
217+ int ncandidates = possible_objects->length ();
218+ for (int i = 1 ; i < ncandidates; i++) {
219+ st->print (" , %d" , possible_objects->at (i)->as_ObjectValue ()->id ());
220+ }
221+ st->print (" ]" );
222+ } else {
223+ st->print (" \n Fields: " );
224+ if (_field_values.length () > 0 ) {
225+ _field_values.at (0 )->print_on (st);
226+ }
227+ for (int i = 1 ; i < _field_values.length (); i++) {
228+ st->print (" , " );
229+ _field_values.at (i)->print_on (st);
230+ }
190231 }
191232#endif
192233}
193234
235+
236+ // ObjectMergeValue
237+
238+ // Returns the ObjectValue that should be used for the local that this
239+ // ObjectMergeValue represents. ObjectMergeValue represents allocation
240+ // merges in C2. This method will select which path the allocation merge
241+ // took during execution of the Trap that triggered the rematerialization
242+ // of the object.
243+ ObjectValue* ObjectMergeValue::select (frame& fr, RegisterMap& reg_map) {
244+ StackValue* sv_selector = StackValue::create_stack_value (&fr, ®_map, _selector);
245+ jint selector = sv_selector->get_int ();
246+
247+ // If the selector is '-1' it means that execution followed the path
248+ // where no scalar replacement happened.
249+ // Otherwise, it is the index in _possible_objects array that holds
250+ // the description of the scalar replaced object.
251+ if (selector == -1 ) {
252+ StackValue* sv_merge_pointer = StackValue::create_stack_value (&fr, ®_map, _merge_pointer);
253+ _selected = new ObjectValue (id ());
254+
255+ // Retrieve the pointer to the real object and use it as if we had
256+ // allocated it during the deoptimization
257+ _selected->set_value (sv_merge_pointer->get_obj ()());
258+
259+ // No need to rematerialize
260+ return nullptr ;
261+ } else {
262+ assert (selector < _possible_objects.length (), " sanity" );
263+ _selected = (ObjectValue*) _possible_objects.at (selector);
264+ return _selected;
265+ }
266+ }
267+
268+ void ObjectMergeValue::read_object (DebugInfoReadStream* stream) {
269+ _selector = read_from (stream);
270+ _merge_pointer = read_from (stream);
271+ int ncandidates = stream->read_int ();
272+ for (int i = 0 ; i < ncandidates; i++) {
273+ ScopeValue* result = read_from (stream);
274+ assert (result->is_object (), " Candidate is not an object!" );
275+ ObjectValue* obj = result->as_ObjectValue ();
276+ _possible_objects.append (obj);
277+ }
278+ }
279+
280+ void ObjectMergeValue::write_on (DebugInfoWriteStream* stream) {
281+ if (is_visited ()) {
282+ stream->write_int (OBJECT_ID_CODE);
283+ stream->write_int (_id);
284+ } else {
285+ set_visited (true );
286+ stream->write_int (OBJECT_MERGE_CODE);
287+ stream->write_int (_id);
288+ _selector->write_on (stream);
289+ _merge_pointer->write_on (stream);
290+ int ncandidates = _possible_objects.length ();
291+ stream->write_int (ncandidates);
292+ for (int i = 0 ; i < ncandidates; i++) {
293+ _possible_objects.at (i)->as_ObjectValue ()->write_on (stream);
294+ }
295+ }
296+ }
297+
194298// ConstantIntValue
195299
196300ConstantIntValue::ConstantIntValue (DebugInfoReadStream* stream) {
0 commit comments