// must call add_safepoint before: it sets PcDesc and this routine uses // the last PcDesc set void DebugInformationRecorder::describe_scope(int pc_offset, ciMethod* method, int bci, bool reexecute, bool is_method_handle_invoke, bool return_oop, DebugToken* locals, DebugToken* expressions, DebugToken* monitors) { 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"); int sender_stream_offset = last_pd->scope_decode_offset(); // update the stream offset of current pc desc int stream_offset = stream()->position(); last_pd->set_scope_decode_offset(stream_offset); // Record flags into pcDesc. last_pd->set_should_reexecute(reexecute); last_pd->set_is_method_handle_invoke(is_method_handle_invoke); last_pd->set_return_oop(return_oop); // serialize sender stream offest stream()->write_int(sender_stream_offset); // serialize scope Metadata* method_enc = (method == NULL)? NULL: method->constant_encoding(); stream()->write_int(oop_recorder()->find_index(method_enc)); stream()->write_bci(bci); assert(method == NULL || (method->is_native() && bci == 0) || (!method->is_native() && 0 <= bci && bci < method->code_size()) || (method->is_compiled_lambda_form() && bci == -99) || // this might happen in C1 bci == -1, "illegal bci"); // serialize the locals/expressions/monitors stream()->write_int((intptr_t) locals); stream()->write_int((intptr_t) expressions); stream()->write_int((intptr_t) monitors); // Here's a tricky bit. We just wrote some bytes. // Wouldn't it be nice to find that we had already // written those same bytes somewhere else? // If we get lucky this way, reset the stream // and reuse the old bytes. By the way, this // trick not only shares parent scopes, but also // compresses equivalent non-safepoint PcDescs. int shared_stream_offset = find_sharable_decode_offset(stream_offset); if (shared_stream_offset != serialized_null) { stream()->set_position(stream_offset); last_pd->set_scope_decode_offset(shared_stream_offset); } }
int DebugInformationRecorder::serialize_scope_values(GrowableArray<ScopeValue*>* values) { if (values == NULL || values->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(values->length()); for (int index = 0; index < values->length(); index++) { values->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; }