472 } |
472 } |
473 return lh / VM.getVM().getAddressSize(); |
473 return lh / VM.getVM().getAddressSize(); |
474 } |
474 } |
475 |
475 |
476 // same as enum InnerClassAttributeOffset in VM code. |
476 // same as enum InnerClassAttributeOffset in VM code. |
477 public static interface InnerClassAttributeOffset { |
477 private static class InnerClassAttributeOffset { |
478 // from JVM spec. "InnerClasses" attribute |
478 // from JVM spec. "InnerClasses" attribute |
479 public static final int innerClassInnerClassInfoOffset = 0; |
479 public static int innerClassInnerClassInfoOffset; |
480 public static final int innerClassOuterClassInfoOffset = 1; |
480 public static int innerClassOuterClassInfoOffset; |
481 public static final int innerClassInnerNameOffset = 2; |
481 public static int innerClassInnerNameOffset; |
482 public static final int innerClassAccessFlagsOffset = 3; |
482 public static int innerClassAccessFlagsOffset; |
483 public static final int innerClassNextOffset = 4; |
483 public static int innerClassNextOffset; |
484 }; |
484 static { |
485 |
485 VM.registerVMInitializedObserver(new Observer() { |
486 public static interface EnclosingMethodAttributeOffset { |
486 public void update(Observable o, Object data) { |
487 public static final int enclosing_method_class_index_offset = 0; |
487 initialize(VM.getVM().getTypeDataBase()); |
488 public static final int enclosing_method_method_index_offset = 1; |
488 } |
489 public static final int enclosing_method_attribute_size = 2; |
489 }); |
490 }; |
490 } |
|
491 |
|
492 private static synchronized void initialize(TypeDataBase db) { |
|
493 innerClassInnerClassInfoOffset = db.lookupIntConstant( |
|
494 "InstanceKlass::inner_class_inner_class_info_offset").intValue(); |
|
495 innerClassOuterClassInfoOffset = db.lookupIntConstant( |
|
496 "InstanceKlass::inner_class_outer_class_info_offset").intValue(); |
|
497 innerClassInnerNameOffset = db.lookupIntConstant( |
|
498 "InstanceKlass::inner_class_inner_name_offset").intValue(); |
|
499 innerClassAccessFlagsOffset = db.lookupIntConstant( |
|
500 "InstanceKlass::inner_class_access_flags_offset").intValue(); |
|
501 innerClassNextOffset = db.lookupIntConstant( |
|
502 "InstanceKlass::inner_class_next_offset").intValue(); |
|
503 } |
|
504 } |
|
505 |
|
506 private static class EnclosingMethodAttributeOffset { |
|
507 public static int enclosingMethodAttributeSize; |
|
508 static { |
|
509 VM.registerVMInitializedObserver(new Observer() { |
|
510 public void update(Observable o, Object data) { |
|
511 initialize(VM.getVM().getTypeDataBase()); |
|
512 } |
|
513 }); |
|
514 } |
|
515 private static synchronized void initialize(TypeDataBase db) { |
|
516 enclosingMethodAttributeSize = db.lookupIntConstant("InstanceKlass::enclosing_method_attribute_size").intValue(); |
|
517 } |
|
518 } |
491 |
519 |
492 // refer to compute_modifier_flags in VM code. |
520 // refer to compute_modifier_flags in VM code. |
493 public long computeModifierFlags() { |
521 public long computeModifierFlags() { |
494 long access = getAccessFlags(); |
522 long access = getAccessFlags(); |
495 // But check if it happens to be member class. |
523 // But check if it happens to be member class. |
496 U2Array innerClassList = getInnerClasses(); |
524 U2Array innerClassList = getInnerClasses(); |
497 int length = (innerClassList == null)? 0 : (int) innerClassList.length(); |
525 int length = (innerClassList == null)? 0 : (int) innerClassList.length(); |
498 if (length > 0) { |
526 if (length > 0) { |
499 if (Assert.ASSERTS_ENABLED) { |
527 if (Assert.ASSERTS_ENABLED) { |
500 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 || |
528 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 || |
501 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size, |
529 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosingMethodAttributeSize, |
502 "just checking"); |
530 "just checking"); |
503 } |
531 } |
504 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) { |
532 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) { |
505 if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) { |
533 if (i == length - EnclosingMethodAttributeOffset.enclosingMethodAttributeSize) { |
506 break; |
534 break; |
507 } |
535 } |
508 int ioff = innerClassList.at(i + |
536 int ioff = innerClassList.at(i + |
509 InnerClassAttributeOffset.innerClassInnerClassInfoOffset); |
537 InnerClassAttributeOffset.innerClassInnerClassInfoOffset); |
510 // 'ioff' can be zero. |
538 // 'ioff' can be zero. |
545 U2Array innerClassList = getInnerClasses(); |
573 U2Array innerClassList = getInnerClasses(); |
546 int length = ( innerClassList == null)? 0 : (int) innerClassList.length(); |
574 int length = ( innerClassList == null)? 0 : (int) innerClassList.length(); |
547 if (length > 0) { |
575 if (length > 0) { |
548 if (Assert.ASSERTS_ENABLED) { |
576 if (Assert.ASSERTS_ENABLED) { |
549 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 || |
577 Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 || |
550 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size, |
578 length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosingMethodAttributeSize, |
551 "just checking"); |
579 "just checking"); |
552 } |
580 } |
553 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) { |
581 for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) { |
554 if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) { |
582 if (i == length - EnclosingMethodAttributeOffset.enclosingMethodAttributeSize) { |
555 break; |
583 break; |
556 } |
584 } |
557 int ioff = innerClassList.at(i + |
585 int ioff = innerClassList.at(i + |
558 InnerClassAttributeOffset.innerClassInnerClassInfoOffset); |
586 InnerClassAttributeOffset.innerClassInnerClassInfoOffset); |
559 // 'ioff' can be zero. |
587 // 'ioff' can be zero. |