1 /*
   2  * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "ci/ciMethodData.hpp"
  28 #include "ci/ciReplay.hpp"
  29 #include "ci/ciSymbol.hpp"
  30 #include "ci/ciKlass.hpp"
  31 #include "ci/ciUtilities.inline.hpp"
  32 #include "compiler/compileBroker.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/oopFactory.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "oops/method.inline.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "runtime/fieldDescriptor.inline.hpp"
  39 #include "runtime/handles.inline.hpp"
  40 #include "utilities/copy.hpp"
  41 #include "utilities/macros.hpp"
  42 
  43 #ifndef PRODUCT
  44 
  45 // ciReplay
  46 
  47 typedef struct _ciMethodDataRecord {
  48   const char* _klass_name;
  49   const char* _method_name;
  50   const char* _signature;
  51 
  52   int _state;
  53   int _current_mileage;
  54 
  55   intptr_t* _data;
  56   char*     _orig_data;
  57   Klass**   _classes;
  58   Method**  _methods;
  59   int*      _classes_offsets;
  60   int*      _methods_offsets;
  61   int       _data_length;
  62   int       _orig_data_length;
  63   int       _classes_length;
  64   int       _methods_length;
  65 } ciMethodDataRecord;
  66 
  67 typedef struct _ciMethodRecord {
  68   const char* _klass_name;
  69   const char* _method_name;
  70   const char* _signature;
  71 
  72   int _instructions_size;
  73   int _interpreter_invocation_count;
  74   int _interpreter_throwout_count;
  75   int _invocation_counter;
  76   int _backedge_counter;
  77 } ciMethodRecord;
  78 
  79 typedef struct _ciInlineRecord {
  80   const char* _klass_name;
  81   const char* _method_name;
  82   const char* _signature;
  83 
  84   int _inline_depth;
  85   int _inline_bci;
  86 } ciInlineRecord;
  87 
  88 class  CompileReplay;
  89 static CompileReplay* replay_state;
  90 
  91 class CompileReplay : public StackObj {
  92  private:
  93   FILE*   _stream;
  94   Thread* _thread;
  95   Handle  _protection_domain;
  96   Handle  _loader;
  97 
  98   GrowableArray<ciMethodRecord*>     _ci_method_records;
  99   GrowableArray<ciMethodDataRecord*> _ci_method_data_records;
 100 
 101   // Use pointer because we may need to return inline records
 102   // without destroying them.
 103   GrowableArray<ciInlineRecord*>*    _ci_inline_records;
 104 
 105   const char* _error_message;
 106 
 107   char* _bufptr;
 108   char* _buffer;
 109   int   _buffer_length;
 110   int   _buffer_pos;
 111 
 112   // "compile" data
 113   ciKlass* _iklass;
 114   Method*  _imethod;
 115   int      _entry_bci;
 116   int      _comp_level;
 117 
 118  public:
 119   CompileReplay(const char* filename, TRAPS) {
 120     _thread = THREAD;
 121     _loader = Handle(_thread, SystemDictionary::java_system_loader());
 122     _protection_domain = Handle();
 123 
 124     _stream = fopen(filename, "rt");
 125     if (_stream == NULL) {
 126       fprintf(stderr, "ERROR: Can't open replay file %s\n", filename);
 127     }
 128 
 129     _ci_inline_records = NULL;
 130     _error_message = NULL;
 131 
 132     _buffer_length = 32;
 133     _buffer = NEW_RESOURCE_ARRAY(char, _buffer_length);
 134     _bufptr = _buffer;
 135     _buffer_pos = 0;
 136 
 137     _imethod = NULL;
 138     _iklass  = NULL;
 139     _entry_bci  = 0;
 140     _comp_level = 0;
 141 
 142     test();
 143   }
 144 
 145   ~CompileReplay() {
 146     if (_stream != NULL) fclose(_stream);
 147   }
 148 
 149   void test() {
 150     strcpy(_buffer, "1 2 foo 4 bar 0x9 \"this is it\"");
 151     _bufptr = _buffer;
 152     assert(parse_int("test") == 1, "what");
 153     assert(parse_int("test") == 2, "what");
 154     assert(strcmp(parse_string(), "foo") == 0, "what");
 155     assert(parse_int("test") == 4, "what");
 156     assert(strcmp(parse_string(), "bar") == 0, "what");
 157     assert(parse_intptr_t("test") == 9, "what");
 158     assert(strcmp(parse_quoted_string(), "this is it") == 0, "what");
 159   }
 160 
 161   bool had_error() {
 162     return _error_message != NULL || _thread->has_pending_exception();
 163   }
 164 
 165   bool can_replay() {
 166     return !(_stream == NULL || had_error());
 167   }
 168 
 169   void report_error(const char* msg) {
 170     _error_message = msg;
 171     // Restore the _buffer contents for error reporting
 172     for (int i = 0; i < _buffer_pos; i++) {
 173       if (_buffer[i] == '\0') _buffer[i] = ' ';
 174     }
 175   }
 176 
 177   int parse_int(const char* label) {
 178     if (had_error()) {
 179       return 0;
 180     }
 181 
 182     int v = 0;
 183     int read;
 184     if (sscanf(_bufptr, "%i%n", &v, &read) != 1) {
 185       report_error(label);
 186     } else {
 187       _bufptr += read;
 188     }
 189     return v;
 190   }
 191 
 192   intptr_t parse_intptr_t(const char* label) {
 193     if (had_error()) {
 194       return 0;
 195     }
 196 
 197     intptr_t v = 0;
 198     int read;
 199     if (sscanf(_bufptr, INTPTR_FORMAT "%n", &v, &read) != 1) {
 200       report_error(label);
 201     } else {
 202       _bufptr += read;
 203     }
 204     return v;
 205   }
 206 
 207   void skip_ws() {
 208     // Skip any leading whitespace
 209     while (*_bufptr == ' ' || *_bufptr == '\t') {
 210       _bufptr++;
 211     }
 212   }
 213 
 214 
 215   char* scan_and_terminate(char delim) {
 216     char* str = _bufptr;
 217     while (*_bufptr != delim && *_bufptr != '\0') {
 218       _bufptr++;
 219     }
 220     if (*_bufptr != '\0') {
 221       *_bufptr++ = '\0';
 222     }
 223     if (_bufptr == str) {
 224       // nothing here
 225       return NULL;
 226     }
 227     return str;
 228   }
 229 
 230   char* parse_string() {
 231     if (had_error()) return NULL;
 232 
 233     skip_ws();
 234     return scan_and_terminate(' ');
 235   }
 236 
 237   char* parse_quoted_string() {
 238     if (had_error()) return NULL;
 239 
 240     skip_ws();
 241 
 242     if (*_bufptr == '"') {
 243       _bufptr++;
 244       return scan_and_terminate('"');
 245     } else {
 246       return scan_and_terminate(' ');
 247     }
 248   }
 249 
 250   const char* parse_escaped_string() {
 251     char* result = parse_quoted_string();
 252     if (result != NULL) {
 253       unescape_string(result);
 254     }
 255     return result;
 256   }
 257 
 258   // Look for the tag 'tag' followed by an
 259   bool parse_tag_and_count(const char* tag, int& length) {
 260     const char* t = parse_string();
 261     if (t == NULL) {
 262       return false;
 263     }
 264 
 265     if (strcmp(tag, t) != 0) {
 266       report_error(tag);
 267       return false;
 268     }
 269     length = parse_int("parse_tag_and_count");
 270     return !had_error();
 271   }
 272 
 273   // Parse a sequence of raw data encoded as bytes and return the
 274   // resulting data.
 275   char* parse_data(const char* tag, int& length) {
 276     int read_size = 0;
 277     if (!parse_tag_and_count(tag, read_size)) {
 278       return NULL;
 279     }
 280 
 281     int actual_size = sizeof(MethodData);
 282     char *result = NEW_RESOURCE_ARRAY(char, actual_size);
 283     int i = 0;
 284     if (read_size != actual_size) {
 285       tty->print_cr("Warning: ciMethodData parsing sees MethodData size %i in file, current is %i", read_size,
 286                     actual_size);
 287       // Replay serializes the entire MethodData, but the data is at the end.
 288       // If the MethodData instance size has changed, we can pad or truncate in the beginning
 289       int padding = actual_size - read_size;
 290       if (padding > 0) {
 291         // pad missing data with zeros
 292         tty->print_cr("- Padding MethodData");
 293         for (; i < padding; i++) {
 294           result[i] = 0;
 295         }
 296       } else if (padding < 0) {
 297         // drop some data
 298         tty->print_cr("- Truncating MethodData");
 299         for (int j = 0; j < -padding; j++) {
 300           int val = parse_int("data");
 301           // discard val
 302         }
 303       }
 304     }
 305 
 306     assert(i < actual_size, "At least some data must remain to be copied");
 307     for (; i < actual_size; i++) {
 308       int val = parse_int("data");
 309       result[i] = val;
 310     }
 311     length = actual_size;
 312     return result;
 313   }
 314 
 315   // Parse a standard chunk of data emitted as:
 316   //   'tag' <length> # # ...
 317   // Where each # is an intptr_t item
 318   intptr_t* parse_intptr_data(const char* tag, int& length) {
 319     if (!parse_tag_and_count(tag, length)) {
 320       return NULL;
 321     }
 322 
 323     intptr_t* result = NEW_RESOURCE_ARRAY(intptr_t, length);
 324     for (int i = 0; i < length; i++) {
 325       skip_ws();
 326       intptr_t val = parse_intptr_t("data");
 327       result[i] = val;
 328     }
 329     return result;
 330   }
 331 
 332   // Parse a possibly quoted version of a symbol into a symbolOop
 333   Symbol* parse_symbol(TRAPS) {
 334     const char* str = parse_escaped_string();
 335     if (str != NULL) {
 336       Symbol* sym = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
 337       return sym;
 338     }
 339     return NULL;
 340   }
 341 
 342   // Parse a valid klass name and look it up
 343   Klass* parse_klass(TRAPS) {
 344     const char* str = parse_escaped_string();
 345     Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
 346     if (klass_name != NULL) {
 347       Klass* k = NULL;
 348       if (_iklass != NULL) {
 349         k = (Klass*)_iklass->find_klass(ciSymbol::make(klass_name->as_C_string()))->constant_encoding();
 350       } else {
 351         k = SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD);
 352       }
 353       if (HAS_PENDING_EXCEPTION) {
 354         oop throwable = PENDING_EXCEPTION;
 355         java_lang_Throwable::print(throwable, tty);
 356         tty->cr();
 357         report_error(str);
 358         if (ReplayIgnoreInitErrors) {
 359           CLEAR_PENDING_EXCEPTION;
 360           _error_message = NULL;
 361         }
 362         return NULL;
 363       }
 364       return k;
 365     }
 366     return NULL;
 367   }
 368 
 369   // Lookup a klass
 370   Klass* resolve_klass(const char* klass, TRAPS) {
 371     Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL);
 372     return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD);
 373   }
 374 
 375   // Parse the standard tuple of <klass> <name> <signature>
 376   Method* parse_method(TRAPS) {
 377     InstanceKlass* k = (InstanceKlass*)parse_klass(CHECK_NULL);
 378     if (k == NULL) {
 379       report_error("Can't find holder klass");
 380       return NULL;
 381     }
 382     Symbol* method_name = parse_symbol(CHECK_NULL);
 383     Symbol* method_signature = parse_symbol(CHECK_NULL);
 384     Method* m = k->find_method(method_name, method_signature);
 385     if (m == NULL) {
 386       report_error("Can't find method");
 387     }
 388     return m;
 389   }
 390 
 391   int get_line(int c) {
 392     while(c != EOF) {
 393       if (_buffer_pos + 1 >= _buffer_length) {
 394         int new_length = _buffer_length * 2;
 395         // Next call will throw error in case of OOM.
 396         _buffer = REALLOC_RESOURCE_ARRAY(char, _buffer, _buffer_length, new_length);
 397         _buffer_length = new_length;
 398       }
 399       if (c == '\n') {
 400         c = getc(_stream); // get next char
 401         break;
 402       } else if (c == '\r') {
 403         // skip LF
 404       } else {
 405         _buffer[_buffer_pos++] = c;
 406       }
 407       c = getc(_stream);
 408     }
 409     // null terminate it, reset the pointer
 410     _buffer[_buffer_pos] = '\0'; // NL or EOF
 411     _buffer_pos = 0;
 412     _bufptr = _buffer;
 413     return c;
 414   }
 415 
 416   // Process each line of the replay file executing each command until
 417   // the file ends.
 418   void process(TRAPS) {
 419     int line_no = 1;
 420     int c = getc(_stream);
 421     while(c != EOF) {
 422       c = get_line(c);
 423       process_command(THREAD);
 424       if (had_error()) {
 425         tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
 426         if (ReplayIgnoreInitErrors) {
 427           CLEAR_PENDING_EXCEPTION;
 428           _error_message = NULL;
 429         } else {
 430           return;
 431         }
 432       }
 433       line_no++;
 434     }
 435   }
 436 
 437   void process_command(TRAPS) {
 438     char* cmd = parse_string();
 439     if (cmd == NULL) {
 440       return;
 441     }
 442     if (strcmp("#", cmd) == 0) {
 443       // ignore
 444     } else if (strcmp("compile", cmd) == 0) {
 445       process_compile(CHECK);
 446     } else if (strcmp("ciMethod", cmd) == 0) {
 447       process_ciMethod(CHECK);
 448     } else if (strcmp("ciMethodData", cmd) == 0) {
 449       process_ciMethodData(CHECK);
 450     } else if (strcmp("staticfield", cmd) == 0) {
 451       process_staticfield(CHECK);
 452     } else if (strcmp("ciInstanceKlass", cmd) == 0) {
 453       process_ciInstanceKlass(CHECK);
 454     } else if (strcmp("instanceKlass", cmd) == 0) {
 455       process_instanceKlass(CHECK);
 456 #if INCLUDE_JVMTI
 457     } else if (strcmp("JvmtiExport", cmd) == 0) {
 458       process_JvmtiExport(CHECK);
 459 #endif // INCLUDE_JVMTI
 460     } else {
 461       report_error("unknown command");
 462     }
 463   }
 464 
 465   // validation of comp_level
 466   bool is_valid_comp_level(int comp_level) {
 467     const int msg_len = 256;
 468     char* msg = NULL;
 469     if (!is_compile(comp_level)) {
 470       msg = NEW_RESOURCE_ARRAY(char, msg_len);
 471       jio_snprintf(msg, msg_len, "%d isn't compilation level", comp_level);
 472     } else if (!TieredCompilation && (comp_level != CompLevel_highest_tier)) {
 473       msg = NEW_RESOURCE_ARRAY(char, msg_len);
 474       switch (comp_level) {
 475         case CompLevel_simple:
 476           jio_snprintf(msg, msg_len, "compilation level %d requires Client VM or TieredCompilation", comp_level);
 477           break;
 478         case CompLevel_full_optimization:
 479           jio_snprintf(msg, msg_len, "compilation level %d requires Server VM", comp_level);
 480           break;
 481         default:
 482           jio_snprintf(msg, msg_len, "compilation level %d requires TieredCompilation", comp_level);
 483       }
 484     }
 485     if (msg != NULL) {
 486       report_error(msg);
 487       return false;
 488     }
 489     return true;
 490   }
 491 
 492   // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ...
 493   void* process_inline(ciMethod* imethod, Method* m, int entry_bci, int comp_level, TRAPS) {
 494     _imethod    = m;
 495     _iklass     = imethod->holder();
 496     _entry_bci  = entry_bci;
 497     _comp_level = comp_level;
 498     int line_no = 1;
 499     int c = getc(_stream);
 500     while(c != EOF) {
 501       c = get_line(c);
 502       // Expecting only lines with "compile" command in inline replay file.
 503       char* cmd = parse_string();
 504       if (cmd == NULL || strcmp("compile", cmd) != 0) {
 505         return NULL;
 506       }
 507       process_compile(CHECK_NULL);
 508       if (had_error()) {
 509         tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
 510         tty->print_cr("%s", _buffer);
 511         return NULL;
 512       }
 513       if (_ci_inline_records != NULL && _ci_inline_records->length() > 0) {
 514         // Found inlining record for the requested method.
 515         return _ci_inline_records;
 516       }
 517       line_no++;
 518     }
 519     return NULL;
 520   }
 521 
 522   // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ...
 523   void process_compile(TRAPS) {
 524     Method* method = parse_method(CHECK);
 525     if (had_error()) return;
 526     int entry_bci = parse_int("entry_bci");
 527     const char* comp_level_label = "comp_level";
 528     int comp_level = parse_int(comp_level_label);
 529     // old version w/o comp_level
 530     if (had_error() && (error_message() == comp_level_label)) {
 531       // use highest available tier
 532       comp_level = TieredCompilation ? TieredStopAtLevel : CompLevel_highest_tier;
 533     }
 534     if (!is_valid_comp_level(comp_level)) {
 535       return;
 536     }
 537     if (_imethod != NULL) {
 538       // Replay Inlining
 539       if (entry_bci != _entry_bci || comp_level != _comp_level) {
 540         return;
 541       }
 542       const char* iklass_name  = _imethod->method_holder()->name()->as_utf8();
 543       const char* imethod_name = _imethod->name()->as_utf8();
 544       const char* isignature   = _imethod->signature()->as_utf8();
 545       const char* klass_name   = method->method_holder()->name()->as_utf8();
 546       const char* method_name  = method->name()->as_utf8();
 547       const char* signature    = method->signature()->as_utf8();
 548       if (strcmp(iklass_name,  klass_name)  != 0 ||
 549           strcmp(imethod_name, method_name) != 0 ||
 550           strcmp(isignature,   signature)   != 0) {
 551         return;
 552       }
 553     }
 554     int inline_count = 0;
 555     if (parse_tag_and_count("inline", inline_count)) {
 556       // Record inlining data
 557       _ci_inline_records = new GrowableArray<ciInlineRecord*>();
 558       for (int i = 0; i < inline_count; i++) {
 559         int depth = parse_int("inline_depth");
 560         int bci = parse_int("inline_bci");
 561         if (had_error()) {
 562           break;
 563         }
 564         Method* inl_method = parse_method(CHECK);
 565         if (had_error()) {
 566           break;
 567         }
 568         new_ciInlineRecord(inl_method, bci, depth);
 569       }
 570     }
 571     if (_imethod != NULL) {
 572       return; // Replay Inlining
 573     }
 574     InstanceKlass* ik = method->method_holder();
 575     ik->initialize(THREAD);
 576     if (HAS_PENDING_EXCEPTION) {
 577       oop throwable = PENDING_EXCEPTION;
 578       java_lang_Throwable::print(throwable, tty);
 579       tty->cr();
 580       if (ReplayIgnoreInitErrors) {
 581         CLEAR_PENDING_EXCEPTION;
 582         ik->set_init_state(InstanceKlass::fully_initialized);
 583       } else {
 584         return;
 585       }
 586     }
 587     // Make sure the existence of a prior compile doesn't stop this one
 588     CompiledMethod* nm = (entry_bci != InvocationEntryBci) ? method->lookup_osr_nmethod_for(entry_bci, comp_level, true) : method->code();
 589     if (nm != NULL) {
 590       nm->make_not_entrant();
 591     }
 592     replay_state = this;
 593     CompileBroker::compile_method(method, entry_bci, comp_level,
 594                                   methodHandle(), 0, CompileTask::Reason_Replay, THREAD);
 595     replay_state = NULL;
 596     reset();
 597   }
 598 
 599   // ciMethod <klass> <name> <signature> <invocation_counter> <backedge_counter> <interpreter_invocation_count> <interpreter_throwout_count> <instructions_size>
 600   //
 601   //
 602   void process_ciMethod(TRAPS) {
 603     Method* method = parse_method(CHECK);
 604     if (had_error()) return;
 605     ciMethodRecord* rec = new_ciMethod(method);
 606     rec->_invocation_counter = parse_int("invocation_counter");
 607     rec->_backedge_counter = parse_int("backedge_counter");
 608     rec->_interpreter_invocation_count = parse_int("interpreter_invocation_count");
 609     rec->_interpreter_throwout_count = parse_int("interpreter_throwout_count");
 610     rec->_instructions_size = parse_int("instructions_size");
 611   }
 612 
 613   // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length> # ... methods <length>
 614   void process_ciMethodData(TRAPS) {
 615     Method* method = parse_method(CHECK);
 616     if (had_error()) return;
 617     /* just copied from Method, to build interpret data*/
 618 
 619     // To be properly initialized, some profiling in the MDO needs the
 620     // method to be rewritten (number of arguments at a call for
 621     // instance)
 622     method->method_holder()->link_class(CHECK);
 623     // methodOopDesc::build_interpreter_method_data(method, CHECK);
 624     {
 625       // Grab a lock here to prevent multiple
 626       // MethodData*s from being created.
 627       MutexLocker ml(MethodData_lock, THREAD);
 628       if (method->method_data() == NULL) {
 629         ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
 630         MethodData* method_data = MethodData::allocate(loader_data, method, CHECK);
 631         method->set_method_data(method_data);
 632       }
 633     }
 634 
 635     // collect and record all the needed information for later
 636     ciMethodDataRecord* rec = new_ciMethodData(method);
 637     rec->_state = parse_int("state");
 638     rec->_current_mileage = parse_int("current_mileage");
 639 
 640     rec->_orig_data = parse_data("orig", rec->_orig_data_length);
 641     if (rec->_orig_data == NULL) {
 642       return;
 643     }
 644     rec->_data = parse_intptr_data("data", rec->_data_length);
 645     if (rec->_data == NULL) {
 646       return;
 647     }
 648     if (!parse_tag_and_count("oops", rec->_classes_length)) {
 649       return;
 650     }
 651     rec->_classes = NEW_RESOURCE_ARRAY(Klass*, rec->_classes_length);
 652     rec->_classes_offsets = NEW_RESOURCE_ARRAY(int, rec->_classes_length);
 653     for (int i = 0; i < rec->_classes_length; i++) {
 654       int offset = parse_int("offset");
 655       if (had_error()) {
 656         return;
 657       }
 658       Klass* k = parse_klass(CHECK);
 659       rec->_classes_offsets[i] = offset;
 660       rec->_classes[i] = k;
 661     }
 662 
 663     if (!parse_tag_and_count("methods", rec->_methods_length)) {
 664       return;
 665     }
 666     rec->_methods = NEW_RESOURCE_ARRAY(Method*, rec->_methods_length);
 667     rec->_methods_offsets = NEW_RESOURCE_ARRAY(int, rec->_methods_length);
 668     for (int i = 0; i < rec->_methods_length; i++) {
 669       int offset = parse_int("offset");
 670       if (had_error()) {
 671         return;
 672       }
 673       Method* m = parse_method(CHECK);
 674       rec->_methods_offsets[i] = offset;
 675       rec->_methods[i] = m;
 676     }
 677   }
 678 
 679   // instanceKlass <name>
 680   //
 681   // Loads and initializes the klass 'name'.  This can be used to
 682   // create particular class loading environments
 683   void process_instanceKlass(TRAPS) {
 684     // just load the referenced class
 685     Klass* k = parse_klass(CHECK);
 686   }
 687 
 688   // ciInstanceKlass <name> <is_linked> <is_initialized> <length> tag # # # ...
 689   //
 690   // Load the klass 'name' and link or initialize it.  Verify that the
 691   // constant pool is the same length as 'length' and make sure the
 692   // constant pool tags are in the same state.
 693   void process_ciInstanceKlass(TRAPS) {
 694     InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
 695     if (k == NULL) {
 696       return;
 697     }
 698     int is_linked = parse_int("is_linked");
 699     int is_initialized = parse_int("is_initialized");
 700     int length = parse_int("length");
 701     if (is_initialized) {
 702       k->initialize(THREAD);
 703       if (HAS_PENDING_EXCEPTION) {
 704         oop throwable = PENDING_EXCEPTION;
 705         java_lang_Throwable::print(throwable, tty);
 706         tty->cr();
 707         if (ReplayIgnoreInitErrors) {
 708           CLEAR_PENDING_EXCEPTION;
 709           k->set_init_state(InstanceKlass::fully_initialized);
 710         } else {
 711           return;
 712         }
 713       }
 714     } else if (is_linked) {
 715       k->link_class(CHECK);
 716     }
 717     ConstantPool* cp = k->constants();
 718     if (length != cp->length()) {
 719       report_error("constant pool length mismatch: wrong class files?");
 720       return;
 721     }
 722 
 723     int parsed_two_word = 0;
 724     for (int i = 1; i < length; i++) {
 725       int tag = parse_int("tag");
 726       if (had_error()) {
 727         return;
 728       }
 729       switch (cp->tag_at(i).value()) {
 730         case JVM_CONSTANT_UnresolvedClass: {
 731           if (tag == JVM_CONSTANT_Class) {
 732             tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
 733             Klass* k = cp->klass_at(i, CHECK);
 734           }
 735           break;
 736         }
 737         case JVM_CONSTANT_Long:
 738         case JVM_CONSTANT_Double:
 739           parsed_two_word = i + 1;
 740 
 741         case JVM_CONSTANT_ClassIndex:
 742         case JVM_CONSTANT_StringIndex:
 743         case JVM_CONSTANT_String:
 744         case JVM_CONSTANT_UnresolvedClassInError:
 745         case JVM_CONSTANT_Fieldref:
 746         case JVM_CONSTANT_Methodref:
 747         case JVM_CONSTANT_InterfaceMethodref:
 748         case JVM_CONSTANT_NameAndType:
 749         case JVM_CONSTANT_Utf8:
 750         case JVM_CONSTANT_Integer:
 751         case JVM_CONSTANT_Float:
 752         case JVM_CONSTANT_MethodHandle:
 753         case JVM_CONSTANT_MethodType:
 754         case JVM_CONSTANT_Dynamic:
 755         case JVM_CONSTANT_InvokeDynamic:
 756           if (tag != cp->tag_at(i).value()) {
 757             report_error("tag mismatch: wrong class files?");
 758             return;
 759           }
 760           break;
 761 
 762         case JVM_CONSTANT_Class:
 763           if (tag == JVM_CONSTANT_Class) {
 764           } else if (tag == JVM_CONSTANT_UnresolvedClass) {
 765             tty->print_cr("Warning: entry was unresolved in the replay data");
 766           } else {
 767             report_error("Unexpected tag");
 768             return;
 769           }
 770           break;
 771 
 772         case 0:
 773           if (parsed_two_word == i) continue;
 774 
 775         default:
 776           fatal("Unexpected tag: %d", cp->tag_at(i).value());
 777           break;
 778       }
 779 
 780     }
 781   }
 782 
 783   // Initialize a class and fill in the value for a static field.
 784   // This is useful when the compile was dependent on the value of
 785   // static fields but it's impossible to properly rerun the static
 786   // initiailizer.
 787   void process_staticfield(TRAPS) {
 788     InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
 789 
 790     if (k == NULL || ReplaySuppressInitializers == 0 ||
 791         (ReplaySuppressInitializers == 2 && k->class_loader() == NULL)) {
 792       return;
 793     }
 794 
 795     assert(k->is_initialized(), "must be");
 796 
 797     const char* field_name = parse_escaped_string();
 798     const char* field_signature = parse_string();
 799     fieldDescriptor fd;
 800     Symbol* name = SymbolTable::lookup(field_name, (int)strlen(field_name), CHECK);
 801     Symbol* sig = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
 802     if (!k->find_local_field(name, sig, &fd) ||
 803         !fd.is_static() ||
 804         fd.has_initial_value()) {
 805       report_error(field_name);
 806       return;
 807     }
 808 
 809     oop java_mirror = k->java_mirror();
 810     if (field_signature[0] == '[') {
 811       int length = parse_int("array length");
 812       oop value = NULL;
 813 
 814       if (field_signature[1] == '[') {
 815         // multi dimensional array
 816         ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
 817         if (kelem == NULL) {
 818           return;
 819         }
 820         int rank = 0;
 821         while (field_signature[rank] == '[') {
 822           rank++;
 823         }
 824         jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
 825         dims[0] = length;
 826         for (int i = 1; i < rank; i++) {
 827           dims[i] = 1; // These aren't relevant to the compiler
 828         }
 829         value = kelem->multi_allocate(rank, dims, CHECK);
 830       } else {
 831         if (strcmp(field_signature, "[B") == 0) {
 832           value = oopFactory::new_byteArray(length, CHECK);
 833         } else if (strcmp(field_signature, "[Z") == 0) {
 834           value = oopFactory::new_boolArray(length, CHECK);
 835         } else if (strcmp(field_signature, "[C") == 0) {
 836           value = oopFactory::new_charArray(length, CHECK);
 837         } else if (strcmp(field_signature, "[S") == 0) {
 838           value = oopFactory::new_shortArray(length, CHECK);
 839         } else if (strcmp(field_signature, "[F") == 0) {
 840           value = oopFactory::new_floatArray(length, CHECK);
 841         } else if (strcmp(field_signature, "[D") == 0) {
 842           value = oopFactory::new_doubleArray(length, CHECK);
 843         } else if (strcmp(field_signature, "[I") == 0) {
 844           value = oopFactory::new_intArray(length, CHECK);
 845         } else if (strcmp(field_signature, "[J") == 0) {
 846           value = oopFactory::new_longArray(length, CHECK);
 847         } else if (field_signature[0] == '[' && field_signature[1] == 'L') {
 848           Klass* kelem = resolve_klass(field_signature + 1, CHECK);
 849           value = oopFactory::new_objArray(kelem, length, CHECK);
 850         } else {
 851           report_error("unhandled array staticfield");
 852         }
 853       }
 854       java_mirror->obj_field_put(fd.offset(), value);
 855     } else {
 856       const char* string_value = parse_escaped_string();
 857       if (strcmp(field_signature, "I") == 0) {
 858         int value = atoi(string_value);
 859         java_mirror->int_field_put(fd.offset(), value);
 860       } else if (strcmp(field_signature, "B") == 0) {
 861         int value = atoi(string_value);
 862         java_mirror->byte_field_put(fd.offset(), value);
 863       } else if (strcmp(field_signature, "C") == 0) {
 864         int value = atoi(string_value);
 865         java_mirror->char_field_put(fd.offset(), value);
 866       } else if (strcmp(field_signature, "S") == 0) {
 867         int value = atoi(string_value);
 868         java_mirror->short_field_put(fd.offset(), value);
 869       } else if (strcmp(field_signature, "Z") == 0) {
 870         int value = atoi(string_value);
 871         java_mirror->bool_field_put(fd.offset(), value);
 872       } else if (strcmp(field_signature, "J") == 0) {
 873         jlong value;
 874         if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
 875           fprintf(stderr, "Error parsing long: %s\n", string_value);
 876           return;
 877         }
 878         java_mirror->long_field_put(fd.offset(), value);
 879       } else if (strcmp(field_signature, "F") == 0) {
 880         float value = atof(string_value);
 881         java_mirror->float_field_put(fd.offset(), value);
 882       } else if (strcmp(field_signature, "D") == 0) {
 883         double value = atof(string_value);
 884         java_mirror->double_field_put(fd.offset(), value);
 885       } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
 886         Handle value = java_lang_String::create_from_str(string_value, CHECK);
 887         java_mirror->obj_field_put(fd.offset(), value());
 888       } else if (field_signature[0] == 'L') {
 889         Klass* k = resolve_klass(string_value, CHECK);
 890         oop value = InstanceKlass::cast(k)->allocate_instance(CHECK);
 891         java_mirror->obj_field_put(fd.offset(), value);
 892       } else {
 893         report_error("unhandled staticfield");
 894       }
 895     }
 896   }
 897 
 898 #if INCLUDE_JVMTI
 899   void process_JvmtiExport(TRAPS) {
 900     const char* field = parse_string();
 901     bool value = parse_int("JvmtiExport flag") != 0;
 902     if (strcmp(field, "can_access_local_variables") == 0) {
 903       JvmtiExport::set_can_access_local_variables(value);
 904     } else if (strcmp(field, "can_hotswap_or_post_breakpoint") == 0) {
 905       JvmtiExport::set_can_hotswap_or_post_breakpoint(value);
 906     } else if (strcmp(field, "can_post_on_exceptions") == 0) {
 907       JvmtiExport::set_can_post_on_exceptions(value);
 908     } else {
 909       report_error("Unrecognized JvmtiExport directive");
 910     }
 911   }
 912 #endif // INCLUDE_JVMTI
 913 
 914   // Create and initialize a record for a ciMethod
 915   ciMethodRecord* new_ciMethod(Method* method) {
 916     ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord);
 917     rec->_klass_name =  method->method_holder()->name()->as_utf8();
 918     rec->_method_name = method->name()->as_utf8();
 919     rec->_signature = method->signature()->as_utf8();
 920     _ci_method_records.append(rec);
 921     return rec;
 922   }
 923 
 924   // Lookup data for a ciMethod
 925   ciMethodRecord* find_ciMethodRecord(Method* method) {
 926     const char* klass_name =  method->method_holder()->name()->as_utf8();
 927     const char* method_name = method->name()->as_utf8();
 928     const char* signature = method->signature()->as_utf8();
 929     for (int i = 0; i < _ci_method_records.length(); i++) {
 930       ciMethodRecord* rec = _ci_method_records.at(i);
 931       if (strcmp(rec->_klass_name, klass_name) == 0 &&
 932           strcmp(rec->_method_name, method_name) == 0 &&
 933           strcmp(rec->_signature, signature) == 0) {
 934         return rec;
 935       }
 936     }
 937     return NULL;
 938   }
 939 
 940   // Create and initialize a record for a ciMethodData
 941   ciMethodDataRecord* new_ciMethodData(Method* method) {
 942     ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord);
 943     rec->_klass_name =  method->method_holder()->name()->as_utf8();
 944     rec->_method_name = method->name()->as_utf8();
 945     rec->_signature = method->signature()->as_utf8();
 946     _ci_method_data_records.append(rec);
 947     return rec;
 948   }
 949 
 950   // Lookup data for a ciMethodData
 951   ciMethodDataRecord* find_ciMethodDataRecord(Method* method) {
 952     const char* klass_name =  method->method_holder()->name()->as_utf8();
 953     const char* method_name = method->name()->as_utf8();
 954     const char* signature = method->signature()->as_utf8();
 955     for (int i = 0; i < _ci_method_data_records.length(); i++) {
 956       ciMethodDataRecord* rec = _ci_method_data_records.at(i);
 957       if (strcmp(rec->_klass_name, klass_name) == 0 &&
 958           strcmp(rec->_method_name, method_name) == 0 &&
 959           strcmp(rec->_signature, signature) == 0) {
 960         return rec;
 961       }
 962     }
 963     return NULL;
 964   }
 965 
 966   // Create and initialize a record for a ciInlineRecord
 967   ciInlineRecord* new_ciInlineRecord(Method* method, int bci, int depth) {
 968     ciInlineRecord* rec = NEW_RESOURCE_OBJ(ciInlineRecord);
 969     rec->_klass_name =  method->method_holder()->name()->as_utf8();
 970     rec->_method_name = method->name()->as_utf8();
 971     rec->_signature = method->signature()->as_utf8();
 972     rec->_inline_bci = bci;
 973     rec->_inline_depth = depth;
 974     _ci_inline_records->append(rec);
 975     return rec;
 976   }
 977 
 978   // Lookup inlining data for a ciMethod
 979   ciInlineRecord* find_ciInlineRecord(Method* method, int bci, int depth) {
 980     if (_ci_inline_records != NULL) {
 981       return find_ciInlineRecord(_ci_inline_records, method, bci, depth);
 982     }
 983     return NULL;
 984   }
 985 
 986   static ciInlineRecord* find_ciInlineRecord(GrowableArray<ciInlineRecord*>*  records,
 987                                       Method* method, int bci, int depth) {
 988     if (records != NULL) {
 989       const char* klass_name  = method->method_holder()->name()->as_utf8();
 990       const char* method_name = method->name()->as_utf8();
 991       const char* signature   = method->signature()->as_utf8();
 992       for (int i = 0; i < records->length(); i++) {
 993         ciInlineRecord* rec = records->at(i);
 994         if ((rec->_inline_bci == bci) &&
 995             (rec->_inline_depth == depth) &&
 996             (strcmp(rec->_klass_name, klass_name) == 0) &&
 997             (strcmp(rec->_method_name, method_name) == 0) &&
 998             (strcmp(rec->_signature, signature) == 0)) {
 999           return rec;
1000         }
1001       }
1002     }
1003     return NULL;
1004   }
1005 
1006   const char* error_message() {
1007     return _error_message;
1008   }
1009 
1010   void reset() {
1011     _error_message = NULL;
1012     _ci_method_records.clear();
1013     _ci_method_data_records.clear();
1014   }
1015 
1016   // Take an ascii string contain \u#### escapes and convert it to utf8
1017   // in place.
1018   static void unescape_string(char* value) {
1019     char* from = value;
1020     char* to = value;
1021     while (*from != '\0') {
1022       if (*from != '\\') {
1023         *from++ = *to++;
1024       } else {
1025         switch (from[1]) {
1026           case 'u': {
1027             from += 2;
1028             jchar value=0;
1029             for (int i=0; i<4; i++) {
1030               char c = *from++;
1031               switch (c) {
1032                 case '0': case '1': case '2': case '3': case '4':
1033                 case '5': case '6': case '7': case '8': case '9':
1034                   value = (value << 4) + c - '0';
1035                   break;
1036                 case 'a': case 'b': case 'c':
1037                 case 'd': case 'e': case 'f':
1038                   value = (value << 4) + 10 + c - 'a';
1039                   break;
1040                 case 'A': case 'B': case 'C':
1041                 case 'D': case 'E': case 'F':
1042                   value = (value << 4) + 10 + c - 'A';
1043                   break;
1044                 default:
1045                   ShouldNotReachHere();
1046               }
1047             }
1048             UNICODE::convert_to_utf8(&value, 1, to);
1049             to++;
1050             break;
1051           }
1052           case 't': *to++ = '\t'; from += 2; break;
1053           case 'n': *to++ = '\n'; from += 2; break;
1054           case 'r': *to++ = '\r'; from += 2; break;
1055           case 'f': *to++ = '\f'; from += 2; break;
1056           default:
1057             ShouldNotReachHere();
1058         }
1059       }
1060     }
1061     *from = *to;
1062   }
1063 };
1064 
1065 void ciReplay::replay(TRAPS) {
1066   int exit_code = replay_impl(THREAD);
1067 
1068   Threads::destroy_vm();
1069 
1070   vm_exit(exit_code);
1071 }
1072 
1073 void* ciReplay::load_inline_data(ciMethod* method, int entry_bci, int comp_level) {
1074   if (FLAG_IS_DEFAULT(InlineDataFile)) {
1075     tty->print_cr("ERROR: no inline replay data file specified (use -XX:InlineDataFile=inline_pid12345.txt).");
1076     return NULL;
1077   }
1078 
1079   VM_ENTRY_MARK;
1080   // Load and parse the replay data
1081   CompileReplay rp(InlineDataFile, THREAD);
1082   if (!rp.can_replay()) {
1083     tty->print_cr("ciReplay: !rp.can_replay()");
1084     return NULL;
1085   }
1086   void* data = rp.process_inline(method, method->get_Method(), entry_bci, comp_level, THREAD);
1087   if (HAS_PENDING_EXCEPTION) {
1088     Handle throwable(THREAD, PENDING_EXCEPTION);
1089     CLEAR_PENDING_EXCEPTION;
1090     java_lang_Throwable::print_stack_trace(throwable, tty);
1091     tty->cr();
1092     return NULL;
1093   }
1094 
1095   if (rp.had_error()) {
1096     tty->print_cr("ciReplay: Failed on %s", rp.error_message());
1097     return NULL;
1098   }
1099   return data;
1100 }
1101 
1102 int ciReplay::replay_impl(TRAPS) {
1103   HandleMark hm;
1104   ResourceMark rm;
1105 
1106   if (ReplaySuppressInitializers > 2) {
1107     // ReplaySuppressInitializers > 2 means that we want to allow
1108     // normal VM bootstrap but once we get into the replay itself
1109     // don't allow any intializers to be run.
1110     ReplaySuppressInitializers = 1;
1111   }
1112 
1113   if (FLAG_IS_DEFAULT(ReplayDataFile)) {
1114     tty->print_cr("ERROR: no compiler replay data file specified (use -XX:ReplayDataFile=replay_pid12345.txt).");
1115     return 1;
1116   }
1117 
1118   // Load and parse the replay data
1119   CompileReplay rp(ReplayDataFile, THREAD);
1120   int exit_code = 0;
1121   if (rp.can_replay()) {
1122     rp.process(THREAD);
1123   } else {
1124     exit_code = 1;
1125     return exit_code;
1126   }
1127 
1128   if (HAS_PENDING_EXCEPTION) {
1129     Handle throwable(THREAD, PENDING_EXCEPTION);
1130     CLEAR_PENDING_EXCEPTION;
1131     java_lang_Throwable::print_stack_trace(throwable, tty);
1132     tty->cr();
1133     exit_code = 2;
1134   }
1135 
1136   if (rp.had_error()) {
1137     tty->print_cr("Failed on %s", rp.error_message());
1138     exit_code = 1;
1139   }
1140   return exit_code;
1141 }
1142 
1143 void ciReplay::initialize(ciMethodData* m) {
1144   if (replay_state == NULL) {
1145     return;
1146   }
1147 
1148   ASSERT_IN_VM;
1149   ResourceMark rm;
1150 
1151   Method* method = m->get_MethodData()->method();
1152   ciMethodDataRecord* rec = replay_state->find_ciMethodDataRecord(method);
1153   if (rec == NULL) {
1154     // This indicates some mismatch with the original environment and
1155     // the replay environment though it's not always enough to
1156     // interfere with reproducing a bug
1157     tty->print_cr("Warning: requesting ciMethodData record for method with no data: ");
1158     method->print_name(tty);
1159     tty->cr();
1160   } else {
1161     m->_state = rec->_state;
1162     m->_current_mileage = rec->_current_mileage;
1163     if (rec->_data_length != 0) {
1164       assert(m->_data_size + m->_extra_data_size == rec->_data_length * (int)sizeof(rec->_data[0]) ||
1165              m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree");
1166 
1167       // Write the correct ciObjects back into the profile data
1168       ciEnv* env = ciEnv::current();
1169       for (int i = 0; i < rec->_classes_length; i++) {
1170         Klass *k = rec->_classes[i];
1171         // In case this class pointer is is tagged, preserve the tag bits
1172         intptr_t status = 0;
1173         if (k != NULL) {
1174           status = ciTypeEntries::with_status(env->get_metadata(k)->as_klass(), rec->_data[rec->_classes_offsets[i]]);
1175         }
1176         rec->_data[rec->_classes_offsets[i]] = status;
1177       }
1178       for (int i = 0; i < rec->_methods_length; i++) {
1179         Method *m = rec->_methods[i];
1180         *(ciMetadata**)(rec->_data + rec->_methods_offsets[i]) =
1181           env->get_metadata(m);
1182       }
1183       // Copy the updated profile data into place as intptr_ts
1184 #ifdef _LP64
1185       Copy::conjoint_jlongs_atomic((jlong *)rec->_data, (jlong *)m->_data, rec->_data_length);
1186 #else
1187       Copy::conjoint_jints_atomic((jint *)rec->_data, (jint *)m->_data, rec->_data_length);
1188 #endif
1189     }
1190 
1191     // copy in the original header
1192     Copy::conjoint_jbytes(rec->_orig_data, (char*)&m->_orig, rec->_orig_data_length);
1193   }
1194 }
1195 
1196 
1197 bool ciReplay::should_not_inline(ciMethod* method) {
1198   if (replay_state == NULL) {
1199     return false;
1200   }
1201   VM_ENTRY_MARK;
1202   // ciMethod without a record shouldn't be inlined.
1203   return replay_state->find_ciMethodRecord(method->get_Method()) == NULL;
1204 }
1205 
1206 bool ciReplay::should_inline(void* data, ciMethod* method, int bci, int inline_depth) {
1207   if (data != NULL) {
1208     GrowableArray<ciInlineRecord*>*  records = (GrowableArray<ciInlineRecord*>*)data;
1209     VM_ENTRY_MARK;
1210     // Inline record are ordered by bci and depth.
1211     return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) != NULL;
1212   } else if (replay_state != NULL) {
1213     VM_ENTRY_MARK;
1214     // Inline record are ordered by bci and depth.
1215     return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) != NULL;
1216   }
1217   return false;
1218 }
1219 
1220 bool ciReplay::should_not_inline(void* data, ciMethod* method, int bci, int inline_depth) {
1221   if (data != NULL) {
1222     GrowableArray<ciInlineRecord*>*  records = (GrowableArray<ciInlineRecord*>*)data;
1223     VM_ENTRY_MARK;
1224     // Inline record are ordered by bci and depth.
1225     return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) == NULL;
1226   } else if (replay_state != NULL) {
1227     VM_ENTRY_MARK;
1228     // Inline record are ordered by bci and depth.
1229     return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) == NULL;
1230   }
1231   return false;
1232 }
1233 
1234 void ciReplay::initialize(ciMethod* m) {
1235   if (replay_state == NULL) {
1236     return;
1237   }
1238 
1239   ASSERT_IN_VM;
1240   ResourceMark rm;
1241 
1242   Method* method = m->get_Method();
1243   ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
1244   if (rec == NULL) {
1245     // This indicates some mismatch with the original environment and
1246     // the replay environment though it's not always enough to
1247     // interfere with reproducing a bug
1248     tty->print_cr("Warning: requesting ciMethod record for method with no data: ");
1249     method->print_name(tty);
1250     tty->cr();
1251   } else {
1252     EXCEPTION_CONTEXT;
1253     // m->_instructions_size = rec->_instructions_size;
1254     m->_instructions_size = -1;
1255     m->_interpreter_invocation_count = rec->_interpreter_invocation_count;
1256     m->_interpreter_throwout_count = rec->_interpreter_throwout_count;
1257     MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR);
1258     guarantee(mcs != NULL, "method counters allocation failed");
1259     mcs->invocation_counter()->_counter = rec->_invocation_counter;
1260     mcs->backedge_counter()->_counter = rec->_backedge_counter;
1261   }
1262 }
1263 
1264 bool ciReplay::is_loaded(Method* method) {
1265   if (replay_state == NULL) {
1266     return true;
1267   }
1268 
1269   ASSERT_IN_VM;
1270   ResourceMark rm;
1271 
1272   ciMethodRecord* rec = replay_state->find_ciMethodRecord(method);
1273   return rec != NULL;
1274 }
1275 #endif // PRODUCT