Exemplo n.º 1
0
// 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);
    }
}
Exemplo n.º 2
0
 int oop_size() { return oop_recorder()->oop_size(); }
void CodeBuffer::finalize_oop_references(methodHandle mh) {
  No_Safepoint_Verifier nsv;

  GrowableArray<oop> oops;

  // Make sure that immediate metadata records something in the OopRecorder
  for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
    // pull code out of each section
    CodeSection* cs = code_section(n);
    if (cs->is_empty())  continue;  // skip trivial section
    RelocIterator iter(cs);
    while (iter.next()) {
      if (iter.type() == relocInfo::metadata_type) {
        metadata_Relocation* md = iter.metadata_reloc();
        if (md->metadata_is_immediate()) {
          Metadata* m = md->metadata_value();
          if (oop_recorder()->is_real(m)) {
            if (m->is_methodData()) {
              m = ((MethodData*)m)->method();
            }
            if (m->is_method()) {
              m = ((Method*)m)->method_holder();
            }
            if (m->is_klass()) {
              append_oop_references(&oops, (Klass*)m);
            } else {
              // XXX This will currently occur for MDO which don't
              // have a backpointer.  This has to be fixed later.
              m->print();
              ShouldNotReachHere();
            }
          }
        }
      }
    }
  }

  if (!oop_recorder()->is_unused()) {
    for (int i = 0; i < oop_recorder()->metadata_count(); i++) {
      Metadata* m = oop_recorder()->metadata_at(i);
      if (oop_recorder()->is_real(m)) {
        if (m->is_methodData()) {
          m = ((MethodData*)m)->method();
        }
        if (m->is_method()) {
          m = ((Method*)m)->method_holder();
        }
        if (m->is_klass()) {
          append_oop_references(&oops, (Klass*)m);
        } else {
          m->print();
          ShouldNotReachHere();
        }
      }
    }

  }

  // Add the class loader of Method* for the nmethod itself
  append_oop_references(&oops, mh->method_holder());

  // Add any oops that we've found
  Thread* thread = Thread::current();
  for (int i = 0; i < oops.length(); i++) {
    oop_recorder()->find_index((jobject)thread->handle_area()->allocate_handle(oops.at(i)));
  }
}