Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8271911: replay compilations of methods which use JSR292 (easy cases) #5270

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view

Large diffs are not rendered by default.

@@ -44,9 +44,10 @@ class OopMapSet;
// to the VM.
class ciEnv : StackObj {
CI_PACKAGE_ACCESS_TO

friend class CompileBroker;
friend class Dependencies; // for get_object, during logging
friend class LocPusher;
friend class FieldPusher;
friend class PrepareExtraDataClosure;

private:
@@ -460,12 +461,49 @@ class ciEnv : StackObj {
// RedefineClasses support
void metadata_do(MetadataClosure* f) { _factory->metadata_do(f); }

// Replay support
private:
static int klass_compare(const InstanceKlass* const &ik1, const InstanceKlass* const &ik2) {
if (ik1 > ik2) {
return 1;
} else if (ik1 < ik2) {
return -1;
} else {
return 0;
}
}
bool dyno_loc(const InstanceKlass* ik, const char *&loc) const;
void set_dyno_loc(const InstanceKlass* ik);
void record_best_dyno_loc(const InstanceKlass* ik);
bool print_dyno_loc(outputStream* out, const InstanceKlass* ik) const;

GrowableArray<const InstanceKlass*>* _dyno_klasses;
GrowableArray<const char *>* _dyno_locs;

#define MAX_DYNO_NAME_LENGTH 1024
char _dyno_name[MAX_DYNO_NAME_LENGTH+1];

public:
// Dump the compilation replay data for the ciEnv to the stream.
void dump_replay_data(int compile_id);
void dump_inline_data(int compile_id);
void dump_replay_data(outputStream* out);
void dump_replay_data_unsafe(outputStream* out);
void dump_replay_data_helper(outputStream* out);
void dump_compile_data(outputStream* out);

const char *dyno_name(const InstanceKlass* ik) const;
const char *replay_name(const InstanceKlass* ik) const;
const char *replay_name(ciKlass* i) const;

void record_lambdaform(Thread* thread, oop obj);
void record_member(Thread* thread, oop obj);
void record_mh(Thread* thread, oop obj);
void record_call_site_obj(Thread* thread, const constantPoolHandle& pool, const Handle appendix);
void record_call_site_method(Thread* thread, const constantPoolHandle& pool, Method* adapter);
void process_invokedynamic(const constantPoolHandle &cp, int index, JavaThread* thread);
void process_invokehandle(const constantPoolHandle &cp, int index, JavaThread* thread);
void find_dynamic_call_sites();
};

#endif // SHARE_CI_CIENV_HPP
@@ -731,6 +731,9 @@ class StaticFinalFieldPrinter : public FieldClosure {
}
};

const char *ciInstanceKlass::replay_name() const {
return CURRENT_ENV->replay_name(get_instanceKlass());
}

void ciInstanceKlass::dump_replay_data(outputStream* out) {
ResourceMark rm;
@@ -741,8 +744,18 @@ void ciInstanceKlass::dump_replay_data(outputStream* out) {
// Try to record related loaded classes
Klass* sub = ik->subklass();
while (sub != NULL) {
if (sub->is_instance_klass() && !sub->is_hidden()) {
out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
if (sub->is_instance_klass()) {
InstanceKlass *isub = InstanceKlass::cast(sub);
if (isub->is_hidden()) {
const char *name = CURRENT_ENV->dyno_name(isub);
if (name != NULL) {
out->print_cr("instanceKlass %s # %s", name, sub->name()->as_quoted_ascii());
} else {
out->print_cr("# instanceKlass %s", sub->name()->as_quoted_ascii());
}
} else {
out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
}
}
sub = sub->next_sibling();
}
@@ -751,7 +764,8 @@ void ciInstanceKlass::dump_replay_data(outputStream* out) {
// tags will be validated for things which shouldn't change and
// classes will be resolved if the tags indicate that they were
// resolved at compile time.
out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(),
const char *name = replay_name();
out->print("ciInstanceKlass %s %d %d %d", name,
is_linked(), is_initialized(), cp->length());
for (int index = 1; index < cp->length(); index++) {
out->print(" %d", cp->tags()->at(index));
@@ -760,7 +774,7 @@ void ciInstanceKlass::dump_replay_data(outputStream* out) {
if (is_initialized()) {
// Dump out the static final fields in case the compilation relies
// on their value for correct replay.
StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii());
StaticFinalFieldPrinter sffp(out, name);
ik->do_local_static_fields(&sffp);
}
}
@@ -293,9 +293,14 @@ class ciInstanceKlass : public ciKlass {
return !is_interface() && !is_abstract();
}

// Replay support

// Dump the current state of this klass for compilation replay.
virtual void dump_replay_data(outputStream* out);

// Return stable class name suitable for replay file.
const char *replay_name() const;

#ifdef ASSERT
bool debug_final_field_at(int offset);
bool debug_stable_field_at(int offset);
@@ -70,6 +70,7 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
_holder(holder)
{
assert(h_m() != NULL, "no null method");
assert(_holder->get_instanceKlass() == h_m->method_holder(), "");

if (LogTouchedMethods) {
h_m->log_touched(Thread::current());
@@ -1288,17 +1289,25 @@ ciMethodBlocks *ciMethod::get_method_blocks() {

#undef FETCH_FLAG_FROM_VM

void ciMethod::dump_name_as_ascii(outputStream* st) {
Method* method = get_Method();
void ciMethod::dump_name_as_ascii(outputStream* st, Method* method) {
st->print("%s %s %s",
method->klass_name()->as_quoted_ascii(),
CURRENT_ENV->replay_name(method->method_holder()),
method->name()->as_quoted_ascii(),
method->signature()->as_quoted_ascii());
}

void ciMethod::dump_name_as_ascii(outputStream* st) {
Method* method = get_Method();
dump_name_as_ascii(st, method);
}

void ciMethod::dump_replay_data(outputStream* st) {
ResourceMark rm;
Method* method = get_Method();
if (MethodHandles::is_signature_polymorphic_method(method)) {
// ignore for now
return;
}
MethodCounters* mcs = method->method_counters();
st->print("ciMethod ");
dump_name_as_ascii(st);
@@ -365,6 +365,7 @@ class ciMethod : public ciMetadata {
bool can_be_statically_bound(ciInstanceKlass* context) const;

// Replay data methods
static void dump_name_as_ascii(outputStream* st, Method* method);
void dump_name_as_ascii(outputStream* st);
void dump_replay_data(outputStream* st);

@@ -647,7 +647,8 @@ void ciMethodData::dump_replay_data_type_helper(outputStream* out, int round, in
if (round == 0) {
count++;
} else {
out->print(" %d %s", (int)(dp_to_di(pdata->dp() + in_bytes(offset)) / sizeof(intptr_t)), k->name()->as_quoted_ascii());
out->print(" %d %s", (int)(dp_to_di(pdata->dp() + in_bytes(offset)) / sizeof(intptr_t)),
CURRENT_ENV->replay_name(k));
}
}
}
@@ -703,13 +704,9 @@ void ciMethodData::dump_replay_data(outputStream* out) {
ResourceMark rm;
MethodData* mdo = get_MethodData();
Method* method = mdo->method();
Klass* holder = method->method_holder();
out->print("ciMethodData %s %s %s %d %d",
holder->name()->as_quoted_ascii(),
method->name()->as_quoted_ascii(),
method->signature()->as_quoted_ascii(),
_state,
current_mileage());
out->print("ciMethodData ");
ciMethod::dump_name_as_ascii(out, method);
out->print(" %d %d", _state, current_mileage());

// dump the contents of the MDO header as raw data
unsigned char* orig = (unsigned char*)&_orig;