712 }
713 return (Field[])result.toArray(new Field[result.size()]);
714 }
715
716 public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
717 if (getSuper() != null) {
718 ((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
719 }
720 int length = getJavaFieldsCount();
721 for (int index = 0; index < length; index++) {
722 short accessFlags = getFieldAccessFlags(index);
723 FieldType type = new FieldType(getFieldSignature(index));
724 AccessFlags access = new AccessFlags(accessFlags);
725 if (!access.isStatic()) {
726 visitField(visitor, type, index);
727 }
728 }
729 }
730
731 /** Field access by name. */
732 public Field findLocalField(Symbol name, Symbol sig) {
733 int length = getJavaFieldsCount();
734 for (int i = 0; i < length; i++) {
735 Symbol f_name = getFieldName(i);
736 Symbol f_sig = getFieldSignature(i);
737 if (name.equals(f_name) && sig.equals(f_sig)) {
738 return newField(i);
739 }
740 }
741
742 return null;
743 }
744
745 /** Find field in direct superinterfaces. */
746 public Field findInterfaceField(Symbol name, Symbol sig) {
747 KlassArray interfaces = getLocalInterfaces();
748 int n = interfaces.length();
749 for (int i = 0; i < n; i++) {
750 InstanceKlass intf1 = (InstanceKlass) interfaces.getAt(i);
751 if (Assert.ASSERTS_ENABLED) {
752 Assert.that(intf1.isInterface(), "just checking type");
753 }
754 // search for field in current interface
755 Field f = intf1.findLocalField(name, sig);
756 if (f != null) {
757 if (Assert.ASSERTS_ENABLED) {
758 Assert.that(f.getAccessFlagsObj().isStatic(), "interface field must be static");
759 }
760 return f;
761 }
762 // search for field in direct superinterfaces
763 f = intf1.findInterfaceField(name, sig);
764 if (f != null) return f;
765 }
766 // otherwise field lookup fails
767 return null;
768 }
769
770 /** Find field according to JVM spec 5.4.3.2, returns the klass in
771 which the field is defined. */
772 public Field findField(Symbol name, Symbol sig) {
773 // search order according to newest JVM spec (5.4.3.2, p.167).
774 // 1) search for field in current klass
775 Field f = findLocalField(name, sig);
776 if (f != null) return f;
777
778 // 2) search for field recursively in direct superinterfaces
779 f = findInterfaceField(name, sig);
780 if (f != null) return f;
781
782 // 3) apply field lookup recursively if superclass exists
783 InstanceKlass supr = (InstanceKlass) getSuper();
784 if (supr != null) return supr.findField(name, sig);
785
786 // 4) otherwise field lookup fails
787 return null;
788 }
789
790 /** Find field according to JVM spec 5.4.3.2, returns the klass in
791 which the field is defined (convenience routine) */
792 public Field findField(String name, String sig) {
793 SymbolTable symbols = VM.getVM().getSymbolTable();
794 Symbol nameSym = symbols.probe(name);
795 Symbol sigSym = symbols.probe(sig);
796 if (nameSym == null || sigSym == null) {
797 return null;
798 }
799 return findField(nameSym, sigSym);
800 }
801
802 /** Find field according to JVM spec 5.4.3.2, returns the klass in
803 which the field is defined (retained only for backward
804 compatibility with jdbx) */
805 public Field findFieldDbg(String name, String sig) {
806 return findField(name, sig);
807 }
808
809 /** Get field by its index in the fields array. Only designed for
810 use in a debugging system. */
811 public Field getFieldByIndex(int fieldIndex) {
812 return newField(fieldIndex);
813 }
814
815
816 /** Return a List of SA Fields for the fields declared in this class.
817 Inherited fields are not included.
818 Return an empty list if there are no fields declared in this class.
819 Only designed for use in a debugging system. */
820 public List getImmediateFields() {
821 // A list of Fields for each field declared in this class/interface,
822 // not including inherited fields.
915
916 public Klass arrayKlassImpl(boolean orNull, int n) {
917 // FIXME: in reflective system this would need to change to
918 // actually allocate
919 if (getArrayKlasses() == null) { return null; }
920 ObjArrayKlass oak = (ObjArrayKlass) getArrayKlasses();
921 if (orNull) {
922 return oak.arrayKlassOrNull(n);
923 }
924 return oak.arrayKlass(n);
925 }
926
927 public Klass arrayKlassImpl(boolean orNull) {
928 return arrayKlassImpl(orNull, 1);
929 }
930
931 public String signature() {
932 return "L" + super.signature() + ";";
933 }
934
935 /** Convenience routine taking Strings; lookup is done in
936 SymbolTable. */
937 public Method findMethod(String name, String sig) {
938 SymbolTable syms = VM.getVM().getSymbolTable();
939 Symbol nameSym = syms.probe(name);
940 Symbol sigSym = syms.probe(sig);
941 if (nameSym == null || sigSym == null) {
942 return null;
943 }
944 return findMethod(nameSym, sigSym);
945 }
946
947 /** Find method in vtable. */
948 public Method findMethod(Symbol name, Symbol sig) {
949 return findMethod(getMethods(), name, sig);
950 }
951
952 /** Breakpoint support (see methods on Method* for details) */
953 public BreakpointInfo getBreakpoints() {
954 if (!VM.getVM().isJvmtiSupported()) {
955 return null;
956 }
957 Address addr = getAddress().getAddressAt(breakpoints.getOffset());
958 return (BreakpointInfo) VMObjectFactory.newObject(BreakpointInfo.class, addr);
959 }
960
961 public IntArray getMethodOrdering() {
962 Address addr = getAddress().getAddressAt(methodOrdering.getOffset());
963 return (IntArray) VMObjectFactory.newObject(IntArray.class, addr);
964 }
965
966 public U2Array getFields() {
967 Address addr = getAddress().getAddressAt(fields.getOffset());
968 return (U2Array) VMObjectFactory.newObject(U2Array.class, addr);
1038 return new DoubleField(this, index);
1039 }
1040 if (type.isFloat()) {
1041 return new FloatField(this, index);
1042 }
1043 if (type.isInt()) {
1044 return new IntField(this, index);
1045 }
1046 if (type.isLong()) {
1047 return new LongField(this, index);
1048 }
1049 if (type.isShort()) {
1050 return new ShortField(this, index);
1051 }
1052 if (type.isBoolean()) {
1053 return new BooleanField(this, index);
1054 }
1055 throw new RuntimeException("Illegal field type at index " + index);
1056 }
1057
1058 private static Method findMethod(MethodArray methods, Symbol name, Symbol signature) {
1059 int len = methods.length();
1060 // methods are sorted, so do binary search
1061 int l = 0;
1062 int h = len - 1;
1063 while (l <= h) {
1064 int mid = (l + h) >> 1;
1065 Method m = methods.at(mid);
1066 long res = m.getName().fastCompare(name);
1067 if (res == 0) {
1068 // found matching name; do linear search to find matching signature
1069 // first, quick check for common case
1070 if (m.getSignature().equals(signature)) return m;
1071 // search downwards through overloaded methods
1072 int i;
1073 for (i = mid - 1; i >= l; i--) {
1074 Method m1 = methods.at(i);
1075 if (!m1.getName().equals(name)) break;
1076 if (m1.getSignature().equals(signature)) return m1;
1077 }
1078 // search upwards
1079 for (i = mid + 1; i <= h; i++) {
1080 Method m1 = methods.at(i);
1081 if (!m1.getName().equals(name)) break;
1082 if (m1.getSignature().equals(signature)) return m1;
1083 }
1084 // not found
1085 if (Assert.ASSERTS_ENABLED) {
1086 int index = linearSearch(methods, name, signature);
1087 if (index != -1) {
1088 throw new DebuggerException("binary search bug: should have found entry " + index);
1089 }
1090 }
1091 return null;
1092 } else if (res < 0) {
1093 l = mid + 1;
1094 } else {
1095 h = mid - 1;
1096 }
1097 }
1098 if (Assert.ASSERTS_ENABLED) {
1099 int index = linearSearch(methods, name, signature);
1100 if (index != -1) {
1101 throw new DebuggerException("binary search bug: should have found entry " + index);
1102 }
1103 }
1104 return null;
1105 }
1106
1107 private static int linearSearch(MethodArray methods, Symbol name, Symbol signature) {
1108 int len = (int) methods.length();
1109 for (int index = 0; index < len; index++) {
1110 Method m = methods.at(index);
1111 if (m.getSignature().equals(signature) && m.getName().equals(name)) {
1112 return index;
1113 }
1114 }
1115 return -1;
1116 }
1117
1118 public void dumpReplayData(PrintStream out) {
1119 ConstantPool cp = getConstants();
1120
1121 // Try to record related loaded classes
1122 Klass sub = getSubklassKlass();
1123 while (sub != null) {
1124 if (sub instanceof InstanceKlass) {
1125 out.println("instanceKlass " + sub.getName().asString());
1126 }
1127 sub = sub.getNextSiblingKlass();
|
712 }
713 return (Field[])result.toArray(new Field[result.size()]);
714 }
715
716 public void iterateNonStaticFields(OopVisitor visitor, Oop obj) {
717 if (getSuper() != null) {
718 ((InstanceKlass) getSuper()).iterateNonStaticFields(visitor, obj);
719 }
720 int length = getJavaFieldsCount();
721 for (int index = 0; index < length; index++) {
722 short accessFlags = getFieldAccessFlags(index);
723 FieldType type = new FieldType(getFieldSignature(index));
724 AccessFlags access = new AccessFlags(accessFlags);
725 if (!access.isStatic()) {
726 visitField(visitor, type, index);
727 }
728 }
729 }
730
731 /** Field access by name. */
732 public Field findLocalField(String name, String sig) {
733 int length = getJavaFieldsCount();
734 for (int i = 0; i < length; i++) {
735 Symbol f_name = getFieldName(i);
736 Symbol f_sig = getFieldSignature(i);
737 if (f_name.equals(name) && f_sig.equals(sig)) {
738 return newField(i);
739 }
740 }
741
742 return null;
743 }
744
745 /** Find field in direct superinterfaces. */
746 public Field findInterfaceField(String name, String sig) {
747 KlassArray interfaces = getLocalInterfaces();
748 int n = interfaces.length();
749 for (int i = 0; i < n; i++) {
750 InstanceKlass intf1 = (InstanceKlass) interfaces.getAt(i);
751 if (Assert.ASSERTS_ENABLED) {
752 Assert.that(intf1.isInterface(), "just checking type");
753 }
754 // search for field in current interface
755 Field f = intf1.findLocalField(name, sig);
756 if (f != null) {
757 if (Assert.ASSERTS_ENABLED) {
758 Assert.that(f.getAccessFlagsObj().isStatic(), "interface field must be static");
759 }
760 return f;
761 }
762 // search for field in direct superinterfaces
763 f = intf1.findInterfaceField(name, sig);
764 if (f != null) return f;
765 }
766 // otherwise field lookup fails
767 return null;
768 }
769
770 /** Find field according to JVM spec 5.4.3.2, returns the klass in
771 which the field is defined. */
772 public Field findField(String name, String sig) {
773 // search order according to newest JVM spec (5.4.3.2, p.167).
774 // 1) search for field in current klass
775 Field f = findLocalField(name, sig);
776 if (f != null) return f;
777
778 // 2) search for field recursively in direct superinterfaces
779 f = findInterfaceField(name, sig);
780 if (f != null) return f;
781
782 // 3) apply field lookup recursively if superclass exists
783 InstanceKlass supr = (InstanceKlass) getSuper();
784 if (supr != null) return supr.findField(name, sig);
785
786 // 4) otherwise field lookup fails
787 return null;
788 }
789
790 /** Find field according to JVM spec 5.4.3.2, returns the klass in
791 which the field is defined (retained only for backward
792 compatibility with jdbx) */
793 public Field findFieldDbg(String name, String sig) {
794 return findField(name, sig);
795 }
796
797 /** Get field by its index in the fields array. Only designed for
798 use in a debugging system. */
799 public Field getFieldByIndex(int fieldIndex) {
800 return newField(fieldIndex);
801 }
802
803
804 /** Return a List of SA Fields for the fields declared in this class.
805 Inherited fields are not included.
806 Return an empty list if there are no fields declared in this class.
807 Only designed for use in a debugging system. */
808 public List getImmediateFields() {
809 // A list of Fields for each field declared in this class/interface,
810 // not including inherited fields.
903
904 public Klass arrayKlassImpl(boolean orNull, int n) {
905 // FIXME: in reflective system this would need to change to
906 // actually allocate
907 if (getArrayKlasses() == null) { return null; }
908 ObjArrayKlass oak = (ObjArrayKlass) getArrayKlasses();
909 if (orNull) {
910 return oak.arrayKlassOrNull(n);
911 }
912 return oak.arrayKlass(n);
913 }
914
915 public Klass arrayKlassImpl(boolean orNull) {
916 return arrayKlassImpl(orNull, 1);
917 }
918
919 public String signature() {
920 return "L" + super.signature() + ";";
921 }
922
923 /** Find method in vtable. */
924 public Method findMethod(String name, String sig) {
925 return findMethod(getMethods(), name, sig);
926 }
927
928 /** Breakpoint support (see methods on Method* for details) */
929 public BreakpointInfo getBreakpoints() {
930 if (!VM.getVM().isJvmtiSupported()) {
931 return null;
932 }
933 Address addr = getAddress().getAddressAt(breakpoints.getOffset());
934 return (BreakpointInfo) VMObjectFactory.newObject(BreakpointInfo.class, addr);
935 }
936
937 public IntArray getMethodOrdering() {
938 Address addr = getAddress().getAddressAt(methodOrdering.getOffset());
939 return (IntArray) VMObjectFactory.newObject(IntArray.class, addr);
940 }
941
942 public U2Array getFields() {
943 Address addr = getAddress().getAddressAt(fields.getOffset());
944 return (U2Array) VMObjectFactory.newObject(U2Array.class, addr);
1014 return new DoubleField(this, index);
1015 }
1016 if (type.isFloat()) {
1017 return new FloatField(this, index);
1018 }
1019 if (type.isInt()) {
1020 return new IntField(this, index);
1021 }
1022 if (type.isLong()) {
1023 return new LongField(this, index);
1024 }
1025 if (type.isShort()) {
1026 return new ShortField(this, index);
1027 }
1028 if (type.isBoolean()) {
1029 return new BooleanField(this, index);
1030 }
1031 throw new RuntimeException("Illegal field type at index " + index);
1032 }
1033
1034 private static Method findMethod(MethodArray methods, String name, String signature) {
1035 int index = linearSearch(methods, name, signature);
1036 if (index != -1) {
1037 return methods.at(index);
1038 } else {
1039 return null;
1040 }
1041 }
1042
1043 private static int linearSearch(MethodArray methods, String name, String signature) {
1044 int len = (int) methods.length();
1045 for (int index = 0; index < len; index++) {
1046 Method m = methods.at(index);
1047 if (m.getSignature().equals(signature) && m.getName().equals(name)) {
1048 return index;
1049 }
1050 }
1051 return -1;
1052 }
1053
1054 public void dumpReplayData(PrintStream out) {
1055 ConstantPool cp = getConstants();
1056
1057 // Try to record related loaded classes
1058 Klass sub = getSubklassKlass();
1059 while (sub != null) {
1060 if (sub instanceof InstanceKlass) {
1061 out.println("instanceKlass " + sub.getName().asString());
1062 }
1063 sub = sub.getNextSiblingKlass();
|