1 /* 2 * Copyright (c) 2011, 2012, 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 24 package com.oracle.graal.hotspot.bridge; 25 26 import static com.oracle.graal.graph.UnsafeAccess.*; 27 import static com.oracle.graal.hotspot.CompilationTask.*; 28 import static com.oracle.graal.java.GraphBuilderPhase.*; 29 import static com.oracle.graal.phases.common.InliningUtil.*; 30 31 import java.io.*; 32 import java.lang.reflect.*; 33 import java.util.*; 34 import java.util.concurrent.*; 35 import java.util.concurrent.atomic.*; 36 37 import com.oracle.graal.api.meta.*; 38 import com.oracle.graal.debug.*; 39 import com.oracle.graal.debug.internal.*; 40 import com.oracle.graal.hotspot.*; 41 import com.oracle.graal.hotspot.debug.*; 42 import com.oracle.graal.hotspot.meta.*; 43 import com.oracle.graal.hotspot.phases.*; 44 import com.oracle.graal.java.*; 45 import com.oracle.graal.nodes.*; 46 import com.oracle.graal.nodes.debug.*; 47 import com.oracle.graal.nodes.spi.*; 48 import com.oracle.graal.phases.*; 49 import com.oracle.graal.phases.PhasePlan.PhasePosition; 50 import com.oracle.graal.printer.*; 51 import com.oracle.graal.replacements.*; 52 53 /** 54 * Exits from the HotSpot VM into Java code. 55 */ 56 public class VMToCompilerImpl implements VMToCompiler { 57 58 private final HotSpotGraalRuntime graalRuntime; 59 60 public final HotSpotResolvedPrimitiveType typeBoolean; 61 public final HotSpotResolvedPrimitiveType typeChar; 62 public final HotSpotResolvedPrimitiveType typeFloat; 63 public final HotSpotResolvedPrimitiveType typeDouble; 64 public final HotSpotResolvedPrimitiveType typeByte; 65 public final HotSpotResolvedPrimitiveType typeShort; 66 public final HotSpotResolvedPrimitiveType typeInt; 67 public final HotSpotResolvedPrimitiveType typeLong; 68 public final HotSpotResolvedPrimitiveType typeVoid; 69 70 private ThreadPoolExecutor compileQueue; 71 private ThreadPoolExecutor slowCompileQueue; 72 private AtomicInteger compileTaskIds = new AtomicInteger(); 73 74 private volatile boolean bootstrapRunning; 75 76 private PrintStream log = System.out; 77 78 private boolean quietMeterAndTime; 79 80 private long compilerStartTime; 81 82 public VMToCompilerImpl(HotSpotGraalRuntime compiler) { 83 this.graalRuntime = compiler; 84 85 typeBoolean = new HotSpotResolvedPrimitiveType(Kind.Boolean); 86 typeChar = new HotSpotResolvedPrimitiveType(Kind.Char); 87 typeFloat = new HotSpotResolvedPrimitiveType(Kind.Float); 88 typeDouble = new HotSpotResolvedPrimitiveType(Kind.Double); 89 typeByte = new HotSpotResolvedPrimitiveType(Kind.Byte); 90 typeShort = new HotSpotResolvedPrimitiveType(Kind.Short); 91 typeInt = new HotSpotResolvedPrimitiveType(Kind.Int); 92 typeLong = new HotSpotResolvedPrimitiveType(Kind.Long); 93 typeVoid = new HotSpotResolvedPrimitiveType(Kind.Void); 94 } 95 96 private static void initMirror(HotSpotResolvedPrimitiveType type, long offset) { 97 Class<?> mirror = type.mirror(); 98 unsafe.putObject(mirror, offset, type); 99 assert unsafe.getObject(mirror, offset) == type; 100 } 101 102 public void startCompiler() throws Throwable { 103 104 HotSpotVMConfig config = graalRuntime.getConfig(); 105 long offset = config.graalMirrorInClassOffset; 106 initMirror(typeBoolean, offset); 107 initMirror(typeChar, offset); 108 initMirror(typeFloat, offset); 109 initMirror(typeDouble, offset); 110 initMirror(typeByte, offset); 111 initMirror(typeShort, offset); 112 initMirror(typeInt, offset); 113 initMirror(typeLong, offset); 114 initMirror(typeVoid, offset); 115 116 if (GraalOptions.LogFile != null) { 117 try { 118 final boolean enableAutoflush = true; 119 log = new PrintStream(new FileOutputStream(GraalOptions.LogFile), enableAutoflush); 120 } catch (FileNotFoundException e) { 121 throw new RuntimeException("couldn't open log file: " + GraalOptions.LogFile, e); 122 } 123 } 124 125 TTY.initialize(log); 126 127 if (GraalOptions.Log == null && GraalOptions.Meter == null && GraalOptions.Time == null && GraalOptions.Dump == null) { 128 if (GraalOptions.MethodFilter != null) { 129 TTY.println("WARNING: Ignoring MethodFilter option since Log, Meter, Time and Dump options are all null"); 130 } 131 } 132 133 if (config.ciTime) { 134 quietMeterAndTime = (GraalOptions.Meter == null && GraalOptions.Time == null); 135 GraalOptions.Debug = true; 136 GraalOptions.Meter = ""; 137 GraalOptions.Time = ""; 138 } 139 140 if (GraalOptions.Debug) { 141 Debug.enable(); 142 if (GraalOptions.DebugReplacements) { 143 DebugEnvironment.initialize(log); 144 } 145 } 146 147 // Install intrinsics. 148 final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class); 149 final Replacements replacements = graalRuntime.getCapability(Replacements.class); 150 if (GraalOptions.Intrinsify) { 151 Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() { 152 153 @Override 154 public void run() { 155 ServiceLoader<ReplacementsProvider> serviceLoader = ServiceLoader.loadInstalled(ReplacementsProvider.class); 156 for (ReplacementsProvider provider : serviceLoader) { 157 provider.registerReplacements(replacements); 158 } 159 runtime.registerReplacements(replacements); 160 if (GraalOptions.BootstrapReplacements) { 161 for (ResolvedJavaMethod method : replacements.getAllReplacements()) { 162 replacements.getMacroSubstitution(method); 163 replacements.getMethodSubstitution(method); 164 replacements.getSnippet(method); 165 } 166 } 167 } 168 }); 169 170 } 171 172 if (GraalOptions.DebugReplacements) { 173 phaseTransition("replacements"); 174 } 175 176 // Create compilation queue. 177 BlockingQueue<Runnable> queue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue<Runnable>() : new LinkedBlockingQueue<Runnable>(); 178 compileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, queue, CompilerThread.FACTORY); 179 180 if (GraalOptions.SlowCompileThreads) { 181 BlockingQueue<Runnable> slowQueue = GraalOptions.PriorityCompileQueue ? new PriorityBlockingQueue<Runnable>() : new LinkedBlockingQueue<Runnable>(); 182 slowCompileQueue = new ThreadPoolExecutor(GraalOptions.Threads, GraalOptions.Threads, 0L, TimeUnit.MILLISECONDS, slowQueue, CompilerThread.LOW_PRIORITY_FACTORY); 183 } 184 185 // Create queue status printing thread. 186 if (GraalOptions.PrintQueue) { 187 Thread t = new Thread() { 188 189 @Override 190 public void run() { 191 while (true) { 192 if (slowCompileQueue == null) { 193 TTY.println(compileQueue.toString()); 194 } else { 195 TTY.println("fast: " + compileQueue.toString() + " slow: " + slowCompileQueue); 196 } 197 try { 198 Thread.sleep(1000); 199 } catch (InterruptedException e) { 200 } 201 } 202 } 203 }; 204 t.setDaemon(true); 205 t.start(); 206 } 207 208 if (GraalOptions.BenchmarkDynamicCounters) { 209 System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, " starting =====", " PASSED in ", "\n"))); 210 System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, "Iteration ~ (~s) begins: ", "Iteration ~ (~s) ends: ", "\n"))); 211 DynamicCounterNode.excludedClassPrefix = "Lcom/oracle/graal/"; 212 DynamicCounterNode.enabled = true; 213 } 214 if (GraalOptions.GenericDynamicCounters) { 215 DynamicCounterNode.enabled = true; 216 } 217 compilerStartTime = System.nanoTime(); 218 } 219 220 private final class BenchmarkCountersOutputStream extends CallbackOutputStream { 221 222 private long startTime; 223 private boolean waitingForEnd; 224 225 private BenchmarkCountersOutputStream(PrintStream delegate, String... patterns) { 226 super(delegate, patterns); 227 } 228 229 @Override 230 protected void patternFound(int index) { 231 switch (index) { 232 case 0: 233 startTime = System.nanoTime(); 234 DynamicCounterNode.clear(); 235 break; 236 case 1: 237 waitingForEnd = true; 238 break; 239 case 2: 240 if (waitingForEnd) { 241 waitingForEnd = false; 242 DynamicCounterNode.dump(delegate, (System.nanoTime() - startTime) / 1000000000d); 243 } 244 break; 245 } 246 } 247 } 248 249 public abstract static class CallbackOutputStream extends OutputStream { 250 251 protected final PrintStream delegate; 252 private final byte[][] patterns; 253 private final int[] positions; 254 255 public CallbackOutputStream(PrintStream delegate, String... patterns) { 256 this.delegate = delegate; 257 this.positions = new int[patterns.length]; 258 this.patterns = new byte[patterns.length][]; 259 for (int i = 0; i < patterns.length; i++) { 260 this.patterns[i] = patterns[i].getBytes(); 261 } 262 } 263 264 protected abstract void patternFound(int index); 265 266 @Override 267 public void write(int b) throws IOException { 268 try { 269 delegate.write(b); 270 for (int i = 0; i < patterns.length; i++) { 271 int j = positions[i]; 272 byte[] cs = patterns[i]; 273 byte patternChar = cs[j]; 274 if (patternChar == '~' && Character.isDigit(b)) { 275 // nothing to do... 276 } else { 277 if (patternChar == '~') { 278 patternChar = cs[++positions[i]]; 279 } 280 if (b == patternChar) { 281 positions[i]++; 282 } else { 283 positions[i] = 0; 284 } 285 } 286 if (positions[i] == patterns[i].length) { 287 positions[i] = 0; 288 patternFound(i); 289 } 290 } 291 } catch (RuntimeException e) { 292 e.printStackTrace(delegate); 293 throw e; 294 } 295 } 296 } 297 298 /** 299 * Take action related to entering a new execution phase. 300 * 301 * @param phase the execution phase being entered 302 */ 303 protected void phaseTransition(String phase) { 304 CompilationStatistics.clear(phase); 305 if (graalRuntime.getConfig().ciTime) { 306 parsedBytecodesPerSecond = MetricRateInPhase.snapshot(phase, parsedBytecodesPerSecond, BytecodesParsed, CompilationTime, TimeUnit.SECONDS); 307 inlinedBytecodesPerSecond = MetricRateInPhase.snapshot(phase, inlinedBytecodesPerSecond, InlinedBytecodes, CompilationTime, TimeUnit.SECONDS); 308 } 309 } 310 311 /** 312 * This method is the first method compiled during bootstrapping. Put any code in there that 313 * warms up compiler paths that are otherwise not exercised during bootstrapping and lead to 314 * later deoptimization when application code is compiled. 315 */ 316 @SuppressWarnings("unused") 317 @Deprecated 318 private synchronized void compileWarmup() { 319 // Method is synchronized to exercise the synchronization code in the compiler. 320 } 321 322 public void bootstrap() throws Throwable { 323 TTY.print("Bootstrapping Graal"); 324 TTY.flush(); 325 long startTime = System.currentTimeMillis(); 326 327 bootstrapRunning = true; 328 boolean firstRun = true; 329 do { 330 // Initialize compile queue with a selected set of methods. 331 Class<Object> objectKlass = Object.class; 332 if (firstRun) { 333 enqueue(getClass().getDeclaredMethod("compileWarmup")); 334 enqueue(objectKlass.getDeclaredMethod("equals", Object.class)); 335 enqueue(objectKlass.getDeclaredMethod("toString")); 336 firstRun = false; 337 } else { 338 for (int i = 0; i < 100; i++) { 339 enqueue(getClass().getDeclaredMethod("bootstrap")); 340 } 341 } 342 343 // Compile until the queue is empty. 344 int z = 0; 345 while (true) { 346 try { 347 assert !CompilationTask.withinEnqueue.get(); 348 CompilationTask.withinEnqueue.set(Boolean.TRUE); 349 if (slowCompileQueue == null) { 350 if (compileQueue.getCompletedTaskCount() >= Math.max(3, compileQueue.getTaskCount())) { 351 break; 352 } 353 } else { 354 if (compileQueue.getCompletedTaskCount() + slowCompileQueue.getCompletedTaskCount() >= Math.max(3, compileQueue.getTaskCount() + slowCompileQueue.getTaskCount())) { 355 break; 356 } 357 } 358 } finally { 359 CompilationTask.withinEnqueue.set(Boolean.FALSE); 360 } 361 362 Thread.sleep(100); 363 while (z < compileQueue.getCompletedTaskCount() / 100) { 364 ++z; 365 TTY.print("."); 366 TTY.flush(); 367 } 368 } 369 } while ((System.currentTimeMillis() - startTime) <= GraalOptions.TimedBootstrap); 370 371 phaseTransition("bootstrap"); 372 373 bootstrapRunning = false; 374 375 TTY.println(" in %d ms", System.currentTimeMillis() - startTime); 376 if (graalRuntime.getCache() != null) { 377 graalRuntime.getCache().clear(); 378 } 379 System.gc(); 380 phaseTransition("bootstrap2"); 381 382 } 383 384 private MetricRateInPhase parsedBytecodesPerSecond; 385 private MetricRateInPhase inlinedBytecodesPerSecond; 386 387 private void enqueue(Method m) throws Throwable { 388 JavaMethod javaMethod = graalRuntime.getRuntime().lookupJavaMethod(m); 389 assert !Modifier.isAbstract(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) && !Modifier.isNative(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) : javaMethod; 390 compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, false, 10); 391 } 392 393 private static void shutdownCompileQueue(ThreadPoolExecutor queue) throws InterruptedException { 394 if (queue != null) { 395 queue.shutdown(); 396 if (Debug.isEnabled() && GraalOptions.Dump != null) { 397 // Wait 2 seconds to flush out all graph dumps that may be of interest 398 queue.awaitTermination(2, TimeUnit.SECONDS); 399 } 400 } 401 } 402 403 public void shutdownCompiler() throws Throwable { 404 try { 405 assert !CompilationTask.withinEnqueue.get(); 406 CompilationTask.withinEnqueue.set(Boolean.TRUE); 407 shutdownCompileQueue(compileQueue); 408 shutdownCompileQueue(slowCompileQueue); 409 } finally { 410 CompilationTask.withinEnqueue.set(Boolean.FALSE); 411 } 412 413 if (Debug.isEnabled() && !quietMeterAndTime) { 414 List<DebugValueMap> topLevelMaps = DebugValueMap.getTopLevelMaps(); 415 List<DebugValue> debugValues = KeyRegistry.getDebugValues(); 416 if (debugValues.size() > 0) { 417 ArrayList<DebugValue> sortedValues = new ArrayList<>(debugValues); 418 Collections.sort(sortedValues); 419 420 if (GraalOptions.SummarizeDebugValues) { 421 printSummary(topLevelMaps, sortedValues); 422 } else if (GraalOptions.PerThreadDebugValues) { 423 for (DebugValueMap map : topLevelMaps) { 424 TTY.println("Showing the results for thread: " + map.getName()); 425 map.group(); 426 map.normalize(); 427 printMap(map, sortedValues, 0); 428 } 429 } else { 430 DebugValueMap globalMap = new DebugValueMap("Global"); 431 for (DebugValueMap map : topLevelMaps) { 432 if (GraalOptions.SummarizePerPhase) { 433 flattenChildren(map, globalMap); 434 } else { 435 globalMap.addChild(map); 436 } 437 } 438 if (!GraalOptions.SummarizePerPhase) { 439 globalMap.group(); 440 } 441 globalMap.normalize(); 442 printMap(globalMap, sortedValues, 0); 443 } 444 } 445 } 446 phaseTransition("final"); 447 448 if (graalRuntime.getConfig().ciTime) { 449 parsedBytecodesPerSecond.printAll("ParsedBytecodesPerSecond", System.out); 450 inlinedBytecodesPerSecond.printAll("InlinedBytecodesPerSecond", System.out); 451 } 452 453 SnippetCounter.printGroups(TTY.out().out()); 454 if (GraalOptions.GenericDynamicCounters) { 455 DynamicCounterNode.dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d); 456 } 457 } 458 459 private void flattenChildren(DebugValueMap map, DebugValueMap globalMap) { 460 globalMap.addChild(map); 461 for (DebugValueMap child : map.getChildren()) { 462 flattenChildren(child, globalMap); 463 } 464 map.clearChildren(); 465 } 466 467 private static void printSummary(List<DebugValueMap> topLevelMaps, List<DebugValue> debugValues) { 468 DebugValueMap result = new DebugValueMap("Summary"); 469 for (int i = debugValues.size() - 1; i >= 0; i--) { 470 DebugValue debugValue = debugValues.get(i); 471 int index = debugValue.getIndex(); 472 long total = collectTotal(topLevelMaps, index); 473 result.setCurrentValue(index, total); 474 } 475 printMap(result, debugValues, 0); 476 } 477 478 static long collectTotal(DebugValue value) { 479 List<DebugValueMap> maps = DebugValueMap.getTopLevelMaps(); 480 long total = 0; 481 for (int i = 0; i < maps.size(); i++) { 482 DebugValueMap map = maps.get(i); 483 int index = value.getIndex(); 484 total += map.getCurrentValue(index); 485 total += collectTotal(map.getChildren(), index); 486 } 487 return total; 488 } 489 490 private static long collectTotal(List<DebugValueMap> maps, int index) { 491 long total = 0; 492 for (int i = 0; i < maps.size(); i++) { 493 DebugValueMap map = maps.get(i); 494 total += map.getCurrentValue(index); 495 total += collectTotal(map.getChildren(), index); 496 } 497 return total; 498 } 499 500 private static void printMap(DebugValueMap map, List<DebugValue> debugValues, int level) { 501 502 printIndent(level); 503 TTY.println("%s", map.getName()); 504 505 for (DebugValue value : debugValues) { 506 long l = map.getCurrentValue(value.getIndex()); 507 if (l != 0) { 508 printIndent(level + 1); 509 TTY.println(value.getName() + "=" + value.toString(l)); 510 } 511 } 512 513 for (DebugValueMap child : map.getChildren()) { 514 printMap(child, debugValues, level + 1); 515 } 516 } 517 518 private static void printIndent(int level) { 519 for (int i = 0; i < level; ++i) { 520 TTY.print(" "); 521 } 522 TTY.print("|-> "); 523 } 524 525 @Override 526 public boolean compileMethod(long metaspaceMethod, final HotSpotResolvedObjectType holder, final int entryBCI, boolean blocking, int priority) throws Throwable { 527 HotSpotResolvedJavaMethod method = holder.createMethod(metaspaceMethod); 528 return compileMethod(method, entryBCI, blocking, priority); 529 } 530 531 /** 532 * Compiles a method to machine code. 533 * 534 * @return true if the method is in the queue (either added to the queue or already in the 535 * queue) 536 */ 537 public boolean compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, boolean blocking, int priority) throws Throwable { 538 CompilationTask current = method.currentTask(); 539 boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; 540 if (osrCompilation && bootstrapRunning) { 541 // no OSR compilations during bootstrap - the compiler is just too slow at this point, 542 // and we know that there are no endless loops 543 return current != null && (current.isInProgress() || !current.isCancelled()); 544 } 545 546 if (CompilationTask.withinEnqueue.get()) { 547 // This is required to avoid deadlocking a compiler thread. The issue is that a 548 // java.util.concurrent.BlockingQueue is used to implement the compilation worker 549 // queues. If a compiler thread triggers a compilation, then it may be blocked trying 550 // to add something to its own queue. 551 return current != null && (current.isInProgress() || !current.isCancelled()); 552 } 553 CompilationTask.withinEnqueue.set(Boolean.TRUE); 554 555 try { 556 if (!blocking && current != null) { 557 if (current.isInProgress()) { 558 if (current.getEntryBCI() == entryBCI) { 559 // a compilation with the correct bci is already in progress, so just return 560 // true 561 return true; 562 } 563 } else { 564 if (GraalOptions.PriorityCompileQueue) { 565 // normally compilation tasks will only be re-queued when they get a 566 // priority boost, so cancel the old task and add a new one 567 current.cancel(); 568 } else if (!current.isCancelled()) { 569 // without a prioritizing compile queue it makes no sense to re-queue the 570 // compilation task 571 return true; 572 } 573 } 574 } 575 576 final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method); 577 int id = compileTaskIds.incrementAndGet(); 578 // OSR compilations need to be finished quickly, so they get max priority 579 int queuePriority = osrCompilation ? -1 : priority; 580 CompilationTask task = CompilationTask.create(graalRuntime, createPhasePlan(optimisticOpts, osrCompilation), optimisticOpts, method, entryBCI, id, queuePriority); 581 if (blocking) { 582 task.runCompilation(); 583 return false; 584 } else { 585 try { 586 method.setCurrentTask(task); 587 if (GraalOptions.SlowCompileThreads && priority > GraalOptions.SlowQueueCutoff) { 588 slowCompileQueue.execute(task); 589 } else { 590 compileQueue.execute(task); 591 } 592 return true; 593 } catch (RejectedExecutionException e) { 594 // The compile queue was already shut down. 595 return false; 596 } 597 } 598 } finally { 599 CompilationTask.withinEnqueue.set(Boolean.FALSE); 600 } 601 } 602 603 @Override 604 public JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder) { 605 return new HotSpotMethodUnresolved(name, signature, holder); 606 } 607 608 @Override 609 public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal) { 610 if (offset != -1) { 611 HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) holder; 612 return resolved.createField(name, type, offset, flags, internal); 613 } 614 return new HotSpotUnresolvedField(holder, name, type); 615 } 616 617 @Override 618 public ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod) { 619 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) holder; 620 return type.createMethod(metaspaceMethod); 621 } 622 623 @Override 624 public ResolvedJavaType createPrimitiveJavaType(int basicType) { 625 switch (basicType) { 626 case 4: 627 return typeBoolean; 628 case 5: 629 return typeChar; 630 case 6: 631 return typeFloat; 632 case 7: 633 return typeDouble; 634 case 8: 635 return typeByte; 636 case 9: 637 return typeShort; 638 case 10: 639 return typeInt; 640 case 11: 641 return typeLong; 642 case 14: 643 return typeVoid; 644 default: 645 throw new IllegalArgumentException("Unknown basic type: " + basicType); 646 } 647 } 648 649 @Override 650 public HotSpotUnresolvedJavaType createUnresolvedJavaType(String name) { 651 int dims = 0; 652 int startIndex = 0; 653 while (name.charAt(startIndex) == '[') { 654 startIndex++; 655 dims++; 656 } 657 658 // Decode name if necessary. 659 if (name.charAt(name.length() - 1) == ';') { 660 assert name.charAt(startIndex) == 'L'; 661 return new HotSpotUnresolvedJavaType(name, name.substring(startIndex + 1, name.length() - 1), dims); 662 } else { 663 return new HotSpotUnresolvedJavaType(HotSpotUnresolvedJavaType.getFullName(name, dims), name, dims); 664 } 665 } 666 667 @Override 668 public HotSpotResolvedObjectType createResolvedJavaType(long metaspaceKlass, String name, String simpleName, Class javaMirror, boolean hasFinalizableSubclass, int sizeOrSpecies) { 669 HotSpotResolvedObjectType type = new HotSpotResolvedObjectType(metaspaceKlass, name, simpleName, javaMirror, hasFinalizableSubclass, sizeOrSpecies); 670 671 long offset = HotSpotGraalRuntime.getInstance().getConfig().graalMirrorInClassOffset; 672 if (!unsafe.compareAndSwapObject(javaMirror, offset, null, type)) { 673 // lost the race - return the existing value instead 674 type = (HotSpotResolvedObjectType) unsafe.getObject(javaMirror, offset); 675 } 676 return type; 677 } 678 679 @Override 680 public Constant createConstant(Kind kind, long value) { 681 if (kind == Kind.Long) { 682 return Constant.forLong(value); 683 } else if (kind == Kind.Int) { 684 return Constant.forInt((int) value); 685 } else if (kind == Kind.Short) { 686 return Constant.forShort((short) value); 687 } else if (kind == Kind.Char) { 688 return Constant.forChar((char) value); 689 } else if (kind == Kind.Byte) { 690 return Constant.forByte((byte) value); 691 } else if (kind == Kind.Boolean) { 692 return (value == 0) ? Constant.FALSE : Constant.TRUE; 693 } else { 694 throw new IllegalArgumentException(); 695 } 696 } 697 698 @Override 699 public Constant createConstantFloat(float value) { 700 return Constant.forFloat(value); 701 } 702 703 @Override 704 public Constant createConstantDouble(double value) { 705 return Constant.forDouble(value); 706 } 707 708 @Override 709 public Constant createConstantObject(Object object) { 710 return Constant.forObject(object); 711 } 712 713 @Override 714 public LocalImpl createLocalImpl(String name, String type, HotSpotResolvedObjectType holder, int bciStart, int bciEnd, int slot) { 715 return new LocalImpl(name, type, holder, bciStart, bciEnd, slot); 716 } 717 718 public PhasePlan createPhasePlan(OptimisticOptimizations optimisticOpts, boolean onStackReplacement) { 719 PhasePlan phasePlan = new PhasePlan(); 720 phasePlan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(graalRuntime.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts)); 721 if (onStackReplacement) { 722 phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase()); 723 } 724 phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase()); 725 return phasePlan; 726 } 727 728 @Override 729 public PrintStream log() { 730 return log; 731 } 732 }