001/* 002 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.hotspot; 024 025import static jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime.*; 026import jdk.internal.jvmci.code.*; 027import jdk.internal.jvmci.meta.*; 028 029/** 030 * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a 031 * weak reference to an instance of this class. This is necessary to keep the nmethod from being 032 * unloaded while the associated {@link HotSpotNmethod} instance is alive. 033 * <p> 034 * Note that there is no (current) way for the reference from an nmethod to a {@link HotSpotNmethod} 035 * instance to be anything but weak. This is due to the fact that HotSpot does not treat nmethods as 036 * strong GC roots. 037 */ 038public class HotSpotNmethod extends HotSpotInstalledCode { 039 040 /** 041 * This (indirect) Method* reference is safe since class redefinition preserves all methods 042 * associated with nmethods in the code cache. 043 */ 044 private final HotSpotResolvedJavaMethod method; 045 046 private final boolean isDefault; 047 private final boolean isExternal; 048 049 public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault) { 050 this(method, name, isDefault, false); 051 } 052 053 public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault, boolean isExternal) { 054 super(name); 055 this.method = method; 056 this.isDefault = isDefault; 057 this.isExternal = isExternal; 058 } 059 060 public boolean isDefault() { 061 return isDefault; 062 } 063 064 public boolean isExternal() { 065 return isExternal; 066 } 067 068 public ResolvedJavaMethod getMethod() { 069 return method; 070 } 071 072 @Override 073 public void invalidate() { 074 runtime().getCompilerToVM().invalidateInstalledCode(this); 075 } 076 077 @Override 078 public String toString() { 079 return String.format("InstalledNmethod[method=%s, codeBlob=0x%x, isDefault=%b, name=%s]", method, getAddress(), isDefault, name); 080 } 081 082 protected boolean checkThreeObjectArgs() { 083 assert method.getSignature().getParameterCount(!method.isStatic()) == 3; 084 assert method.getSignature().getParameterKind(0) == Kind.Object; 085 assert method.getSignature().getParameterKind(1) == Kind.Object; 086 assert !method.isStatic() || method.getSignature().getParameterKind(2) == Kind.Object; 087 return true; 088 } 089 090 private boolean checkArgs(Object... args) { 091 JavaType[] sig = method.toParameterTypes(); 092 assert args.length == sig.length : method.format("%H.%n(%p): expected ") + sig.length + " args, got " + args.length; 093 for (int i = 0; i < sig.length; i++) { 094 Object arg = args[i]; 095 if (arg == null) { 096 assert sig[i].getKind() == Kind.Object : method.format("%H.%n(%p): expected arg ") + i + " to be Object, not " + sig[i]; 097 } else if (sig[i].getKind() != Kind.Object) { 098 assert sig[i].getKind().toBoxedJavaClass() == arg.getClass() : method.format("%H.%n(%p): expected arg ") + i + " to be " + sig[i] + ", not " + arg.getClass(); 099 } 100 } 101 return true; 102 } 103 104 @Override 105 public Object executeVarargs(Object... args) throws InvalidInstalledCodeException { 106 assert checkArgs(args); 107 assert !isExternal(); 108 return runtime().getCompilerToVM().executeCompiledMethodVarargs(args, this); 109 } 110 111 @Override 112 public long getStart() { 113 return isValid() ? super.getStart() : 0; 114 } 115}