Mercurial > hg > truffle
comparison graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java @ 13895:4731c1a0b1f3
consolidated GNFI code into graal.hotspot project and cleaned up the documentation and code
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 06 Feb 2014 18:44:14 +0100 |
parents | graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeFunctionInterface.java@43678ad7ae92 |
children | 3089e9a7cf44 |
comparison
equal
deleted
inserted
replaced
13894:4fa77c58ad8f | 13895:4731c1a0b1f3 |
---|---|
1 /* | |
2 * Copyright (c) 2014, 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 com.oracle.graal.hotspot.nfi; | |
24 | |
25 import static com.oracle.graal.api.code.CodeUtil.*; | |
26 import static com.oracle.graal.graph.UnsafeAccess.*; | |
27 import static com.oracle.graal.hotspot.nfi.NativeCallStubGraphBuilder.*; | |
28 | |
29 import com.oracle.graal.api.code.*; | |
30 import com.oracle.graal.api.code.CallingConvention.*; | |
31 import com.oracle.graal.api.meta.*; | |
32 import com.oracle.graal.api.meta.ProfilingInfo.*; | |
33 import com.oracle.graal.compiler.*; | |
34 import com.oracle.graal.compiler.target.*; | |
35 import com.oracle.graal.debug.*; | |
36 import com.oracle.graal.debug.Debug.*; | |
37 import com.oracle.graal.hotspot.*; | |
38 import com.oracle.graal.hotspot.meta.*; | |
39 import com.oracle.graal.lir.asm.*; | |
40 import com.oracle.graal.nodes.*; | |
41 import com.oracle.graal.phases.*; | |
42 import com.oracle.graal.phases.tiers.*; | |
43 | |
44 public class HotSpotNativeFunctionInterface implements NativeFunctionInterface { | |
45 | |
46 private final HotSpotProviders providers; | |
47 private final Backend backend; | |
48 private final HotSpotNativeLibraryHandle rtldDefault; | |
49 private final HotSpotNativeFunctionPointer libraryLoadFunctionPointer; | |
50 private final HotSpotNativeFunctionPointer functionLookupFunctionPointer; | |
51 private final RawNativeCallNodeFactory factory; | |
52 | |
53 private HotSpotNativeFunctionHandle libraryLookupFunctionHandle; | |
54 private HotSpotNativeFunctionHandle dllLookupFunctionHandle; | |
55 | |
56 public HotSpotNativeFunctionInterface(HotSpotProviders providers, RawNativeCallNodeFactory factory, Backend backend, long dlopen, long dlsym, long rtldDefault) { | |
57 this.rtldDefault = rtldDefault == HotSpotVMConfig.INVALID_RTLD_DEFAULT_HANDLE ? null : new HotSpotNativeLibraryHandle("RTLD_DEFAULT", rtldDefault); | |
58 this.providers = providers; | |
59 this.backend = backend; | |
60 this.factory = factory; | |
61 this.libraryLoadFunctionPointer = new HotSpotNativeFunctionPointer(dlopen, "os::dll_load"); | |
62 this.functionLookupFunctionPointer = new HotSpotNativeFunctionPointer(dlsym, "os::dll_lookup"); | |
63 } | |
64 | |
65 @Override | |
66 public HotSpotNativeLibraryHandle getLibraryHandle(String libPath) { | |
67 if (libraryLookupFunctionHandle == null) { | |
68 libraryLookupFunctionHandle = createHandle(libraryLoadFunctionPointer, long.class, long.class, long.class, int.class); | |
69 } | |
70 | |
71 int ebufLen = 1024; | |
72 // Allocating a single chunk for both the error message buffer and the | |
73 // file name simplifies deallocation below. | |
74 long buffer = unsafe.allocateMemory(ebufLen + libPath.length() + 1); | |
75 long ebuf = buffer; | |
76 long libPathCString = writeCString(libPath, buffer + ebufLen); | |
77 try { | |
78 long handle = (long) libraryLookupFunctionHandle.call(libPathCString, ebuf, ebufLen); | |
79 if (handle == 0) { | |
80 throw new UnsatisfiedLinkError(libPath); | |
81 } | |
82 return new HotSpotNativeLibraryHandle(libPath, handle); | |
83 } finally { | |
84 unsafe.freeMemory(buffer); | |
85 } | |
86 } | |
87 | |
88 @Override | |
89 public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes) { | |
90 HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(name, library, true); | |
91 return getFunctionHandle(functionPointer, returnType, argumentTypes); | |
92 } | |
93 | |
94 @Override | |
95 public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes) { | |
96 HotSpotNativeFunctionPointer functionPointer = null; | |
97 for (NativeLibraryHandle libraryHandle : libraries) { | |
98 functionPointer = lookupFunctionPointer(name, libraryHandle, false); | |
99 if (functionPointer != null) { | |
100 return createHandle(functionPointer, returnType, argumentTypes); | |
101 } | |
102 } | |
103 // Fall back to default library path | |
104 return getFunctionHandle(name, returnType, argumentTypes); | |
105 } | |
106 | |
107 @Override | |
108 public HotSpotNativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes) { | |
109 if (rtldDefault == null) { | |
110 throw new UnsatisfiedLinkError(name); | |
111 } | |
112 return getFunctionHandle(rtldDefault, name, returnType, argumentTypes); | |
113 } | |
114 | |
115 private HotSpotNativeFunctionPointer lookupFunctionPointer(String name, NativeLibraryHandle library, boolean linkageErrorIfMissing) { | |
116 if (name == null || library == null) { | |
117 throw new NullPointerException(); | |
118 } | |
119 if (dllLookupFunctionHandle == null) { | |
120 dllLookupFunctionHandle = createHandle(functionLookupFunctionPointer, long.class, long.class, long.class); | |
121 } | |
122 long nameCString = createCString(name); | |
123 try { | |
124 long functionPointer = (long) dllLookupFunctionHandle.call(((HotSpotNativeLibraryHandle) library).value, nameCString); | |
125 if (functionPointer == 0L) { | |
126 if (!linkageErrorIfMissing) { | |
127 return null; | |
128 } | |
129 throw new UnsatisfiedLinkError(name); | |
130 } | |
131 return new HotSpotNativeFunctionPointer(functionPointer, name); | |
132 } finally { | |
133 unsafe.freeMemory(nameCString); | |
134 } | |
135 } | |
136 | |
137 @Override | |
138 public HotSpotNativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) { | |
139 if (!(functionPointer instanceof HotSpotNativeFunctionPointer)) { | |
140 throw new UnsatisfiedLinkError(functionPointer.getName()); | |
141 } | |
142 return createHandle(functionPointer, returnType, argumentTypes); | |
143 } | |
144 | |
145 private HotSpotNativeFunctionHandle createHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) { | |
146 HotSpotNativeFunctionPointer hs = (HotSpotNativeFunctionPointer) functionPointer; | |
147 InstalledCode code = installNativeFunctionStub(hs.value, returnType, argumentTypes); | |
148 return new HotSpotNativeFunctionHandle(code, hs.name, argumentTypes); | |
149 } | |
150 | |
151 /** | |
152 * Creates and installs a stub for calling a native function. | |
153 */ | |
154 private InstalledCode installNativeFunctionStub(long functionPointer, Class returnType, Class... argumentTypes) { | |
155 StructuredGraph g = getGraph(providers, factory, functionPointer, returnType, argumentTypes); | |
156 Suites suites = providers.getSuites().createSuites(); | |
157 PhaseSuite<HighTierContext> phaseSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy(); | |
158 CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, g.method(), false); | |
159 CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), null, phaseSuite, OptimisticOptimizations.ALL, | |
160 DefaultProfilingInfo.get(TriState.UNKNOWN), null, suites, true, new CompilationResult(), CompilationResultBuilderFactory.Default); | |
161 InstalledCode installedCode; | |
162 try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) { | |
163 installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null); | |
164 } | |
165 return installedCode; | |
166 } | |
167 | |
168 @Override | |
169 public HotSpotNativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name) { | |
170 for (NativeLibraryHandle libraryHandle : libraries) { | |
171 HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(name, libraryHandle, false); | |
172 if (functionPointer != null) { | |
173 return functionPointer; | |
174 } | |
175 } | |
176 // Fall back to default library path | |
177 if (rtldDefault == null) { | |
178 throw new UnsatisfiedLinkError(name); | |
179 } | |
180 return lookupFunctionPointer(name, rtldDefault, true); | |
181 } | |
182 | |
183 @Override | |
184 public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) { | |
185 return new HotSpotNativeFunctionPointer(rawValue, null); | |
186 } | |
187 } |