1 /* 2 * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.hotspot.test; 24 25 import java.lang.annotation.Annotation; 26 import java.lang.management.ManagementFactory; 27 import java.lang.reflect.Field; 28 import java.lang.reflect.Type; 29 import javax.management.Attribute; 30 import javax.management.MBeanAttributeInfo; 31 import javax.management.MBeanInfo; 32 import javax.management.MBeanOperationInfo; 33 import javax.management.MBeanServer; 34 import javax.management.ObjectInstance; 35 import javax.management.ObjectName; 36 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; 37 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; 38 import jdk.vm.ci.meta.Assumptions; 39 import jdk.vm.ci.meta.Constant; 40 import jdk.vm.ci.meta.ConstantPool; 41 import jdk.vm.ci.meta.ExceptionHandler; 42 import jdk.vm.ci.meta.JavaConstant; 43 import jdk.vm.ci.meta.JavaKind; 44 import jdk.vm.ci.meta.LineNumberTable; 45 import jdk.vm.ci.meta.LocalVariableTable; 46 import jdk.vm.ci.meta.ProfilingInfo; 47 import jdk.vm.ci.meta.ResolvedJavaField; 48 import jdk.vm.ci.meta.ResolvedJavaMethod; 49 import jdk.vm.ci.meta.ResolvedJavaType; 50 import jdk.vm.ci.meta.Signature; 51 import jdk.vm.ci.meta.SpeculationLog; 52 import org.graalvm.compiler.debug.GraalDebugConfig; 53 import org.graalvm.compiler.hotspot.HotSpotGraalMBean; 54 import org.graalvm.compiler.options.OptionValues; 55 import org.graalvm.util.EconomicMap; 56 import static org.junit.Assert.assertEquals; 57 import static org.junit.Assert.assertNotNull; 58 import static org.junit.Assert.assertNotSame; 59 import static org.junit.Assert.assertNull; 60 import static org.junit.Assert.assertSame; 61 import static org.junit.Assert.assertTrue; 62 import org.junit.Test; 63 64 public class HotSpotGraalMBeanTest { 65 @Test 66 public void registration() throws Exception { 67 ObjectName name; 68 69 Field field = null; 70 try { 71 field = stopMBeanServer(); 72 } catch (Exception ex) { 73 if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { 74 // skip on JDK9 75 return; 76 } 77 } 78 assertNull("The platformMBeanServer isn't initialized now", field.get(null)); 79 80 HotSpotGraalMBean bean = HotSpotGraalMBean.create(null); 81 assertNotNull("Bean created", bean); 82 83 assertNull("It is not registered yet", bean.ensureRegistered(true)); 84 85 MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 86 87 assertNotNull("Now the bean thinks it is registered", name = bean.ensureRegistered(true)); 88 89 assertNotNull("And the bean is found", server.getObjectInstance(name)); 90 } 91 92 private static Field stopMBeanServer() throws NoSuchFieldException, SecurityException, IllegalAccessException, IllegalArgumentException { 93 final Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer"); 94 field.setAccessible(true); 95 field.set(null, null); 96 return field; 97 } 98 99 @Test 100 public void readBeanInfo() throws Exception { 101 ObjectName name; 102 103 assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); 104 105 HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); 106 assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); 107 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 108 109 ObjectInstance bean = server.getObjectInstance(name); 110 assertNotNull("Bean is registered", bean); 111 MBeanInfo info = server.getMBeanInfo(name); 112 assertNotNull("Info is found", info); 113 114 MBeanAttributeInfo printCompilation = findAttributeInfo("PrintCompilation", info); 115 assertNotNull("PrintCompilation found", printCompilation); 116 assertEquals("true/false", Boolean.class.getName(), printCompilation.getType()); 117 118 Attribute printOn = new Attribute(printCompilation.getName(), Boolean.TRUE); 119 120 Object before = server.getAttribute(name, printCompilation.getName()); 121 server.setAttribute(name, printOn); 122 Object after = server.getAttribute(name, printCompilation.getName()); 123 124 assertNull("Default value was not set", before); 125 assertEquals("Changed to on", Boolean.TRUE, after); 126 } 127 128 private static MBeanAttributeInfo findAttributeInfo(String attrName, MBeanInfo info) { 129 MBeanAttributeInfo printCompilation = null; 130 for (MBeanAttributeInfo attr : info.getAttributes()) { 131 if (attr.getName().equals(attrName)) { 132 assertTrue("Readable", attr.isReadable()); 133 assertTrue("Writable", attr.isWritable()); 134 printCompilation = attr; 135 break; 136 } 137 } 138 return printCompilation; 139 } 140 141 @Test 142 public void optionsAreCached() throws Exception { 143 ObjectName name; 144 145 assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); 146 147 HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); 148 149 OptionValues original = new OptionValues(EconomicMap.create()); 150 151 assertSame(original, realBean.optionsFor(original, null)); 152 153 assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); 154 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 155 156 ObjectInstance bean = server.getObjectInstance(name); 157 assertNotNull("Bean is registered", bean); 158 MBeanInfo info = server.getMBeanInfo(name); 159 assertNotNull("Info is found", info); 160 161 MBeanAttributeInfo dump = findAttributeInfo("Dump", info); 162 163 Attribute dumpTo1 = new Attribute(dump.getName(), 1); 164 165 server.setAttribute(name, dumpTo1); 166 Object after = server.getAttribute(name, dump.getName()); 167 assertEquals(1, after); 168 169 final OptionValues modified1 = realBean.optionsFor(original, null); 170 assertNotSame(original, modified1); 171 final OptionValues modified2 = realBean.optionsFor(original, null); 172 assertSame("Options are cached", modified1, modified2); 173 174 } 175 176 @Test 177 public void dumpOperation() throws Exception { 178 Field field = null; 179 try { 180 field = stopMBeanServer(); 181 } catch (Exception ex) { 182 if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { 183 // skip on JDK9 184 return; 185 } 186 } 187 assertNull("The platformMBeanServer isn't initialized now", field.get(null)); 188 189 ObjectName name; 190 191 assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); 192 193 HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); 194 195 assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); 196 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 197 198 ObjectInstance bean = server.getObjectInstance(name); 199 assertNotNull("Bean is registered", bean); 200 201 MBeanInfo info = server.getMBeanInfo(name); 202 assertNotNull("Info is found", info); 203 204 final MBeanOperationInfo[] arr = info.getOperations(); 205 assertEquals("Currently three overloads", 3, arr.length); 206 MBeanOperationInfo dumpOp = null; 207 for (int i = 0; i < arr.length; i++) { 208 assertEquals("dumpMethod", arr[i].getName()); 209 if (arr[i].getSignature().length == 3) { 210 dumpOp = arr[i]; 211 } 212 } 213 assertNotNull("three args variant found", dumpOp); 214 215 server.invoke(name, "dumpMethod", new Object[]{ 216 "java.util.Arrays", "asList", ":3" 217 }, null); 218 219 MBeanAttributeInfo dump = findAttributeInfo("Dump", info); 220 Attribute dumpTo1 = new Attribute(dump.getName(), ""); 221 server.setAttribute(name, dumpTo1); 222 Object after = server.getAttribute(name, dump.getName()); 223 assertEquals("", after); 224 225 OptionValues empty = new OptionValues(EconomicMap.create()); 226 OptionValues unsetDump = realBean.optionsFor(empty, null); 227 228 final OptionValues forMethod = realBean.optionsFor(unsetDump, new MockResolvedJavaMethod()); 229 assertNotSame(unsetDump, forMethod); 230 Object nothing = unsetDump.getMap().get(GraalDebugConfig.Options.Dump); 231 assertEquals("Empty string", "", nothing); 232 233 Object specialValue = forMethod.getMap().get(GraalDebugConfig.Options.Dump); 234 assertEquals(":3", specialValue); 235 236 OptionValues normalMethod = realBean.optionsFor(unsetDump, null); 237 Object noSpecialValue = normalMethod.getMap().get(GraalDebugConfig.Options.Dump); 238 assertEquals("Empty string", "", noSpecialValue); 239 } 240 241 private static class MockResolvedJavaMethod implements HotSpotResolvedJavaMethod { 242 MockResolvedJavaMethod() { 243 } 244 245 @Override 246 public boolean isCallerSensitive() { 247 throw new UnsupportedOperationException(); 248 } 249 250 @Override 251 public HotSpotResolvedObjectType getDeclaringClass() { 252 return new MockResolvedObjectType(); 253 } 254 255 @Override 256 public boolean isForceInline() { 257 throw new UnsupportedOperationException(); 258 } 259 260 @Override 261 public boolean hasReservedStackAccess() { 262 throw new UnsupportedOperationException(); 263 } 264 265 @Override 266 public void setNotInlineable() { 267 throw new UnsupportedOperationException(); 268 } 269 270 @Override 271 public boolean ignoredBySecurityStackWalk() { 272 throw new UnsupportedOperationException(); 273 } 274 275 @Override 276 public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) { 277 throw new UnsupportedOperationException(); 278 } 279 280 @Override 281 public boolean hasCompiledCode() { 282 throw new UnsupportedOperationException(); 283 } 284 285 @Override 286 public boolean hasCompiledCodeAtLevel(int level) { 287 throw new UnsupportedOperationException(); 288 } 289 290 @Override 291 public int vtableEntryOffset(ResolvedJavaType resolved) { 292 throw new UnsupportedOperationException(); 293 } 294 295 @Override 296 public int intrinsicId() { 297 throw new UnsupportedOperationException(); 298 } 299 300 @Override 301 public int allocateCompileId(int entryBCI) { 302 throw new UnsupportedOperationException(); 303 } 304 305 @Override 306 public boolean hasCodeAtLevel(int entryBCI, int level) { 307 throw new UnsupportedOperationException(); 308 } 309 310 @Override 311 public byte[] getCode() { 312 throw new UnsupportedOperationException(); 313 } 314 315 @Override 316 public int getCodeSize() { 317 throw new UnsupportedOperationException(); 318 } 319 320 @Override 321 public int getMaxLocals() { 322 throw new UnsupportedOperationException(); 323 } 324 325 @Override 326 public int getMaxStackSize() { 327 throw new UnsupportedOperationException(); 328 } 329 330 @Override 331 public boolean isSynthetic() { 332 throw new UnsupportedOperationException(); 333 } 334 335 @Override 336 public boolean isVarArgs() { 337 throw new UnsupportedOperationException(); 338 } 339 340 @Override 341 public boolean isBridge() { 342 throw new UnsupportedOperationException(); 343 } 344 345 @Override 346 public boolean isClassInitializer() { 347 throw new UnsupportedOperationException(); 348 } 349 350 @Override 351 public boolean isConstructor() { 352 throw new UnsupportedOperationException(); 353 } 354 355 @Override 356 public boolean canBeStaticallyBound() { 357 throw new UnsupportedOperationException(); 358 } 359 360 @Override 361 public ExceptionHandler[] getExceptionHandlers() { 362 throw new UnsupportedOperationException(); 363 } 364 365 @Override 366 public StackTraceElement asStackTraceElement(int bci) { 367 throw new UnsupportedOperationException(); 368 } 369 370 @Override 371 public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) { 372 throw new UnsupportedOperationException(); 373 } 374 375 @Override 376 public void reprofile() { 377 throw new UnsupportedOperationException(); 378 } 379 380 @Override 381 public ConstantPool getConstantPool() { 382 throw new UnsupportedOperationException(); 383 } 384 385 @Override 386 public Annotation[][] getParameterAnnotations() { 387 throw new UnsupportedOperationException(); 388 } 389 390 @Override 391 public Type[] getGenericParameterTypes() { 392 throw new UnsupportedOperationException(); 393 } 394 395 @Override 396 public boolean canBeInlined() { 397 throw new UnsupportedOperationException(); 398 } 399 400 @Override 401 public boolean hasNeverInlineDirective() { 402 throw new UnsupportedOperationException(); 403 } 404 405 @Override 406 public boolean shouldBeInlined() { 407 throw new UnsupportedOperationException(); 408 } 409 410 @Override 411 public LineNumberTable getLineNumberTable() { 412 throw new UnsupportedOperationException(); 413 } 414 415 @Override 416 public LocalVariableTable getLocalVariableTable() { 417 throw new UnsupportedOperationException(); 418 } 419 420 @Override 421 public Constant getEncoding() { 422 throw new UnsupportedOperationException(); 423 } 424 425 @Override 426 public boolean isInVirtualMethodTable(ResolvedJavaType resolved) { 427 throw new UnsupportedOperationException(); 428 } 429 430 @Override 431 public SpeculationLog getSpeculationLog() { 432 throw new UnsupportedOperationException(); 433 } 434 435 @Override 436 public String getName() { 437 return "asList"; 438 } 439 440 @Override 441 public Signature getSignature() { 442 throw new UnsupportedOperationException(); 443 } 444 445 @Override 446 public int getModifiers() { 447 throw new UnsupportedOperationException(); 448 } 449 450 @Override 451 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 452 throw new UnsupportedOperationException(); 453 } 454 455 @Override 456 public Annotation[] getAnnotations() { 457 throw new UnsupportedOperationException(); 458 } 459 460 @Override 461 public Annotation[] getDeclaredAnnotations() { 462 throw new UnsupportedOperationException(); 463 } 464 465 @Override 466 public boolean isIntrinsicCandidate() { 467 return true; 468 } 469 470 private static class MockResolvedObjectType implements HotSpotResolvedObjectType { 471 MockResolvedObjectType() { 472 } 473 474 @Override 475 public long getFingerprint() { 476 return 0L; 477 } 478 479 @Override 480 public HotSpotResolvedObjectType getArrayClass() { 481 throw new UnsupportedOperationException(); 482 } 483 484 @Override 485 public ResolvedJavaType getComponentType() { 486 throw new UnsupportedOperationException(); 487 } 488 489 @Override 490 public Assumptions.AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() { 491 throw new UnsupportedOperationException(); 492 } 493 494 @Override 495 public HotSpotResolvedObjectType getSuperclass() { 496 throw new UnsupportedOperationException(); 497 } 498 499 @Override 500 public HotSpotResolvedObjectType[] getInterfaces() { 501 throw new UnsupportedOperationException(); 502 } 503 504 @Override 505 public HotSpotResolvedObjectType getSupertype() { 506 throw new UnsupportedOperationException(); 507 } 508 509 @Override 510 public HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType) { 511 throw new UnsupportedOperationException(); 512 } 513 514 @Override 515 public ConstantPool getConstantPool() { 516 throw new UnsupportedOperationException(); 517 } 518 519 @Override 520 public int instanceSize() { 521 throw new UnsupportedOperationException(); 522 } 523 524 @Override 525 public int getVtableLength() { 526 throw new UnsupportedOperationException(); 527 } 528 529 @Override 530 public Assumptions.AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method) { 531 throw new UnsupportedOperationException(); 532 } 533 534 @Override 535 public boolean isDefinitelyResolvedWithRespectTo(ResolvedJavaType accessingClass) { 536 throw new UnsupportedOperationException(); 537 } 538 539 @Override 540 public Constant klass() { 541 throw new UnsupportedOperationException(); 542 } 543 544 @Override 545 public boolean isPrimaryType() { 546 throw new UnsupportedOperationException(); 547 } 548 549 @Override 550 public int superCheckOffset() { 551 throw new UnsupportedOperationException(); 552 } 553 554 @Override 555 public long prototypeMarkWord() { 556 throw new UnsupportedOperationException(); 557 } 558 559 @Override 560 public int layoutHelper() { 561 throw new UnsupportedOperationException(); 562 } 563 564 @Override 565 public HotSpotResolvedObjectType getEnclosingType() { 566 throw new UnsupportedOperationException(); 567 } 568 569 @Override 570 public ResolvedJavaMethod getClassInitializer() { 571 throw new UnsupportedOperationException(); 572 } 573 574 @Override 575 public boolean hasFinalizer() { 576 throw new UnsupportedOperationException(); 577 } 578 579 @Override 580 public Assumptions.AssumptionResult<Boolean> hasFinalizableSubclass() { 581 throw new UnsupportedOperationException(); 582 } 583 584 @Override 585 public boolean isInterface() { 586 throw new UnsupportedOperationException(); 587 } 588 589 @Override 590 public boolean isInstanceClass() { 591 throw new UnsupportedOperationException(); 592 } 593 594 @Override 595 public boolean isInitialized() { 596 throw new UnsupportedOperationException(); 597 } 598 599 @Override 600 public void initialize() { 601 throw new UnsupportedOperationException(); 602 } 603 604 @Override 605 public boolean isLinked() { 606 throw new UnsupportedOperationException(); 607 } 608 609 @Override 610 public boolean isAssignableFrom(ResolvedJavaType other) { 611 throw new UnsupportedOperationException(); 612 } 613 614 @Override 615 public boolean isInstance(JavaConstant obj) { 616 throw new UnsupportedOperationException(); 617 } 618 619 @Override 620 public ResolvedJavaType getSingleImplementor() { 621 throw new UnsupportedOperationException(); 622 } 623 624 @Override 625 public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { 626 throw new UnsupportedOperationException(); 627 } 628 629 @Override 630 public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { 631 throw new UnsupportedOperationException(); 632 } 633 634 @Override 635 public ResolvedJavaField[] getStaticFields() { 636 throw new UnsupportedOperationException(); 637 } 638 639 @Override 640 public ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind) { 641 throw new UnsupportedOperationException(); 642 } 643 644 @Override 645 public String getSourceFileName() { 646 throw new UnsupportedOperationException(); 647 } 648 649 @Override 650 public boolean isLocal() { 651 throw new UnsupportedOperationException(); 652 } 653 654 @Override 655 public boolean isMember() { 656 throw new UnsupportedOperationException(); 657 } 658 659 @Override 660 public ResolvedJavaMethod[] getDeclaredConstructors() { 661 throw new UnsupportedOperationException(); 662 } 663 664 @Override 665 public ResolvedJavaMethod[] getDeclaredMethods() { 666 throw new UnsupportedOperationException(); 667 } 668 669 @Override 670 public boolean isCloneableWithAllocation() { 671 throw new UnsupportedOperationException(); 672 } 673 674 @Override 675 public String getName() { 676 return "Ljava/util/Arrays;"; 677 } 678 679 @Override 680 public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { 681 throw new UnsupportedOperationException(); 682 } 683 684 @Override 685 public int getModifiers() { 686 throw new UnsupportedOperationException(); 687 } 688 689 @Override 690 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 691 throw new UnsupportedOperationException(); 692 } 693 694 @Override 695 public Annotation[] getAnnotations() { 696 throw new UnsupportedOperationException(); 697 } 698 699 @Override 700 public Annotation[] getDeclaredAnnotations() { 701 throw new UnsupportedOperationException(); 702 } 703 } 704 } 705 }