src/share/vm/ci/ciReplay.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 8028468 Cdiff src/share/vm/ci/ciReplay.cpp

src/share/vm/ci/ciReplay.cpp

Print this page

        

*** 22,31 **** --- 22,33 ---- */ #include "precompiled.hpp" #include "ci/ciMethodData.hpp" #include "ci/ciReplay.hpp" + #include "ci/ciSymbol.hpp" + #include "ci/ciKlass.hpp" #include "ci/ciUtilities.hpp" #include "compiler/compileBroker.hpp" #include "memory/allocation.inline.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp"
*** 60,69 **** --- 62,79 ---- int interpreter_throwout_count; int invocation_counter; int backedge_counter; } ciMethodRecord; + typedef struct _ciInlineRecord { + const char* klass; + const char* method; + const char* signature; + int inline_depth; + int bci; + } ciInlineRecord; + class CompileReplay; static CompileReplay* replay_state; class CompileReplay : public StackObj { private:
*** 72,81 **** --- 82,94 ---- Handle protection_domain; Handle loader; GrowableArray<ciMethodRecord*> ci_method_records; GrowableArray<ciMethodDataRecord*> ci_method_data_records; + // Use pointer because we may need to retirn inline records + // without destroying. + GrowableArray<ciInlineRecord*>* ci_inline_records; const char* _error_message; char* bufptr; char* buffer;
*** 271,281 **** // Parse a valid klass name and look it up Klass* parse_klass(TRAPS) { const char* str = parse_escaped_string(); Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL); if (klass_name != NULL) { ! Klass* k = SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, THREAD); if (HAS_PENDING_EXCEPTION) { oop throwable = PENDING_EXCEPTION; java_lang_Throwable::print(throwable, tty); tty->cr(); report_error(str); --- 284,299 ---- // Parse a valid klass name and look it up Klass* parse_klass(TRAPS) { const char* str = parse_escaped_string(); Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL); if (klass_name != NULL) { ! Klass* k = NULL; ! if (_iklass != NULL) { ! k = (Klass*)_iklass->find_klass(ciSymbol::make(klass_name->as_C_string()))->constant_encoding(); ! } else { ! k = SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, THREAD); ! } if (HAS_PENDING_EXCEPTION) { oop throwable = PENDING_EXCEPTION; java_lang_Throwable::print(throwable, tty); tty->cr(); report_error(str);
*** 305,314 **** --- 323,337 ---- } // Process each line of the replay file executing each command until // the file ends. void process(TRAPS) { + _imethod = NULL; + _iklass = NULL; + _entry_bci = 0; + _comp_level = 0; + line_no = 1; int pos = 0; int c = getc(stream); while(c != EOF) { if (pos + 1 >= buffer_length) {
*** 394,404 **** return false; } return true; } ! // compile <klass> <name> <signature> <entry_bci> <comp_level> void process_compile(TRAPS) { Method* method = parse_method(CHECK); if (had_error()) return; int entry_bci = parse_int("entry_bci"); const char* comp_level_label = "comp_level"; --- 417,482 ---- return false; } return true; } ! ciKlass* _iklass; ! Method* _imethod; ! int _entry_bci; ! int _comp_level; ! ! // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ... ! void* process_inline(ciMethod* imethod, Method* m, int entry_bci, int comp_level, TRAPS) { ! _imethod = m; ! _iklass = imethod->holder(); ! _entry_bci = entry_bci; ! _comp_level = comp_level; ! line_no = 1; ! int pos = 0; ! int c = getc(stream); ! while(c != EOF) { ! if (pos + 1 >= buffer_length) { ! int newl = buffer_length * 2; ! char* newb = NEW_RESOURCE_ARRAY(char, newl); ! memcpy(newb, buffer, pos); ! buffer = newb; ! buffer_length = newl; ! } ! if (c == '\n') { ! // null terminate it, reset the pointer and process the line ! buffer[pos] = '\0'; ! buffer_end = pos++; ! bufptr = buffer; ! { ! char* cmd = parse_string(); ! if (cmd == NULL || strcmp("compile", cmd) != 0) { ! return NULL; ! } ! process_compile(CHECK_NULL); ! if (ci_inline_records != NULL && ci_inline_records->length() > 0) { ! return ci_inline_records; ! } ! } ! if (had_error()) { ! tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message); ! tty->print_cr("%s", buffer); ! return NULL; ! } ! pos = 0; ! buffer_end = 0; ! line_no++; ! } else if (c == '\r') { ! // skip LF ! } else { ! buffer[pos++] = c; ! } ! c = getc(stream); ! } ! return NULL; ! } ! ! // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ... void process_compile(TRAPS) { Method* method = parse_method(CHECK); if (had_error()) return; int entry_bci = parse_int("entry_bci"); const char* comp_level_label = "comp_level";
*** 408,417 **** --- 486,532 ---- comp_level = CompLevel_full_optimization; } if (!is_valid_comp_level(comp_level)) { return; } + if (_imethod != NULL) { + // Replay Inlinig + if (entry_bci != _entry_bci || comp_level != _comp_level) { + return; + } + const char* iklass_name = _imethod->method_holder()->name()->as_utf8(); + const char* imethod_name = _imethod->name()->as_utf8(); + const char* isignature = _imethod->signature()->as_utf8(); + const char* klass_name = method->method_holder()->name()->as_utf8(); + const char* method_name = method->name()->as_utf8(); + const char* signature = method->signature()->as_utf8(); + if (strcmp(iklass_name, klass_name) != 0 || + strcmp(imethod_name, method_name) != 0 || + strcmp(isignature, signature) != 0) { + return; + } + } + int inline_count = 0; + if (parse_tag_and_count("inline", inline_count)) { + // Record inlining data + ci_inline_records = new GrowableArray<ciInlineRecord*>(); + for (int i = 0; i < inline_count; i++) { + int depth = parse_int("inline_depth"); + int bci = parse_int("inline_bci"); + if (had_error()) { + break; + } + Method* inl_method = parse_method(CHECK); + if (had_error()) { + break; + } + new_ciInlineRecord(inl_method, bci, depth); + } + } + if (_imethod != NULL) { + return; // Replay Inlining + } Klass* k = method->method_holder(); ((InstanceKlass*)k)->initialize(THREAD); if (HAS_PENDING_EXCEPTION) { oop throwable = PENDING_EXCEPTION; java_lang_Throwable::print(throwable, tty);
*** 568,577 **** --- 683,695 ---- case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_NameAndType: case JVM_CONSTANT_Utf8: case JVM_CONSTANT_Integer: case JVM_CONSTANT_Float: + case JVM_CONSTANT_MethodHandle: + case JVM_CONSTANT_MethodType: + case JVM_CONSTANT_InvokeDynamic: if (tag != cp->tag_at(i).value()) { report_error("tag mismatch: wrong class files?"); return; } break;
*** 776,785 **** --- 894,955 ---- } } return NULL; } + // Create and initialize a record for a ciInlineRecord + ciInlineRecord* new_ciInlineRecord(Method* method, int bci, int depth) { + ciInlineRecord* rec = NEW_RESOURCE_OBJ(ciInlineRecord); + rec->klass = method->method_holder()->name()->as_utf8(); + rec->method = method->name()->as_utf8(); + rec->signature = method->signature()->as_utf8(); + rec->bci = bci; + rec->inline_depth = depth; + ci_inline_records->append(rec); + return rec; + } + + // Lookup inlining data for a ciMethod + ciInlineRecord* find_ciInlineRecord(Method* method, int bci, int inline_depth) { + if (ci_inline_records != NULL) { + const char* klass_name = method->method_holder()->name()->as_utf8(); + const char* method_name = method->name()->as_utf8(); + const char* signature = method->signature()->as_utf8(); + for (int i = 0; i < ci_inline_records->length(); i++) { + ciInlineRecord* rec = ci_inline_records->at(i); + if ((rec->bci == bci) && + (rec->inline_depth == inline_depth) && + (strcmp(rec->klass, klass_name) == 0) && + (strcmp(rec->method, method_name) == 0) && + (strcmp(rec->signature, signature) == 0)) { + return rec; + } + } + } + return NULL; + } + + static ciInlineRecord* find_ciInlineRecord(GrowableArray<ciInlineRecord*>* records, + Method* method, int bci, int inline_depth) { + if (records != NULL) { + const char* klass_name = method->method_holder()->name()->as_utf8(); + const char* method_name = method->name()->as_utf8(); + const char* signature = method->signature()->as_utf8(); + for (int i = 0; i < records->length(); i++) { + ciInlineRecord* rec = records->at(i); + if ((rec->bci == bci) && + (rec->inline_depth == inline_depth) && + (strcmp(rec->klass, klass_name) == 0) && + (strcmp(rec->method, method_name) == 0) && + (strcmp(rec->signature, signature) == 0)) { + return rec; + } + } + } + return NULL; + } + const char* error_message() { return _error_message; } void reset() {
*** 843,857 **** Threads::destroy_vm(); vm_exit(exit_code); } int ciReplay::replay_impl(TRAPS) { HandleMark hm; ResourceMark rm; // Make sure we don't run with background compilation ! BackgroundCompilation = false; if (ReplaySuppressInitializers > 2) { // ReplaySuppressInitializers > 2 means that we want to allow // normal VM bootstrap but once we get into the replay itself // don't allow any intializers to be run. --- 1013,1058 ---- Threads::destroy_vm(); vm_exit(exit_code); } + void* ciReplay::load_inline_data(ciMethod* method, int entry_bci, int comp_level) { + if (FLAG_IS_DEFAULT(InlineDataFile)) { + tty->print_cr("ERROR: no inline replay data file specified (use -XX:InlineDataFile=inline_pid12345.txt)."); + return NULL; + } + + VM_ENTRY_MARK; + // Load and parse the replay data + CompileReplay rp(InlineDataFile, THREAD); + if (!rp.can_replay()) { + tty->print_cr("ciReplay: !rp.can_replay()"); + return NULL; + } + void* data = rp.process_inline(method, method->get_Method(), entry_bci, comp_level, THREAD); + if (HAS_PENDING_EXCEPTION) { + oop throwable = PENDING_EXCEPTION; + CLEAR_PENDING_EXCEPTION; + java_lang_Throwable::print(throwable, tty); + tty->cr(); + java_lang_Throwable::print_stack_trace(throwable, tty); + tty->cr(); + return NULL; + } + + if (rp.had_error()) { + tty->print_cr("ciReplay: Failed on %s", rp.error_message()); + return NULL; + } + return data; + } + int ciReplay::replay_impl(TRAPS) { HandleMark hm; ResourceMark rm; // Make sure we don't run with background compilation ! // BackgroundCompilation = false; if (ReplaySuppressInitializers > 2) { // ReplaySuppressInitializers > 2 means that we want to allow // normal VM bootstrap but once we get into the replay itself // don't allow any intializers to be run.
*** 888,898 **** exit_code = 1; } return exit_code; } - void ciReplay::initialize(ciMethodData* m) { if (replay_state == NULL) { return; } --- 1089,1098 ----
*** 937,952 **** bool ciReplay::should_not_inline(ciMethod* method) { if (replay_state == NULL) { return false; } - VM_ENTRY_MARK; // ciMethod without a record shouldn't be inlined. return replay_state->find_ciMethodRecord(method->get_Method()) == NULL; } void ciReplay::initialize(ciMethod* m) { if (replay_state == NULL) { return; } --- 1137,1178 ---- bool ciReplay::should_not_inline(ciMethod* method) { if (replay_state == NULL) { return false; } VM_ENTRY_MARK; // ciMethod without a record shouldn't be inlined. return replay_state->find_ciMethodRecord(method->get_Method()) == NULL; } + bool ciReplay::should_inline(void* data, ciMethod* method, int bci, int inline_depth) { + if (data != NULL) { + GrowableArray<ciInlineRecord*>* records = (GrowableArray<ciInlineRecord*>*)data; + VM_ENTRY_MARK; + // Inline record are ordered by bci and depth. + return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) != NULL; + } else if (replay_state != NULL) { + VM_ENTRY_MARK; + // Inline record are ordered by bci and depth. + return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) != NULL; + } + return false; + } + + bool ciReplay::should_not_inline(void* data, ciMethod* method, int bci, int inline_depth) { + if (data != NULL) { + GrowableArray<ciInlineRecord*>* records = (GrowableArray<ciInlineRecord*>*)data; + VM_ENTRY_MARK; + // Inline record are ordered by bci and depth. + return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) == NULL; + } else if (replay_state != NULL) { + VM_ENTRY_MARK; + // Inline record are ordered by bci and depth. + return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) == NULL; + } + return false; + } void ciReplay::initialize(ciMethod* m) { if (replay_state == NULL) { return; }
src/share/vm/ci/ciReplay.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File