diff options
-rw-r--r-- | dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java | 1 | ||||
-rw-r--r-- | luni/src/main/java/libcore/util/NativeAllocationRegistry.java | 3 | ||||
-rw-r--r-- | luni/src/main/native/Android.bp | 2 | ||||
-rw-r--r-- | luni/src/main/native/JniConstants.cpp | 7 | ||||
-rw-r--r-- | luni/src/main/native/JniConstants.h | 1 | ||||
-rw-r--r-- | luni/src/main/native/Register.cpp | 2 | ||||
-rw-r--r-- | luni/src/main/native/java_util_regex_Matcher.cpp | 289 | ||||
-rw-r--r-- | luni/src/main/native/java_util_regex_Pattern.cpp | 106 | ||||
-rw-r--r-- | mmodules/intracoreapi/api/intra/current-api.txt | 12 | ||||
-rw-r--r-- | ojluni/src/main/java/java/util/regex/Matcher.java | 72 | ||||
-rw-r--r-- | ojluni/src/main/java/java/util/regex/Pattern.java | 17 |
11 files changed, 36 insertions, 476 deletions
diff --git a/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java b/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java index 4eea1a58e2..7b82c3cf9a 100644 --- a/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java +++ b/dalvik/src/main/java/dalvik/annotation/optimization/ReachabilitySensitive.java @@ -79,6 +79,7 @@ import java.lang.annotation.Target; * * @hide */ +@libcore.api.IntraCoreApi @Retention(RetentionPolicy.RUNTIME) // Let the GC or interpreter ask, if they need to. // TODO(b/72332040): Reconsider retention later. @Target({ElementType.FIELD, ElementType.METHOD}) diff --git a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java index 5dc1e98334..e114ebe35d 100644 --- a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java +++ b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java @@ -41,6 +41,7 @@ import java.lang.ref.Reference; * @hide */ @libcore.api.CorePlatformApi +@libcore.api.IntraCoreApi public class NativeAllocationRegistry { private final ClassLoader classLoader; @@ -118,6 +119,7 @@ public class NativeAllocationRegistry { * kind of native allocation */ @libcore.api.CorePlatformApi + @libcore.api.IntraCoreApi public static NativeAllocationRegistry createMalloced( ClassLoader classLoader, long freeFunction) { return new NativeAllocationRegistry(classLoader, freeFunction, 0, true); @@ -227,6 +229,7 @@ public class NativeAllocationRegistry { * thrown. */ @libcore.api.CorePlatformApi + @libcore.api.IntraCoreApi public Runnable registerNativeAllocation(Object referent, long nativePtr) { if (referent == null) { throw new IllegalArgumentException("referent is null"); diff --git a/luni/src/main/native/Android.bp b/luni/src/main/native/Android.bp index 85c6430a06..f94ff9563b 100644 --- a/luni/src/main/native/Android.bp +++ b/luni/src/main/native/Android.bp @@ -31,8 +31,6 @@ filegroup { "java_lang_invoke_MethodHandle.cpp", "java_lang_invoke_VarHandle.cpp", "java_math_NativeBN.cpp", - "java_util_regex_Matcher.cpp", - "java_util_regex_Pattern.cpp", "libcore_icu_ICU.cpp", "libcore_icu_NativeConverter.cpp", "libcore_icu_TimeZoneNames.cpp", diff --git a/luni/src/main/native/JniConstants.cpp b/luni/src/main/native/JniConstants.cpp index bf567aab41..a6b7b9e8d0 100644 --- a/luni/src/main/native/JniConstants.cpp +++ b/luni/src/main/native/JniConstants.cpp @@ -61,7 +61,6 @@ jclass localeDataClass; jclass longClass; jclass netlinkSocketAddressClass; jclass packetSocketAddressClass; -jclass patternSyntaxExceptionClass; jclass stringClass; jclass structAddrinfoClass; jclass structGroupReqClass; @@ -108,7 +107,6 @@ void EnsureJniConstantsInitialized(JNIEnv* env) { longClass = findClass(env, "java/lang/Long"); netlinkSocketAddressClass = findClass(env, "android/system/NetlinkSocketAddress"); packetSocketAddressClass = findClass(env, "android/system/PacketSocketAddress"); - patternSyntaxExceptionClass = findClass(env, "java/util/regex/PatternSyntaxException"); stringClass = findClass(env, "java/lang/String"); structAddrinfoClass = findClass(env, "android/system/StructAddrinfo"); structGroupReqClass = findClass(env, "android/system/StructGroupReq"); @@ -223,11 +221,6 @@ jclass JniConstants::GetPacketSocketAddressClass(JNIEnv* env) { return packetSocketAddressClass; } -jclass JniConstants::GetPatternSyntaxExceptionClass(JNIEnv* env) { - EnsureJniConstantsInitialized(env); - return patternSyntaxExceptionClass; -} - jclass JniConstants::GetStringClass(JNIEnv* env) { EnsureJniConstantsInitialized(env); return stringClass; diff --git a/luni/src/main/native/JniConstants.h b/luni/src/main/native/JniConstants.h index 021dc53455..2931411c79 100644 --- a/luni/src/main/native/JniConstants.h +++ b/luni/src/main/native/JniConstants.h @@ -46,7 +46,6 @@ struct JniConstants { static jclass GetLongClass(JNIEnv* env); static jclass GetNetlinkSocketAddressClass(JNIEnv* env); static jclass GetPacketSocketAddressClass(JNIEnv* env); - static jclass GetPatternSyntaxExceptionClass(JNIEnv* env); static jclass GetStringClass(JNIEnv* env); static jclass GetStructAddrinfoClass(JNIEnv* env); static jclass GetStructFlockClass(JNIEnv* env); diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp index 0b4a94a5a1..40e580e59c 100644 --- a/luni/src/main/native/Register.cpp +++ b/luni/src/main/native/Register.cpp @@ -40,8 +40,6 @@ jint JNI_OnLoad(JavaVM* vm, void*) { REGISTER(register_java_lang_invoke_MethodHandle); REGISTER(register_java_lang_invoke_VarHandle); REGISTER(register_java_math_NativeBN); - REGISTER(register_java_util_regex_Matcher); - REGISTER(register_java_util_regex_Pattern); REGISTER(register_libcore_icu_ICU); REGISTER(register_libcore_icu_NativeConverter); REGISTER(register_libcore_icu_TimeZoneNames); diff --git a/luni/src/main/native/java_util_regex_Matcher.cpp b/luni/src/main/native/java_util_regex_Matcher.cpp deleted file mode 100644 index 12fb764c6e..0000000000 --- a/luni/src/main/native/java_util_regex_Matcher.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "Matcher" - -#include <memory> -#include <stdlib.h> - -#include <android-base/logging.h> -#include <nativehelper/JNIHelp.h> -#include <nativehelper/ScopedPrimitiveArray.h> -#include <nativehelper/ScopedStringChars.h> -#include <nativehelper/jni_macros.h> - -#include "IcuUtilities.h" -#include "JniException.h" -#include "ScopedJavaUnicodeString.h" -#include "unicode/parseerr.h" -#include "unicode/regex.h" - -// ICU documentation: http://icu-project.org/apiref/icu4c/classRegexMatcher.html - -/** - * Encapsulates an instance of ICU4C's RegexMatcher class along with a copy of - * the input it's currently operating on in the native heap. - * - * Rationale: We choose to make a copy here because it turns out to be a lot - * cheaper when a moving GC and/or string compression is enabled. This is - * because env->GetStringChars() always copies in this scenario. This becomes - * especially bad when the String in question is long and/or contains a large - * number of matches. - * - * Drawbacks: The native allocation associated with this class is no longer - * fixed size, so we're effectively lying to the NativeAllocationRegistry about - * the size of the object(s) we're allocating on the native heap. The peak - * memory usage doesn't change though, given that GetStringChars would have - * made an allocation of precisely the same size. - */ -class MatcherState { -public: - MatcherState(icu::RegexMatcher* matcher) : - mMatcher(matcher), - mUChars(nullptr), - mUText(nullptr), - mStatus(U_ZERO_ERROR) { - } - - bool updateInput(JNIEnv* env, jstring input) { - // First, close the UText struct, since we're about to allocate a new one. - if (mUText != nullptr) { - utext_close(mUText); - mUText = nullptr; - } - - // Then delete the UChar* associated with the UText struct.. - mUChars.reset(nullptr); - - // TODO: We should investigate whether we can avoid an additional copy - // in the native heap when is_copy == JNI_TRUE. The problem with doing - // that is that we might call ReleaseStringChars with a different - // JNIEnv* on a different downcall. This is currently safe as - // implemented in ART, but is unlikely to be portable and the spec stays - // silent on the matter. - ScopedStringChars inputChars(env, input); - if (inputChars.get() == nullptr) { - // There will be an exception pending if we get here. - return false; - } - - // Make a copy of |input| on the native heap. This copy will be live - // until the next call to updateInput or close. - mUChars.reset(new (std::nothrow) UChar[inputChars.size()]); - if (mUChars.get() == nullptr) { - env->ThrowNew(env->FindClass("Ljava/lang/OutOfMemoryError;"), "Out of memory"); - return false; - } - - static_assert(sizeof(UChar) == sizeof(jchar), "sizeof(Uchar) != sizeof(jchar)"); - memcpy(mUChars.get(), inputChars.get(), inputChars.size() * sizeof(jchar)); - - // Reset any errors that might have occurred on previous patches. - mStatus = U_ZERO_ERROR; - mUText = utext_openUChars(nullptr, mUChars.get(), inputChars.size(), &mStatus); - if (mUText == nullptr) { - CHECK(maybeThrowIcuException(env, "utext_openUChars", mStatus)); - return false; - } - - // It is an error for ICU to have returned a non-null mUText but to - // still have indicated an error. - CHECK(U_SUCCESS(mStatus)); - - mMatcher->reset(mUText); - return true; - } - - ~MatcherState() { - if (mUText != nullptr) { - utext_close(mUText); - } - } - - icu::RegexMatcher* matcher() { - return mMatcher.get(); - } - - UErrorCode& status() { - return mStatus; - } - - void updateOffsets(JNIEnv* env, jintArray javaOffsets) { - ScopedIntArrayRW offsets(env, javaOffsets); - if (offsets.get() == NULL) { - return; - } - - for (size_t i = 0, groupCount = mMatcher->groupCount(); i <= groupCount; ++i) { - offsets[2*i + 0] = mMatcher->start(i, mStatus); - offsets[2*i + 1] = mMatcher->end(i, mStatus); - } - } - -private: - std::unique_ptr<icu::RegexMatcher> mMatcher; - std::unique_ptr<UChar[]> mUChars; - UText* mUText; - UErrorCode mStatus; - - // Disallow copy and assignment. - MatcherState(const MatcherState&); - void operator=(const MatcherState&); -}; - -static inline MatcherState* toMatcherState(jlong address) { - return reinterpret_cast<MatcherState*>(static_cast<uintptr_t>(address)); -} - -static void Matcher_free(void* address) { - MatcherState* state = reinterpret_cast<MatcherState*>(address); - delete state; -} - -static jlong Matcher_getNativeFinalizer(JNIEnv*, jclass) { - return reinterpret_cast<jlong>(&Matcher_free); -} - -static jboolean Matcher_findImpl(JNIEnv* env, jclass, jlong addr, jint startIndex, jintArray offsets) { - MatcherState* state = toMatcherState(addr); - UBool result = state->matcher()->find(startIndex, state->status()); - if (result) { - state->updateOffsets(env, offsets); - return JNI_TRUE; - } else { - return JNI_FALSE; - } -} - -static jboolean Matcher_findNextImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) { - MatcherState* state = toMatcherState(addr); - UBool result = state->matcher()->find(); - if (result) { - state->updateOffsets(env, offsets); - return JNI_TRUE; - } else { - return JNI_FALSE; - } -} - -static jint Matcher_groupCountImpl(JNIEnv*, jclass, jlong addr) { - MatcherState* state = toMatcherState(addr); - return state->matcher()->groupCount(); -} - -static jboolean Matcher_hitEndImpl(JNIEnv*, jclass, jlong addr) { - MatcherState* state = toMatcherState(addr); - if (state->matcher()->hitEnd() != 0) { - return JNI_TRUE; - } else { - return JNI_FALSE; - } -} - -static jboolean Matcher_lookingAtImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) { - MatcherState* state = toMatcherState(addr); - UBool result = state->matcher()->lookingAt(state->status()); - if (result) { - state->updateOffsets(env, offsets); - return JNI_TRUE; - } else { - return JNI_FALSE; - } -} - -static jboolean Matcher_matchesImpl(JNIEnv* env, jclass, jlong addr, jintArray offsets) { - MatcherState* state = toMatcherState(addr); - UBool result = state->matcher()->matches(state->status()); - if (result) { - state->updateOffsets(env, offsets); - return JNI_TRUE; - } else { - return JNI_FALSE; - } -} - -static jlong Matcher_openImpl(JNIEnv* env, jclass, jlong patternAddr) { - icu::RegexPattern* pattern = reinterpret_cast<icu::RegexPattern*>(static_cast<uintptr_t>(patternAddr)); - UErrorCode status = U_ZERO_ERROR; - icu::RegexMatcher* result = pattern->matcher(status); - if (maybeThrowIcuException(env, "RegexPattern::matcher", status)) { - return 0; - } - - return reinterpret_cast<uintptr_t>(new MatcherState(result)); -} - -static jboolean Matcher_requireEndImpl(JNIEnv*, jclass, jlong addr) { - MatcherState* state = toMatcherState(addr); - if (state->matcher()->requireEnd() != 0) { - return JNI_TRUE; - } else { - return JNI_FALSE; - } -} - -static void Matcher_setInputImpl(JNIEnv* env, jclass, jlong addr, jstring javaText, jint start, jint end) { - MatcherState* state = toMatcherState(addr); - if (state->updateInput(env, javaText)) { - state->matcher()->region(start, end, state->status()); - } -} - -static void Matcher_useAnchoringBoundsImpl(JNIEnv*, jclass, jlong addr, jboolean value) { - MatcherState* state = toMatcherState(addr); - state->matcher()->useAnchoringBounds(value); -} - -static void Matcher_useTransparentBoundsImpl(JNIEnv*, jclass, jlong addr, jboolean value) { - MatcherState* state = toMatcherState(addr); - state->matcher()->useTransparentBounds(value); -} - -static jint Matcher_getMatchedGroupIndex0(JNIEnv* env, jclass, jlong patternAddr, jstring javaGroupName) { - icu::RegexPattern* pattern = reinterpret_cast<icu::RegexPattern*>(static_cast<uintptr_t>(patternAddr)); - ScopedJavaUnicodeString groupName(env, javaGroupName); - UErrorCode status = U_ZERO_ERROR; - - jint result = pattern->groupNumberFromName(groupName.unicodeString(), status); - if (U_SUCCESS(status)) { - return result; - } - if (status == U_REGEX_INVALID_CAPTURE_GROUP_NAME) { - return -1; - } - maybeThrowIcuException(env, "RegexPattern::groupNumberFromName", status); - return -1; -} - - -static JNINativeMethod gMethods[] = { - NATIVE_METHOD(Matcher, getMatchedGroupIndex0, "(JLjava/lang/String;)I"), - NATIVE_METHOD(Matcher, findImpl, "(JI[I)Z"), - NATIVE_METHOD(Matcher, findNextImpl, "(J[I)Z"), - NATIVE_METHOD(Matcher, getNativeFinalizer, "()J"), - NATIVE_METHOD(Matcher, groupCountImpl, "(J)I"), - NATIVE_METHOD(Matcher, hitEndImpl, "(J)Z"), - NATIVE_METHOD(Matcher, lookingAtImpl, "(J[I)Z"), - NATIVE_METHOD(Matcher, matchesImpl, "(J[I)Z"), - NATIVE_METHOD(Matcher, openImpl, "(J)J"), - NATIVE_METHOD(Matcher, requireEndImpl, "(J)Z"), - NATIVE_METHOD(Matcher, setInputImpl, "(JLjava/lang/String;II)V"), - NATIVE_METHOD(Matcher, useAnchoringBoundsImpl, "(JZ)V"), - NATIVE_METHOD(Matcher, useTransparentBoundsImpl, "(JZ)V"), -}; -void register_java_util_regex_Matcher(JNIEnv* env) { - jniRegisterNativeMethods(env, "java/util/regex/Matcher", gMethods, NELEM(gMethods)); -} diff --git a/luni/src/main/native/java_util_regex_Pattern.cpp b/luni/src/main/native/java_util_regex_Pattern.cpp deleted file mode 100644 index a893bab9f3..0000000000 --- a/luni/src/main/native/java_util_regex_Pattern.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "Pattern" - -#include <stdlib.h> - -#include <nativehelper/JNIHelp.h> -#include <nativehelper/jni_macros.h> - -#include "unicode/parseerr.h" -#include "unicode/regex.h" - -#include "JniConstants.h" -#include "ScopedJavaUnicodeString.h" - -// ICU documentation: http://icu-project.org/apiref/icu4c/classRegexPattern.html - -static const char* regexDetailMessage(UErrorCode status) { - // These human-readable error messages were culled from "utypes.h", and then slightly tuned - // to make more sense in context. - // If we don't have a special-case, we'll just return the textual name of - // the enum value (such as U_REGEX_RULE_SYNTAX), which is better than nothing. - switch (status) { - case U_REGEX_INTERNAL_ERROR: return "An internal error was detected"; - case U_REGEX_RULE_SYNTAX: return "Syntax error in regexp pattern"; - case U_REGEX_INVALID_STATE: return "Matcher in invalid state for requested operation"; - case U_REGEX_BAD_ESCAPE_SEQUENCE: return "Unrecognized backslash escape sequence in pattern"; - case U_REGEX_PROPERTY_SYNTAX: return "Incorrect Unicode property"; - case U_REGEX_UNIMPLEMENTED: return "Use of unimplemented feature"; - case U_REGEX_MISMATCHED_PAREN: return "Incorrectly nested parentheses in regexp pattern"; - case U_REGEX_NUMBER_TOO_BIG: return "Decimal number is too large"; - case U_REGEX_BAD_INTERVAL: return "Error in {min,max} interval"; - case U_REGEX_MAX_LT_MIN: return "In {min,max}, max is less than min"; - case U_REGEX_INVALID_BACK_REF: return "Back-reference to a non-existent capture group"; - case U_REGEX_INVALID_FLAG: return "Invalid value for match mode flags"; - case U_REGEX_LOOK_BEHIND_LIMIT: return "Look-behind pattern matches must have a bounded maximum length"; - case U_REGEX_SET_CONTAINS_STRING: return "Regular expressions cannot have UnicodeSets containing strings"; - case U_REGEX_OCTAL_TOO_BIG: return "Octal character constants must be <= 0377."; - case U_REGEX_MISSING_CLOSE_BRACKET: return "Missing closing bracket in character class"; - case U_REGEX_INVALID_RANGE: return "In a character range [x-y], x is greater than y"; - case U_REGEX_STACK_OVERFLOW: return "Regular expression backtrack stack overflow"; - case U_REGEX_TIME_OUT: return "Maximum allowed match time exceeded"; - case U_REGEX_STOPPED_BY_CALLER: return "Matching operation aborted by user callback function"; - default: - return u_errorName(status); - } -} - -static void throwPatternSyntaxException(JNIEnv* env, UErrorCode status, jstring pattern, UParseError error) { - static jmethodID method = env->GetMethodID(JniConstants::GetPatternSyntaxExceptionClass(env), - "<init>", "(Ljava/lang/String;Ljava/lang/String;I)V"); - jstring message = env->NewStringUTF(regexDetailMessage(status)); - jclass exceptionClass = JniConstants::GetPatternSyntaxExceptionClass(env); - jobject exception = env->NewObject(exceptionClass, method, message, pattern, error.offset); - env->Throw(reinterpret_cast<jthrowable>(exception)); -} - -static void Pattern_free(void* addr) { - delete reinterpret_cast<icu::RegexPattern*>(addr); -} - -static jlong Pattern_getNativeFinalizer(JNIEnv*, jclass) { - return reinterpret_cast<jlong>(&Pattern_free); -} - -static jlong Pattern_compileImpl(JNIEnv* env, jclass, jstring javaRegex, jint flags) { - flags |= UREGEX_ERROR_ON_UNKNOWN_ESCAPES; - - UErrorCode status = U_ZERO_ERROR; - UParseError error; - error.offset = -1; - - ScopedJavaUnicodeString regex(env, javaRegex); - if (!regex.valid()) { - return 0; - } - icu::UnicodeString& regexString(regex.unicodeString()); - icu::RegexPattern* result = icu::RegexPattern::compile(regexString, flags, error, status); - if (!U_SUCCESS(status)) { - throwPatternSyntaxException(env, status, javaRegex, error); - } - return static_cast<jlong>(reinterpret_cast<uintptr_t>(result)); -} - -static JNINativeMethod gMethods[] = { - NATIVE_METHOD(Pattern, compileImpl, "(Ljava/lang/String;I)J"), - NATIVE_METHOD(Pattern, getNativeFinalizer, "()J"), -}; - -void register_java_util_regex_Pattern(JNIEnv* env) { - jniRegisterNativeMethods(env, "java/util/regex/Pattern", gMethods, NELEM(gMethods)); -} diff --git a/mmodules/intracoreapi/api/intra/current-api.txt b/mmodules/intracoreapi/api/intra/current-api.txt index 02cedb46c3..c2024d6522 100644 --- a/mmodules/intracoreapi/api/intra/current-api.txt +++ b/mmodules/intracoreapi/api/intra/current-api.txt @@ -48,6 +48,13 @@ package dalvik.annotation.compat { } +package dalvik.annotation.optimization { + + @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @libcore.api.IntraCoreApi public @interface ReachabilitySensitive { + } + +} + package dalvik.system { @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public final class BlockGuard { @@ -120,6 +127,11 @@ package libcore.net { package libcore.util { + @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public class NativeAllocationRegistry { + method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static libcore.util.NativeAllocationRegistry createMalloced(ClassLoader, long); + method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public Runnable registerNativeAllocation(Object, long); + } + @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE_USE}) @libcore.api.IntraCoreApi public @interface NonNull { } diff --git a/ojluni/src/main/java/java/util/regex/Matcher.java b/ojluni/src/main/java/java/util/regex/Matcher.java index fd60baf6b5..eca98dbae7 100644 --- a/ojluni/src/main/java/java/util/regex/Matcher.java +++ b/ojluni/src/main/java/java/util/regex/Matcher.java @@ -26,8 +26,7 @@ package java.util.regex; -import dalvik.annotation.optimization.ReachabilitySensitive; -import libcore.util.NativeAllocationRegistry; +import com.android.icu.util.regex.NativeMatcher; /** * An engine that performs match operations on a {@linkplain java.lang.CharSequence @@ -109,10 +108,6 @@ public final class Matcher implements MatchResult { /** * The Pattern object that created this Matcher. */ - // Patterns also contain cleanup code and a ReachabilitySensitive field. - // This ensures that "this" and pattern remain reachable while we're using pattern.address - // directly. - @ReachabilitySensitive private Pattern parentPattern; /** @@ -137,21 +132,7 @@ public final class Matcher implements MatchResult { */ private boolean matchFound; - /** - * The address of the native peer. - * Uses of this must be manually synchronized to avoid native crashes. - */ - @ReachabilitySensitive - private long address; - - /** - * If non-null, a Runnable that can be used to explicitly deallocate address. - */ - private Runnable nativeFinalizer; - - private static final NativeAllocationRegistry registry = - NativeAllocationRegistry.createMalloced(Matcher.class.getClassLoader(), - getNativeFinalizer()); + private NativeMatcher nativeMatcher; /** * The index of the last position appended in a substitution. @@ -230,13 +211,8 @@ public final class Matcher implements MatchResult { parentPattern = newPattern; synchronized (this) { - if (nativeFinalizer != null) { - nativeFinalizer.run(); - address = 0; // In case openImpl throws. - nativeFinalizer = null; - } - address = openImpl(parentPattern.address); - nativeFinalizer = registry.registerNativeAllocation(this, address); + nativeMatcher = null; // In case NativeMatcher.create throws. + nativeMatcher = NativeMatcher.create(parentPattern.nativePattern); } if (text != null) { @@ -533,7 +509,7 @@ public final class Matcher implements MatchResult { */ public int groupCount() { synchronized (this) { - return groupCountImpl(address); + return nativeMatcher.groupCount(); } } @@ -548,7 +524,7 @@ public final class Matcher implements MatchResult { */ public boolean matches() { synchronized (this) { - matchFound = matchesImpl(address, groups); + matchFound = nativeMatcher.matches(groups); } return matchFound; } @@ -570,7 +546,7 @@ public final class Matcher implements MatchResult { */ public boolean find() { synchronized (this) { - matchFound = findNextImpl(address, groups); + matchFound = nativeMatcher.findNext(groups); } return matchFound; } @@ -600,7 +576,7 @@ public final class Matcher implements MatchResult { throw new IndexOutOfBoundsException("Illegal start index"); reset(); synchronized (this) { - matchFound = findImpl(address, start, groups); + matchFound = nativeMatcher.find(start, groups); } return matchFound; } @@ -621,7 +597,7 @@ public final class Matcher implements MatchResult { */ public boolean lookingAt() { synchronized (this) { - matchFound = lookingAtImpl(address, groups); + matchFound = nativeMatcher.lookingAt(groups); } return matchFound; } @@ -1023,7 +999,7 @@ public final class Matcher implements MatchResult { public Matcher useTransparentBounds(boolean b) { synchronized (this) { transparentBounds = b; - useTransparentBoundsImpl(address, b); + nativeMatcher.useTransparentBounds(b); } return this; } @@ -1072,7 +1048,7 @@ public final class Matcher implements MatchResult { public Matcher useAnchoringBounds(boolean b) { synchronized (this) { anchoringBounds = b; - useAnchoringBoundsImpl(address, b); + nativeMatcher.useAnchoringBounds(b); } return this; } @@ -1112,7 +1088,7 @@ public final class Matcher implements MatchResult { */ public boolean hitEnd() { synchronized (this) { - return hitEndImpl(address); + return nativeMatcher.hitEnd(); } } @@ -1132,7 +1108,7 @@ public final class Matcher implements MatchResult { */ public boolean requireEnd() { synchronized (this) { - return requireEndImpl(address); + return nativeMatcher.requireEnd(); } } @@ -1195,9 +1171,9 @@ public final class Matcher implements MatchResult { private void resetForInput() { synchronized (this) { - setInputImpl(address, text, from, to); - useAnchoringBoundsImpl(address, anchoringBounds); - useTransparentBoundsImpl(address, transparentBounds); + nativeMatcher.setInput(text, from, to); + nativeMatcher.useAnchoringBounds(anchoringBounds); + nativeMatcher.useTransparentBounds(transparentBounds); } } @@ -1216,7 +1192,7 @@ public final class Matcher implements MatchResult { private int getMatchedGroupIndex(String name) { ensureMatch(); - int result = getMatchedGroupIndex0(parentPattern.address, name); + int result = nativeMatcher.getMatchedGroupIndex(name); if (result < 0) { throw new IllegalArgumentException("No capturing group in the pattern " + "with the name " + name); @@ -1224,20 +1200,6 @@ public final class Matcher implements MatchResult { return result; } - private static native int getMatchedGroupIndex0(long patternAddr, String name); - private static native boolean findImpl(long addr, int startIndex, int[] offsets); - private static native boolean findNextImpl(long addr, int[] offsets); - private static native long getNativeFinalizer(); - private static native int groupCountImpl(long addr); - private static native boolean hitEndImpl(long addr); - private static native boolean lookingAtImpl(long addr, int[] offsets); - private static native boolean matchesImpl(long addr, int[] offsets); - private static native long openImpl(long patternAddr); - private static native boolean requireEndImpl(long addr); - private static native void setInputImpl(long addr, String s, int start, int end); - private static native void useAnchoringBoundsImpl(long addr, boolean value); - private static native void useTransparentBoundsImpl(long addr, boolean value); - /** * A trivial match result implementation that's based on an array of integers * representing match offsets. The array is of the form diff --git a/ojluni/src/main/java/java/util/regex/Pattern.java b/ojluni/src/main/java/java/util/regex/Pattern.java index 55a48de906..3a5ad6390b 100644 --- a/ojluni/src/main/java/java/util/regex/Pattern.java +++ b/ojluni/src/main/java/java/util/regex/Pattern.java @@ -26,11 +26,9 @@ package java.util.regex; -import dalvik.annotation.optimization.ReachabilitySensitive; +import com.android.icu.util.regex.NativePattern; import dalvik.system.VMRuntime; -import libcore.util.NativeAllocationRegistry; - import java.util.Iterator; import java.util.ArrayList; import java.util.NoSuchElementException; @@ -945,12 +943,7 @@ public final class Pattern // BEGIN Android-changed: reimplement matching logic natively via ICU. // We only need some tie-ins to native memory, instead of a large number // of fields on the .java side. - @ReachabilitySensitive - transient long address; - - private static final NativeAllocationRegistry registry = - NativeAllocationRegistry.createMalloced(Pattern.class.getClassLoader(), - getNativeFinalizer()); + /* package */ transient NativePattern nativePattern; // END Android-changed: reimplement matching logic natively via ICU. /** @@ -1430,12 +1423,8 @@ public final class Pattern // These are the flags natively supported by ICU. // They even have the same value in native code. int icuFlags = flags & (CASE_INSENSITIVE | COMMENTS | MULTILINE | DOTALL | UNIX_LINES); - address = compileImpl(icuPattern, icuFlags); - registry.registerNativeAllocation(this, address); + nativePattern = NativePattern.create(icuPattern, icuFlags); } - - private static native long compileImpl(String regex, int flags); - private static native long getNativeFinalizer(); // END Android-changed: reimplement matching logic natively via ICU. /** |