< 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"

*** 976,10 ***
--- 977,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:

*** 1022,130 ***
        }
  
      }
    }
  
!   // 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;
      }
  
!     oop java_mirror = k->java_mirror();
      if (field_signature[0] == JVM_SIGNATURE_ARRAY) {
        int length = parse_int("array length");
        oop value = nullptr;
  
        if (length != -1) {
          if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
            // multi dimensional array
!           ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
!           if (kelem == nullptr) {
-             return;
-           }
            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);
          } else {
            if (strcmp(field_signature, "[B") == 0) {
!             value = oopFactory::new_byteArray(length, CHECK);
            } else if (strcmp(field_signature, "[Z") == 0) {
!             value = oopFactory::new_boolArray(length, CHECK);
            } else if (strcmp(field_signature, "[C") == 0) {
!             value = oopFactory::new_charArray(length, CHECK);
            } else if (strcmp(field_signature, "[S") == 0) {
!             value = oopFactory::new_shortArray(length, CHECK);
            } else if (strcmp(field_signature, "[F") == 0) {
!             value = oopFactory::new_floatArray(length, CHECK);
            } else if (strcmp(field_signature, "[D") == 0) {
!             value = oopFactory::new_doubleArray(length, CHECK);
            } else if (strcmp(field_signature, "[I") == 0) {
!             value = oopFactory::new_intArray(length, CHECK);
            } else if (strcmp(field_signature, "[J") == 0) {
!             value = oopFactory::new_longArray(length, CHECK);
            } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
                       field_signature[1] == JVM_SIGNATURE_CLASS) {
!             Klass* actual_array_klass = parse_klass(CHECK);
              Klass* kelem = ObjArrayKlass::cast(actual_array_klass)->element_klass();
!             value = oopFactory::new_objArray(kelem, length, CHECK);
            } else {
              report_error("unhandled array staticfield");
            }
          }
        }
        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) {
-         oop value = nullptr;
-         if (string_value != nullptr) {
-           Klass* k = resolve_klass(string_value, CHECK);
-           value = InstanceKlass::cast(k)->allocate_instance(CHECK);
-         }
-         java_mirror->obj_field_put(fd.offset(), value);
-       } else {
          report_error("unhandled staticfield");
        }
      }
    }
  
--- 1024,237 ---
        }
  
      }
    }
  
!   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));
+       }
+       }
      }
+   };
  
!   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 (length != -1) {
          if (field_signature[1] == JVM_SIGNATURE_ARRAY) {
            // multi dimensional array
!           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_(true));
          } else {
            if (strcmp(field_signature, "[B") == 0) {
!             value = oopFactory::new_byteArray(length, CHECK_(true));
            } else if (strcmp(field_signature, "[Z") == 0) {
!             value = oopFactory::new_boolArray(length, CHECK_(true));
            } else if (strcmp(field_signature, "[C") == 0) {
!             value = oopFactory::new_charArray(length, CHECK_(true));
            } else if (strcmp(field_signature, "[S") == 0) {
!             value = oopFactory::new_shortArray(length, CHECK_(true));
            } else if (strcmp(field_signature, "[F") == 0) {
!             value = oopFactory::new_floatArray(length, CHECK_(true));
            } else if (strcmp(field_signature, "[D") == 0) {
!             value = oopFactory::new_doubleArray(length, CHECK_(true));
            } else if (strcmp(field_signature, "[I") == 0) {
!             value = oopFactory::new_intArray(length, CHECK_(true));
            } else if (strcmp(field_signature, "[J") == 0) {
!             value = oopFactory::new_longArray(length, CHECK_(true));
            } else if (field_signature[0] == JVM_SIGNATURE_ARRAY &&
                       field_signature[1] == JVM_SIGNATURE_CLASS) {
!             Klass* actual_array_klass = parse_klass(CHECK_(true));
              Klass* kelem = ObjArrayKlass::cast(actual_array_klass)->element_klass();
!             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] == JVM_SIGNATURE_CLASS) {
+       const char* instance = parse_escaped_string();
+       oop value = nullptr;
+       if (instance != nullptr) {
+         Klass* k = resolve_klass(instance, CHECK_(true));
+         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 {
!       bool res = process_staticfield_reference(field_signature, java_mirror, &fd, CHECK);
!       if (!res)  {
          report_error("unhandled staticfield");
        }
      }
    }
  
< prev index next >