< prev index next >

src/hotspot/share/ci/ciReplay.cpp

Print this page
@@ -40,10 +40,11 @@
  #include "memory/oopFactory.hpp"
  #include "memory/resourceArea.hpp"
  #include "oops/constantPool.inline.hpp"
  #include "oops/cpCache.inline.hpp"
  #include "oops/fieldStreams.inline.hpp"
+ #include "oops/inlineKlass.inline.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/method.inline.hpp"
  #include "oops/oop.inline.hpp"
  #include "oops/resolvedIndyEntry.hpp"
  #include "prims/jvmtiExport.hpp"

@@ -975,10 +976,11 @@
              tty->print_cr("Resolving klass %s at %d", cp->klass_name_at(i)->as_utf8(), i);
              Klass* k = cp->klass_at(i, CHECK);
            }
            break;
          }
+ 
          case JVM_CONSTANT_Long:
          case JVM_CONSTANT_Double:
            parsed_two_word = i + 1;
  
          case JVM_CONSTANT_ClassIndex:

@@ -1021,125 +1023,232 @@
        }
  
      }
    }
  
-   // staticfield <klass> <name> <signature> <value>
-   //
-   // Initialize a class and fill in the value for a static field.
-   // This is useful when the compile was dependent on the value of
-   // static fields but it's impossible to properly rerun the static
-   // initializer.
-   void process_staticfield(TRAPS) {
-     InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
- 
-     if (k == nullptr || ReplaySuppressInitializers == 0 ||
-         (ReplaySuppressInitializers == 2 && k->class_loader() == nullptr)) {
-       skip_remaining();
-       return;
-     }
- 
-     assert(k->is_initialized(), "must be");
- 
-     const char* field_name = parse_escaped_string();
-     const char* field_signature = parse_string();
-     fieldDescriptor fd;
-     Symbol* name = SymbolTable::new_symbol(field_name);
-     Symbol* sig = SymbolTable::new_symbol(field_signature);
-     if (!k->find_local_field(name, sig, &fd) ||
-         !fd.is_static() ||
-         fd.has_initial_value()) {
-       report_error(field_name);
-       return;
+   class InlineTypeFieldInitializer : public FieldClosure {
+     oop _vt;
+     CompileReplay* _replay;
+   public:
+     InlineTypeFieldInitializer(oop vt, CompileReplay* replay)
+   : _vt(vt), _replay(replay) {}
+ 
+     void do_field(fieldDescriptor* fd) {
+       BasicType bt = fd->field_type();
+       const char* string_value = fd->is_null_free_inline_type() ? nullptr : _replay->parse_escaped_string();
+       switch (bt) {
+       case T_BYTE: {
+         int value = atoi(string_value);
+         _vt->byte_field_put(fd->offset(), value);
+         break;
+       }
+       case T_BOOLEAN: {
+         int value = atoi(string_value);
+         _vt->bool_field_put(fd->offset(), value);
+         break;
+       }
+       case T_SHORT: {
+         int value = atoi(string_value);
+         _vt->short_field_put(fd->offset(), value);
+         break;
+       }
+       case T_CHAR: {
+         int value = atoi(string_value);
+         _vt->char_field_put(fd->offset(), value);
+         break;
+       }
+       case T_INT: {
+         int value = atoi(string_value);
+         _vt->int_field_put(fd->offset(), value);
+         break;
+       }
+       case T_LONG: {
+         jlong value;
+         if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
+           fprintf(stderr, "Error parsing long: %s\n", string_value);
+           break;
+         }
+         _vt->long_field_put(fd->offset(), value);
+         break;
+       }
+       case T_FLOAT: {
+         float value = atof(string_value);
+         _vt->float_field_put(fd->offset(), value);
+         break;
+       }
+       case T_DOUBLE: {
+         double value = atof(string_value);
+         _vt->double_field_put(fd->offset(), value);
+         break;
+       }
+       case T_ARRAY:
+       case T_OBJECT:
+         if (!fd->is_null_free_inline_type()) {
+           JavaThread* THREAD = JavaThread::current();
+           bool res = _replay->process_staticfield_reference(string_value, _vt, fd, THREAD);
+           assert(res, "should succeed for arrays & objects");
+           break;
+         } else {
+           InlineKlass* vk = InlineKlass::cast(fd->field_holder()->get_inline_type_field_klass(fd->index()));
+           if (fd->is_flat()) {
+             int field_offset = fd->offset() - vk->first_field_offset();
+             oop obj = cast_to_oop(cast_from_oop<address>(_vt) + field_offset);
+             InlineTypeFieldInitializer init_fields(obj, _replay);
+             vk->do_nonstatic_fields(&init_fields);
+           } else {
+             oop value = vk->allocate_instance(JavaThread::current());
+             _vt->obj_field_put(fd->offset(), value);
+           }
+           break;
+         }
+       default: {
+         fatal("Unhandled type: %s", type2name(bt));
+       }
+       }
      }
+   };
  
-     oop java_mirror = k->java_mirror();
+   bool process_staticfield_reference(const char* field_signature, oop java_mirror, fieldDescriptor* fd, TRAPS) {
      if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
        int length = parse_int("array length");
        oop value = nullptr;
  
        if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
          // multi dimensional array
-         ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
-         if (kelem == nullptr) {
-           return;
-         }
+         Klass* k = resolve_klass(field_signature, CHECK_(true));
+         ArrayKlass* kelem = (ArrayKlass *)k;
          int rank = 0;
          while (field_signature[rank] == JVM_SIGNATURE_ARRAY) {
            rank++;
          }
          jint* dims = NEW_RESOURCE_ARRAY(jint, rank);
          dims[0] = length;
          for (int i = 1; i < rank; i++) {
            dims[i] = 1; // These aren't relevant to the compiler
          }
-         value = kelem->multi_allocate(rank, dims, CHECK);
+         value = kelem->multi_allocate(rank, dims, CHECK_(true));
        } else {
          if (strcmp(field_signature, "[B") == 0) {
-           value = oopFactory::new_byteArray(length, CHECK);
+           value = oopFactory::new_byteArray(length, CHECK_(true));
          } else if (strcmp(field_signature, "[Z") == 0) {
-           value = oopFactory::new_boolArray(length, CHECK);
+           value = oopFactory::new_boolArray(length, CHECK_(true));
          } else if (strcmp(field_signature, "[C") == 0) {
-           value = oopFactory::new_charArray(length, CHECK);
+           value = oopFactory::new_charArray(length, CHECK_(true));
          } else if (strcmp(field_signature, "[S") == 0) {
-           value = oopFactory::new_shortArray(length, CHECK);
+           value = oopFactory::new_shortArray(length, CHECK_(true));
          } else if (strcmp(field_signature, "[F") == 0) {
-           value = oopFactory::new_floatArray(length, CHECK);
+           value = oopFactory::new_floatArray(length, CHECK_(true));
          } else if (strcmp(field_signature, "[D") == 0) {
-           value = oopFactory::new_doubleArray(length, CHECK);
+           value = oopFactory::new_doubleArray(length, CHECK_(true));
          } else if (strcmp(field_signature, "[I") == 0) {
-           value = oopFactory::new_intArray(length, CHECK);
+           value = oopFactory::new_intArray(length, CHECK_(true));
          } else if (strcmp(field_signature, "[J") == 0) {
-           value = oopFactory::new_longArray(length, CHECK);
+           value = oopFactory::new_longArray(length, CHECK_(true));
          } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
                     field_signature[1] == JVM_SIGNATURE_CLASS) {
-           parse_klass(CHECK); // eat up the array class name
-           Klass* kelem = resolve_klass(field_signature + 1, CHECK);
-           value = oopFactory::new_objArray(kelem, length, CHECK);
+           Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true));
+           parse_klass(CHECK_(true)); // eat up the array class name
+           value = oopFactory::new_objArray(kelem, length, CHECK_(true));
+         } else if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
+           Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true));
+           parse_klass(CHECK_(true)); // eat up the array class name
+           value = oopFactory::new_valueArray(kelem, length, CHECK_(true));
          } else {
            report_error("unhandled array staticfield");
          }
        }
+       java_mirror->obj_field_put(fd->offset(), value);
+       return true;
+     } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
+       const char* string_value = parse_escaped_string();
+       Handle value = java_lang_String::create_from_str(string_value, CHECK_(true));
+       java_mirror->obj_field_put(fd->offset(), value());
+       return true;
+     } else if (field_signature[0] == 'L') {
+       const char* instance = parse_escaped_string();
+       Klass* k = resolve_klass(instance, CHECK_(true));
+       oop value = InstanceKlass::cast(k)->allocate_instance(CHECK_(true));
+       java_mirror->obj_field_put(fd->offset(), value);
+       return true;
+     }
+     return false;
+   }
+ 
+   // Initialize a class and fill in the value for a static field.
+   // This is useful when the compile was dependent on the value of
+   // static fields but it's impossible to properly rerun the static
+   // initializer.
+   void process_staticfield(TRAPS) {
+     InstanceKlass* k = (InstanceKlass *)parse_klass(CHECK);
+ 
+     if (k == nullptr || ReplaySuppressInitializers == 0 ||
+         (ReplaySuppressInitializers == 2 && k->class_loader() == nullptr)) {
+         skip_remaining();
+       return;
+     }
+ 
+     assert(k->is_initialized(), "must be");
+ 
+     const char* field_name = parse_escaped_string();
+     const char* field_signature = parse_string();
+     fieldDescriptor fd;
+     Symbol* name = SymbolTable::new_symbol(field_name);
+     Symbol* sig = SymbolTable::new_symbol(field_signature);
+     if (!k->find_local_field(name, sig, &fd) ||
+         !fd.is_static() ||
+         fd.has_initial_value()) {
+       report_error(field_name);
+       return;
+     }
+ 
+     oop java_mirror = k->java_mirror();
+     if (strcmp(field_signature, "I") == 0) {
+       const char* string_value = parse_escaped_string();
+       int value = atoi(string_value);
+       java_mirror->int_field_put(fd.offset(), value);
+     } else if (strcmp(field_signature, "B") == 0) {
+       const char* string_value = parse_escaped_string();
+       int value = atoi(string_value);
+       java_mirror->byte_field_put(fd.offset(), value);
+     } else if (strcmp(field_signature, "C") == 0) {
+       const char* string_value = parse_escaped_string();
+       int value = atoi(string_value);
+       java_mirror->char_field_put(fd.offset(), value);
+     } else if (strcmp(field_signature, "S") == 0) {
+       const char* string_value = parse_escaped_string();
+       int value = atoi(string_value);
+       java_mirror->short_field_put(fd.offset(), value);
+     } else if (strcmp(field_signature, "Z") == 0) {
+       const char* string_value = parse_escaped_string();
+       int value = atoi(string_value);
+       java_mirror->bool_field_put(fd.offset(), value);
+     } else if (strcmp(field_signature, "J") == 0) {
+       const char* string_value = parse_escaped_string();
+       jlong value;
+       if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
+         fprintf(stderr, "Error parsing long: %s\n", string_value);
+         return;
+       }
+       java_mirror->long_field_put(fd.offset(), value);
+     } else if (strcmp(field_signature, "F") == 0) {
+       const char* string_value = parse_escaped_string();
+       float value = atof(string_value);
+       java_mirror->float_field_put(fd.offset(), value);
+     } else if (strcmp(field_signature, "D") == 0) {
+       const char* string_value = parse_escaped_string();
+       double value = atof(string_value);
+       java_mirror->double_field_put(fd.offset(), value);
+     } else if (fd.is_null_free_inline_type()) {
+       Klass* kelem = resolve_klass(field_signature, CHECK);
+       InlineKlass* vk = InlineKlass::cast(kelem);
+       oop value = vk->allocate_instance(CHECK);
+       InlineTypeFieldInitializer init_fields(value, this);
+       vk->do_nonstatic_fields(&init_fields);
        java_mirror->obj_field_put(fd.offset(), value);
      } else {
-       const char* string_value = parse_escaped_string();
-       if (strcmp(field_signature, "I") == 0) {
-         int value = atoi(string_value);
-         java_mirror->int_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "B") == 0) {
-         int value = atoi(string_value);
-         java_mirror->byte_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "C") == 0) {
-         int value = atoi(string_value);
-         java_mirror->char_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "S") == 0) {
-         int value = atoi(string_value);
-         java_mirror->short_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "Z") == 0) {
-         int value = atoi(string_value);
-         java_mirror->bool_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "J") == 0) {
-         jlong value;
-         if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
-           fprintf(stderr, "Error parsing long: %s\n", string_value);
-           return;
-         }
-         java_mirror->long_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "F") == 0) {
-         float value = atof(string_value);
-         java_mirror->float_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "D") == 0) {
-         double value = atof(string_value);
-         java_mirror->double_field_put(fd.offset(), value);
-       } else if (strcmp(field_signature, "Ljava/lang/String;") == 0) {
-         Handle value = java_lang_String::create_from_str(string_value, CHECK);
-         java_mirror->obj_field_put(fd.offset(), value());
-       } else if (field_signature[0] == JVM_SIGNATURE_CLASS) {
-         Klass* k = resolve_klass(string_value, CHECK);
-         oop value = InstanceKlass::cast(k)->allocate_instance(CHECK);
-         java_mirror->obj_field_put(fd.offset(), value);
-       } else {
+       bool res = process_staticfield_reference(field_signature, java_mirror, &fd, CHECK);
+       if (!res)  {
          report_error("unhandled staticfield");
        }
      }
    }
  
< prev index next >