1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package libcore.util; 17 18 import com.android.ravenwood.common.RavenwoodRuntimeNative; 19 20 import java.lang.ref.Cleaner; 21 import java.lang.ref.Reference; 22 23 /** 24 * Re-implementation of ART's NativeAllocationRegistry for Ravenwood. 25 * - We don't track the native allocation size on Ravenwood. 26 * - sun.misc.Cleaner isn't available on the desktop JVM, so we use java.lang.ref.Cleaner. 27 * (Should ART switch to java.lang.ref.Cleaner?) 28 */ 29 public class NativeAllocationRegistry { 30 private final long mFreeFunction; 31 private static final Cleaner sCleaner = Cleaner.create(); 32 createNonmalloced( ClassLoader classLoader, long freeFunction, long size)33 public static NativeAllocationRegistry createNonmalloced( 34 ClassLoader classLoader, long freeFunction, long size) { 35 return new NativeAllocationRegistry(classLoader, freeFunction, size, false); 36 } 37 createMalloced( ClassLoader classLoader, long freeFunction, long size)38 public static NativeAllocationRegistry createMalloced( 39 ClassLoader classLoader, long freeFunction, long size) { 40 return new NativeAllocationRegistry(classLoader, freeFunction, size, true); 41 } 42 createMalloced( ClassLoader classLoader, long freeFunction)43 public static NativeAllocationRegistry createMalloced( 44 ClassLoader classLoader, long freeFunction) { 45 return new NativeAllocationRegistry(classLoader, freeFunction, 0, true); 46 } 47 NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size)48 public NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size) { 49 this(classLoader, freeFunction, size, size == 0); 50 } 51 NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size, boolean mallocAllocation)52 private NativeAllocationRegistry(ClassLoader classLoader, long freeFunction, long size, 53 boolean mallocAllocation) { 54 if (size < 0) { 55 throw new IllegalArgumentException("Invalid native allocation size: " + size); 56 } 57 mFreeFunction = freeFunction; 58 } 59 registerNativeAllocation(Object referent, long nativePtr)60 public Runnable registerNativeAllocation(Object referent, long nativePtr) { 61 if (referent == null) { 62 throw new IllegalArgumentException("referent is null"); 63 } 64 if (nativePtr == 0) { 65 throw new IllegalArgumentException("nativePtr is null"); 66 } 67 68 final Runnable releaser = () -> { 69 RavenwoodRuntimeNative.applyFreeFunction(mFreeFunction, nativePtr); 70 }; 71 sCleaner.register(referent, releaser); 72 73 // Ensure that cleaner doesn't get invoked before we enable it. 74 Reference.reachabilityFence(referent); 75 return releaser; 76 } 77 } 78