changeset 22625:545590b1ab83

expanded CodeCacheProvider so that it supports all forms of code installation and made CompilerToVM.installCode package-private
author Doug Simon <doug.simon@oracle.com>
date Tue, 29 Sep 2015 14:43:37 +0200
parents cbf58dcb03d3
children b6b46b741102
files jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CodeCacheProvider.java jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CompilationRequest.java jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CompilationResult.java jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/package-info.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVM.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCodeCacheProvider.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompilationRequest.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledCode.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledNmethod.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotNmethod.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotRuntimeStub.java
diffstat 11 files changed, 209 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CodeCacheProvider.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CodeCacheProvider.java	Tue Sep 29 14:43:37 2015 +0200
@@ -37,26 +37,55 @@
 public interface CodeCacheProvider {
 
     /**
-     * Adds the given compilation result as an implementation of the given method without making it
-     * the default implementation.
+     * Installs code for a given method based on a given compilation result without making it the
+     * default implementation of the method.
      *
-     * @param method a method to which the executable code is begin added
+     * @param method a method implemented by the installed code
      * @param compResult the compilation result to be added
-     * @param speculationLog the speculation log to be used
-     * @return a reference to the compiled and ready-to-run code or throws a
-     *         {@link BailoutException} if the code installation failed
+     * @param log the speculation log to be used
+     * @param installedCode a predefined {@link InstalledCode} object to use as a reference to the
+     *            installed code. If {@code null}, a new {@link InstalledCode} object will be
+     *            created.
+     * @return a reference to the ready-to-run code
+     * @throws BailoutException if the code installation failed
      */
-    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode);
+    default InstalledCode addCode(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode installedCode) {
+        return installCode(new CompilationRequest(method), compResult, installedCode, log, false);
+    }
 
     /**
-     * Sets the given compilation result as the default implementation of the given method.
+     * Installs code for a given method based on a given compilation result and makes it the default
+     * implementation of the method.
      *
-     * @param method a method to which the executable code is begin added
+     * @param method a method implemented by the installed code and for which the installed code
+     *            becomes the default implementation
      * @param compResult the compilation result to be added
-     * @return a reference to the compiled and ready-to-run code or null if the code installation
-     *         failed
+     * @return a reference to the ready-to-run code
+     * @throws BailoutException if the code installation failed
      */
-    InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult);
+    default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompilationResult compResult) {
+        return installCode(new CompilationRequest(method), compResult, null, null, true);
+    }
+
+    /**
+     * Installs code based on a given compilation result.
+     *
+     * @param compRequest details of the method compiled to produce {@code compResult} or
+     *            {@code null} if the input to {@code compResult} was not a
+     *            {@link ResolvedJavaMethod}
+     * @param compResult the compilation result to be added
+     * @param installedCode a pre-allocated {@link InstalledCode} object to use as a reference to
+     *            the installed code. If {@code null}, a new {@link InstalledCode} object will be
+     *            created.
+     * @param log the speculation log to be used
+     * @param isDefault specifies if the installed code should be made the default implementation of
+     *            {@code compRequest.getMethod()}. The default implementation for a method is the
+     *            code executed for standard calls to the method. This argument is ignored if
+     *            {@code compRequest == null}.
+     * @return a reference to the compiled and ready-to-run installed code
+     * @throws BailoutException if the code installation failed
+     */
+    InstalledCode installCode(CompilationRequest compRequest, CompilationResult compResult, InstalledCode installedCode, SpeculationLog log, boolean isDefault);
 
     /**
      * Gets a name for a {@link Mark} mark.
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CompilationRequest.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CompilationRequest.java	Tue Sep 29 14:43:37 2015 +0200
@@ -34,12 +34,23 @@
     private final int entryBCI;
 
     /**
-     * Creates a compilation request.
+     * Creates a request to compile a method starting at its entry point.
      *
      * @param method the method to be compiled
-     * @param entryBCI the bytecode index (BCI) at which to start compiling
+     */
+    public CompilationRequest(ResolvedJavaMethod method) {
+        this(method, -1);
+    }
+
+    /**
+     * Creates a request to compile a method starting at a given BCI.
+     *
+     * @param method the method to be compiled
+     * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
+     *            method's entry point
      */
     public CompilationRequest(ResolvedJavaMethod method, int entryBCI) {
+        assert method != null;
         this.method = method;
         this.entryBCI = entryBCI;
     }
@@ -54,9 +65,14 @@
     /**
      * Gets the bytecode index (BCI) at which to start compiling where -1 denotes a non-OSR
      * compilation request and all other values denote an on stack replacement (OSR) compilation
-     * request
+     * request.
      */
     public int getEntryBCI() {
         return entryBCI;
     }
+
+    @Override
+    public String toString() {
+        return method.format("%H.%n(%p)@" + entryBCI);
+    }
 }
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CompilationResult.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/CompilationResult.java	Tue Sep 29 14:43:37 2015 +0200
@@ -489,7 +489,6 @@
         }
     }
 
-    private int id = -1;
     private int entryBCI = -1;
 
     private final DataSection dataSection = new DataSection();
@@ -560,7 +559,6 @@
             CompilationResult that = (CompilationResult) obj;
             // @formatter:off
             if (this.entryBCI == that.entryBCI &&
-                this.id == that.id &&
                 this.customStackAreaOffset == that.customStackAreaOffset &&
                 this.totalFrameSize == that.totalFrameSize &&
                 this.targetCodeSize == that.targetCodeSize &&
@@ -581,20 +579,6 @@
     }
 
     /**
-     * @return the compile id
-     */
-    public int getId() {
-        return id;
-    }
-
-    /**
-     * @param id the compile id to set
-     */
-    public void setId(int id) {
-        this.id = id;
-    }
-
-    /**
      * @return the entryBCI
      */
     public int getEntryBCI() {
--- a/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/package-info.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.code/src/jdk/internal/jvmci/code/package-info.java	Tue Sep 29 14:43:37 2015 +0200
@@ -23,8 +23,8 @@
 /**
  * Package that defines the interface between a Java application that wants to install code and the runtime.
  * The runtime provides in implementation of the {@link jdk.internal.jvmci.code.CodeCacheProvider} interface.
- * The method {@link jdk.internal.jvmci.code.CodeCacheProvider#addMethod(jdk.internal.jvmci.meta.ResolvedJavaMethod, CompilationResult, jdk.internal.jvmci.meta.SpeculationLog, InstalledCode)}
- * can be used to install code for a given method.
+ * The method {@link jdk.internal.jvmci.code.CodeCacheProvider#addCode(jdk.internal.jvmci.meta.ResolvedJavaMethod, CompilationResult, jdk.internal.jvmci.meta.SpeculationLog, InstalledCode)}
+ * can be used to install code.
  */
 package jdk.internal.jvmci.code;
 
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVM.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVM.java	Tue Sep 29 14:43:37 2015 +0200
@@ -315,7 +315,7 @@
      *         {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
      *         {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
      */
-    public int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog) {
+    int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog) {
         return installCodeImpl(target, compiledCode, code, speculationLog);
     }
 
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCodeCacheProvider.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCodeCacheProvider.java	Tue Sep 29 14:43:37 2015 +0200
@@ -28,6 +28,7 @@
 
 import jdk.internal.jvmci.code.BailoutException;
 import jdk.internal.jvmci.code.CodeCacheProvider;
+import jdk.internal.jvmci.code.CompilationRequest;
 import jdk.internal.jvmci.code.CompilationResult;
 import jdk.internal.jvmci.code.CompilationResult.Call;
 import jdk.internal.jvmci.code.CompilationResult.ConstantReference;
@@ -42,7 +43,6 @@
 import jdk.internal.jvmci.common.JVMCIError;
 import jdk.internal.jvmci.meta.Constant;
 import jdk.internal.jvmci.meta.JavaConstant;
-import jdk.internal.jvmci.meta.ResolvedJavaMethod;
 import jdk.internal.jvmci.meta.SerializableConstant;
 import jdk.internal.jvmci.meta.SpeculationLog;
 import jdk.internal.jvmci.meta.VMConstant;
@@ -113,57 +113,60 @@
         return runtime.getConfig().runtimeCallStackSize;
     }
 
-    public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) {
+    private InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) {
         ((HotSpotJVMCIRuntime) runtime).notifyInstall(this, installedCode, compResult);
         return installedCode;
     }
 
-    private InstalledCode installCode(CompilationResult compResult, HotSpotCompiledNmethod compiledCode, InstalledCode installedCode, SpeculationLog log) {
-        int result = runtime.getCompilerToVM().installCode(target, compiledCode, installedCode, log);
-        if (result != config.codeInstallResultOk) {
-            String msg = compiledCode.getInstallationFailureMessage();
-            String resultDesc = config.getCodeInstallResultDescription(result);
-            if (msg != null) {
-                msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
+    public InstalledCode installCode(CompilationRequest compRequest, CompilationResult compResult, InstalledCode installedCode, SpeculationLog log, boolean isDefault) {
+        HotSpotResolvedJavaMethod method = compRequest != null ? (HotSpotResolvedJavaMethod) compRequest.getMethod() : null;
+        InstalledCode resultInstalledCode;
+        if (installedCode == null) {
+            if (method == null) {
+                // Must be a stub
+                resultInstalledCode = new HotSpotRuntimeStub(compResult.getName());
             } else {
-                msg = String.format("Code installation failed: %s", resultDesc);
+                resultInstalledCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
             }
-            if (result == config.codeInstallResultDependenciesInvalid) {
-                throw new AssertionError(resultDesc + " " + msg);
-            }
-            throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg);
-        }
-        return logOrDump(installedCode, compResult);
-    }
-
-    public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv, boolean isDefault) {
-        if (compResult.getId() == -1) {
-            compResult.setId(method.allocateCompileId(compResult.getEntryBCI()));
+        } else {
+            resultInstalledCode = installedCode;
         }
-        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
-        HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(method, compResult, jvmciEnv);
-        return installCode(compResult, compiledCode, installedCode, method.getSpeculationLog());
-    }
-
-    @Override
-    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode predefinedInstalledCode) {
-        HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
-        if (compResult.getId() == -1) {
-            compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI()));
+        HotSpotCompiledCode compiledCode;
+        if (method != null) {
+            final int id;
+            final long jvmciEnv;
+            if (compRequest instanceof HotSpotCompilationRequest) {
+                HotSpotCompilationRequest hsCompRequest = (HotSpotCompilationRequest) compRequest;
+                id = hsCompRequest.getId();
+                jvmciEnv = hsCompRequest.getJvmciEnv();
+            } else {
+                id = method.allocateCompileId(compRequest.getEntryBCI());
+                jvmciEnv = 0L;
+            }
+            compiledCode = new HotSpotCompiledNmethod(method, compResult, id, jvmciEnv);
+        } else {
+            compiledCode = new HotSpotCompiledCode(compResult);
         }
-        InstalledCode installedCode = predefinedInstalledCode;
-        if (installedCode == null) {
-            HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false);
-            installedCode = code;
+        int result = runtime.getCompilerToVM().installCode(target, compiledCode, resultInstalledCode, log);
+        if (result != config.codeInstallResultOk) {
+            String resultDesc = config.getCodeInstallResultDescription(result);
+            if (compiledCode instanceof HotSpotCompiledNmethod) {
+                HotSpotCompiledNmethod compiledNmethod = (HotSpotCompiledNmethod) compiledCode;
+                String msg = compiledNmethod.getInstallationFailureMessage();
+                if (msg != null) {
+                    msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
+                } else {
+                    msg = String.format("Code installation failed: %s", resultDesc);
+                }
+                if (result == config.codeInstallResultDependenciesInvalid) {
+                    throw new AssertionError(resultDesc + " " + msg);
+                }
+                throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg);
+            } else {
+                throw new BailoutException("Error installing %s: %s", compResult.getName(), resultDesc);
+            }
         }
-        HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(hotspotMethod, compResult);
-        return installCode(compResult, compiledCode, installedCode, log);
-    }
-
-    @Override
-    public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) {
-        HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
-        return installMethod(hotspotMethod, compResult, 0L, true);
+        return logOrDump(resultInstalledCode, compResult);
     }
 
     public boolean needsDataPatch(JavaConstant constant) {
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompilationRequest.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompilationRequest.java	Tue Sep 29 14:43:37 2015 +0200
@@ -26,13 +26,34 @@
 
 /**
  * A compilation request with extra HotSpot specific context such as a compilation identifier and
- * the address of a {@code JVMCIEnv} object that provides extra native level context for a
- * compilation.
+ * the address of a {@code JVMCIEnv} object that provides native context for a compilation.
  */
 public class HotSpotCompilationRequest extends CompilationRequest {
     private final long jvmciEnv;
     private final int id;
 
+    /**
+     * Creates a request to compile a method starting at a given BCI and allocates an identifier to
+     * the request.
+     *
+     * @param method the method to be compiled
+     * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
+     *            method's entry point
+     * @param jvmciEnv address of a native {@code JVMCIEnv} object or 0L
+     */
+    public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv) {
+        this(method, entryBCI, jvmciEnv, method.allocateCompileId(-1));
+    }
+
+    /**
+     * Creates a request to compile a method starting at a given BCI.
+     *
+     * @param method the method to be compiled
+     * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
+     *            method's entry point
+     * @param jvmciEnv address of a native {@code JVMCIEnv} object or 0L
+     * @param id an identifier for the request
+     */
     public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
         super(method, entryBCI);
         this.jvmciEnv = jvmciEnv;
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledCode.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledCode.java	Tue Sep 29 14:43:37 2015 +0200
@@ -48,7 +48,7 @@
  * A {@link CompilationResult} with additional HotSpot-specific information required for installing
  * the code in HotSpot's code cache.
  */
-public abstract class HotSpotCompiledCode {
+public class HotSpotCompiledCode {
 
     public final String name;
     public final Site[] sites;
@@ -176,4 +176,9 @@
         Arrays.sort(result, new SiteComparator());
         return result;
     }
+
+    @Override
+    public String toString() {
+        return name;
+    }
 }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledNmethod.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotCompiledNmethod.java	Tue Sep 29 14:43:37 2015 +0200
@@ -32,8 +32,17 @@
 
     public final HotSpotResolvedJavaMethod method;
     public final int entryBCI;
+
+    /**
+     * Compilation identifier.
+     */
     public final int id;
+
+    /**
+     * Address of a native {@code JVMCIEnv} object or 0L if no such object exists.
+     */
     public final long jvmciEnv;
+
     public final boolean hasUnsafeAccess;
 
     /**
@@ -42,15 +51,11 @@
      */
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage;
 
-    public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) {
-        this(method, compResult, 0L);
-    }
-
-    public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv) {
+    public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, int id, long jvmciEnv) {
         super(compResult);
         this.method = method;
         this.entryBCI = compResult.getEntryBCI();
-        this.id = compResult.getId();
+        this.id = id;
         this.jvmciEnv = jvmciEnv;
         this.hasUnsafeAccess = compResult.hasUnsafeAccess();
     }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotNmethod.java	Mon Sep 28 21:31:35 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotNmethod.java	Tue Sep 29 14:43:37 2015 +0200
@@ -47,27 +47,17 @@
     private final HotSpotResolvedJavaMethod method;
 
     private final boolean isDefault;
-    private final boolean isExternal;
 
     public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault) {
-        this(method, name, isDefault, false);
-    }
-
-    public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault, boolean isExternal) {
         super(name);
         this.method = method;
         this.isDefault = isDefault;
-        this.isExternal = isExternal;
     }
 
     public boolean isDefault() {
         return isDefault;
     }
 
-    public boolean isExternal() {
-        return isExternal;
-    }
-
     public ResolvedJavaMethod getMethod() {
         return method;
     }
@@ -107,7 +97,6 @@
     @Override
     public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
         assert checkArgs(args);
-        assert !isExternal();
         return compilerToVM().executeInstalledCode(args, this);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotRuntimeStub.java	Tue Sep 29 14:43:37 2015 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.jvmci.hotspot;
+
+import jdk.internal.jvmci.code.InstalledCode;
+import jdk.internal.jvmci.code.InvalidInstalledCodeException;
+import jdk.internal.jvmci.meta.ResolvedJavaMethod;
+
+/**
+ * Implementation of {@link InstalledCode} for code installed as a RuntimeStub.
+ */
+public class HotSpotRuntimeStub extends HotSpotInstalledCode {
+
+    public HotSpotRuntimeStub(String name) {
+        super(name);
+    }
+
+    public ResolvedJavaMethod getMethod() {
+        return null;
+    }
+
+    @Override
+    public boolean isValid() {
+        return true;
+    }
+
+    @Override
+    public void invalidate() {
+    }
+
+    @Override
+    public String toString() {
+        return String.format("InstalledRuntimeStub[stub=%s, codeBlob=0x%x]", name, getAddress());
+    }
+
+    @Override
+    public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
+        throw new InternalError("Cannot call stub " + name);
+    }
+}