src/share/vm/ci/ciInstanceKlass.cpp

changeset 4267
bd7a7ce2e264
parent 4037
da91efe96a93
child 4531
fcc9e7681d63
     1.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp	Fri Nov 09 08:36:17 2012 -0800
     1.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp	Mon Nov 12 14:03:53 2012 -0800
     1.3 @@ -561,3 +561,114 @@
     1.4    }
     1.5    return impl;
     1.6  }
     1.7 +
     1.8 +// Utility class for printing of the contents of the static fields for
     1.9 +// use by compilation replay.  It only prints out the information that
    1.10 +// could be consumed by the compiler, so for primitive types it prints
    1.11 +// out the actual value.  For Strings it's the actual string value.
    1.12 +// For array types it it's first level array size since that's the
    1.13 +// only value which statically unchangeable.  For all other reference
    1.14 +// types it simply prints out the dynamic type.
    1.15 +
    1.16 +class StaticFinalFieldPrinter : public FieldClosure {
    1.17 +  outputStream* _out;
    1.18 +  const char*   _holder;
    1.19 + public:
    1.20 +  StaticFinalFieldPrinter(outputStream* out, const char* holder) :
    1.21 +    _out(out),
    1.22 +    _holder(holder) {
    1.23 +  }
    1.24 +  void do_field(fieldDescriptor* fd) {
    1.25 +    if (fd->is_final() && !fd->has_initial_value()) {
    1.26 +      oop mirror = fd->field_holder()->java_mirror();
    1.27 +      _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii());
    1.28 +      switch (fd->field_type()) {
    1.29 +        case T_BYTE:    _out->print_cr("%d", mirror->byte_field(fd->offset()));   break;
    1.30 +        case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset()));   break;
    1.31 +        case T_SHORT:   _out->print_cr("%d", mirror->short_field(fd->offset()));  break;
    1.32 +        case T_CHAR:    _out->print_cr("%d", mirror->char_field(fd->offset()));   break;
    1.33 +        case T_INT:     _out->print_cr("%d", mirror->int_field(fd->offset()));    break;
    1.34 +        case T_LONG:    _out->print_cr(INT64_FORMAT, mirror->long_field(fd->offset()));   break;
    1.35 +        case T_FLOAT: {
    1.36 +          float f = mirror->float_field(fd->offset());
    1.37 +          _out->print_cr("%d", *(int*)&f);
    1.38 +          break;
    1.39 +        }
    1.40 +        case T_DOUBLE: {
    1.41 +          double d = mirror->double_field(fd->offset());
    1.42 +          _out->print_cr(INT64_FORMAT, *(jlong*)&d);
    1.43 +          break;
    1.44 +        }
    1.45 +        case T_ARRAY: {
    1.46 +          oop value =  mirror->obj_field_acquire(fd->offset());
    1.47 +          if (value == NULL) {
    1.48 +            _out->print_cr("null");
    1.49 +          } else {
    1.50 +            typeArrayOop ta = (typeArrayOop)value;
    1.51 +            _out->print("%d", ta->length());
    1.52 +            if (value->is_objArray()) {
    1.53 +              objArrayOop oa = (objArrayOop)value;
    1.54 +              const char* klass_name  = value->klass()->name()->as_quoted_ascii();
    1.55 +              _out->print(" %s", klass_name);
    1.56 +            }
    1.57 +            _out->cr();
    1.58 +          }
    1.59 +          break;
    1.60 +        }
    1.61 +        case T_OBJECT: {
    1.62 +          oop value =  mirror->obj_field_acquire(fd->offset());
    1.63 +          if (value == NULL) {
    1.64 +            _out->print_cr("null");
    1.65 +          } else if (value->is_instance()) {
    1.66 +            if (value->is_a(SystemDictionary::String_klass())) {
    1.67 +              _out->print("\"");
    1.68 +              _out->print_raw(java_lang_String::as_quoted_ascii(value));
    1.69 +              _out->print_cr("\"");
    1.70 +            } else {
    1.71 +              const char* klass_name  = value->klass()->name()->as_quoted_ascii();
    1.72 +              _out->print_cr(klass_name);
    1.73 +            }
    1.74 +          } else {
    1.75 +            ShouldNotReachHere();
    1.76 +          }
    1.77 +          break;
    1.78 +        }
    1.79 +        default:
    1.80 +          ShouldNotReachHere();
    1.81 +        }
    1.82 +    }
    1.83 +  }
    1.84 +};
    1.85 +
    1.86 +
    1.87 +void ciInstanceKlass::dump_replay_data(outputStream* out) {
    1.88 +  ASSERT_IN_VM;
    1.89 +  InstanceKlass* ik = get_instanceKlass();
    1.90 +  ConstantPool*  cp = ik->constants();
    1.91 +
    1.92 +  // Try to record related loaded classes
    1.93 +  Klass* sub = ik->subklass();
    1.94 +  while (sub != NULL) {
    1.95 +    if (sub->oop_is_instance()) {
    1.96 +      out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
    1.97 +    }
    1.98 +    sub = sub->next_sibling();
    1.99 +  }
   1.100 +
   1.101 +  // Dump out the state of the constant pool tags.  During replay the
   1.102 +  // tags will be validated for things which shouldn't change and
   1.103 +  // classes will be resolved if the tags indicate that they were
   1.104 +  // resolved at compile time.
   1.105 +  out->print("ciInstanceKlass %s %d %d %d", ik->name()->as_quoted_ascii(),
   1.106 +             is_linked(), is_initialized(), cp->length());
   1.107 +  for (int index = 1; index < cp->length(); index++) {
   1.108 +    out->print(" %d", cp->tags()->at(index));
   1.109 +  }
   1.110 +  out->cr();
   1.111 +  if (is_initialized()) {
   1.112 +    //  Dump out the static final fields in case the compilation relies
   1.113 +    //  on their value for correct replay.
   1.114 +    StaticFinalFieldPrinter sffp(out, ik->name()->as_quoted_ascii());
   1.115 +    ik->do_local_static_fields(&sffp);
   1.116 +  }
   1.117 +}

mercurial