changeset 13019:e31f5c06438d mvt

ciReplay support for value type reference fields
author roland
date Thu, 01 Jun 2017 17:13:31 +0200
parents b03e14ea3e9b
children 4cd1b06ce224
files src/share/vm/ci/ciInstanceKlass.cpp src/share/vm/ci/ciReplay.cpp
diffstat 2 files changed, 131 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/ci/ciInstanceKlass.cpp	Wed Jun 07 15:38:35 2017 -0400
+++ b/src/share/vm/ci/ciInstanceKlass.cpp	Thu Jun 01 17:13:31 2017 +0200
@@ -704,7 +704,11 @@
       ResourceMark rm;
       InstanceKlass* holder = fd->field_holder();
       oop mirror = holder->java_mirror();
-      _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
+      _out->print("staticfield %s %s ", _holder, fd->name()->as_quoted_ascii());
+      BasicType bt = fd->field_type();
+      if (bt != T_OBJECT && bt != T_ARRAY) {
+        _out->print("%s ", fd->signature()->as_quoted_ascii());
+      }
       do_field_helper(fd, mirror, false);
       _out->cr();
     }
@@ -724,8 +728,9 @@
 };
 
 void StaticFieldPrinter::do_field_helper(fieldDescriptor* fd, oop mirror, bool flattened) {
-  switch (fd->field_type()) {
-    case T_BYTE:    _out->print_cr("%d", mirror->byte_field(fd->offset()));   break;
+  BasicType bt = fd->field_type();
+  switch (bt) {
+    case T_BYTE:    _out->print("%d", mirror->byte_field(fd->offset()));   break;
     case T_BOOLEAN: _out->print("%d", mirror->bool_field(fd->offset()));   break;
     case T_SHORT:   _out->print("%d", mirror->short_field(fd->offset()));  break;
     case T_CHAR:    _out->print("%d", mirror->char_field(fd->offset()));   break;
@@ -741,39 +746,26 @@
       _out->print(INT64_FORMAT, *(int64_t*)&d);
       break;
     }
-    case T_ARRAY: {
+    case T_ARRAY:
+    case T_OBJECT: {
       oop value =  mirror->obj_field_acquire(fd->offset());
       if (value == NULL) {
         _out->print("null");
       } else {
-        typeArrayOop ta = (typeArrayOop)value;
-        _out->print("%d", ta->length());
-        if (value->is_objArray()) {
-          objArrayOop oa = (objArrayOop)value;
-          const char* klass_name  = value->klass()->name()->as_quoted_ascii();
-          _out->print(" %s", klass_name);
+        _out->print("%s", value->klass()->signature_name());
+        if (value->is_array()) {
+          _out->print(" %d", ((arrayOop)value)->length());
+        } else {
+          assert(value->is_instance() && bt == T_OBJECT, "what else?");
+          if (value->is_a(SystemDictionary::String_klass())) {
+            _out->print(" \"");
+            _out->print_raw(java_lang_String::as_quoted_ascii(value));
+            _out->print("\"");
+          }          
         }
       }
       break;
     }
-    case T_OBJECT: {
-      oop value =  mirror->obj_field_acquire(fd->offset());
-      if (value == NULL) {
-        _out->print("null");
-      } else if (value->is_instance()) {
-        if (value->is_a(SystemDictionary::String_klass())) {
-          _out->print("\"");
-          _out->print_raw(java_lang_String::as_quoted_ascii(value));
-          _out->print("\"");
-        } else {
-          const char* klass_name  = value->klass()->name()->as_quoted_ascii();
-          _out->print("%s", klass_name);
-        }
-      } else {
-        ShouldNotReachHere();
-      }
-      break;
-    }
     case T_VALUETYPE: {
       ResetNoHandleMark rnhm;
       Thread* THREAD = Thread::current();
--- a/src/share/vm/ci/ciReplay.cpp	Wed Jun 07 15:38:35 2017 -0400
+++ b/src/share/vm/ci/ciReplay.cpp	Thu Jun 01 17:13:31 2017 +0200
@@ -794,11 +794,12 @@
         break;
       }
       case T_ARRAY:
-        _replay->report_error("Array in value type unsupported");
+      case T_OBJECT: {
+        Thread* THREAD = Thread::current();
+        bool res = _replay->process_staticfield_reference(string_value, _vt, fd, THREAD);
+        assert(res, "should succeed for arrays & objects");
         break;
-      case T_OBJECT:
-        _replay->report_error("Object in value type unsupported");
-        break;
+      }
       case T_VALUETYPE: {
         Thread* THREAD = Thread::current();
         SignatureStream ss(fd->signature(), false);
@@ -818,6 +819,65 @@
     }
   };
 
+  bool process_staticfield_reference(const char* field_signature, oop java_mirror, fieldDescriptor* fd, TRAPS) {
+    if (field_signature[0] == '[') {
+      int length = parse_int("array length");
+      oop value = NULL;
+
+      if (field_signature[1] == '[') {
+        // multi dimensional array
+        Klass* k = resolve_klass(field_signature, CHECK_(true));
+        ArrayKlass* kelem = (ArrayKlass *)k;
+        int rank = 0;
+        while (field_signature[rank] == '[') {
+          rank++;
+        }
+        int* dims = NEW_RESOURCE_ARRAY(int, 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_singleArray(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] == '[' && field_signature[1] == 'L') {
+          Klass* kelem = resolve_klass(field_signature + 1, CHECK_(true));
+          value = oopFactory::new_objArray(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') {
+      Klass* k = resolve_klass(field_signature, 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
@@ -845,102 +905,56 @@
     }
 
     oop java_mirror = k->java_mirror();
-    if (field_signature[0] == '[') {
-      int length = parse_int("array length");
-      oop value = NULL;
-
-      if (field_signature[1] == '[') {
-        // multi dimensional array
-        ArrayKlass* kelem = (ArrayKlass *)parse_klass(CHECK);
-        int rank = 0;
-        while (field_signature[rank] == '[') {
-          rank++;
-        }
-        int* dims = NEW_RESOURCE_ARRAY(int, 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_singleArray(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] == '[' && field_signature[1] == 'L') {
-          Klass* kelem = resolve_klass(field_signature + 1, CHECK);
-          value = oopFactory::new_objArray(kelem, length, CHECK);
-        } else {
-          report_error("unhandled array staticfield");
-        }
+    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 (field_signature[0] == 'Q') {
+      Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
+      Klass* kelem = resolve_klass(field_signature, CHECK);
+      ValueKlass* vk = ValueKlass::cast(kelem);
+      oop value = vk->allocate_instance(CHECK);
+      ValueTypeFieldInitializer init_fields(value, this);
+      vk->do_nonstatic_fields(&init_fields);
+      if (HAS_PENDING_EXCEPTION) {
+        return;
       }
       java_mirror->obj_field_put(fd.offset(), value);
     } else {
-      const char* string_value = field_signature[0] != 'Q' ? parse_escaped_string() : NULL;
-      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] == 'L') {
-        Klass* k = resolve_klass(string_value, CHECK);
-        oop value = InstanceKlass::cast(k)->allocate_instance(CHECK);
-        java_mirror->obj_field_put(fd.offset(), value);
-      } else if (field_signature[0] == 'Q') {
-        Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
-        Klass* kelem = resolve_klass(field_signature, CHECK);
-        ValueKlass* vk = ValueKlass::cast(kelem);
-        oop value = vk->allocate_instance(CHECK);
-        ValueTypeFieldInitializer init_fields(value, this);
-        vk->do_nonstatic_fields(&init_fields);
-        java_mirror->obj_field_put(fd.offset(), value);
-      } else if (field_signature[0] == 'Q') {
-        Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
-        Klass* kelem = resolve_klass(field_signature, CHECK);
-        ValueKlass* vk = ValueKlass::cast(kelem);
-        oop value = vk->allocate_instance(CHECK);
-        ValueTypeFieldInitializer 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");
       }
     }