diff options
author | 2017-11-01 13:32:41 +0000 | |
---|---|---|
committer | 2017-11-01 16:21:52 +0000 | |
commit | 26ef34c01ae5db2d3c964844b3717b8974a612c9 (patch) | |
tree | 8470588d8d0601626b3524abb5fbe19386ba7fe4 | |
parent | 62540e3cc58abde95e147210d584614651d858b5 (diff) |
ART: Move intrinsics definitions to runtime
Bug: 37538194
Test: art/test.py --host
Change-Id: Ic7adf5f8b14be0e1880ae898a4e199b4416a4d24
-rw-r--r-- | compiler/driver/compiler_driver.cc | 32 | ||||
-rw-r--r-- | runtime/Android.bp | 1 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_intrinsics.cc | 2 | ||||
-rw-r--r-- | runtime/intrinsics_enum.h (renamed from compiler/intrinsics_enum.h) | 6 | ||||
-rw-r--r-- | runtime/intrinsics_list.h (renamed from compiler/intrinsics_list.h) | 48 | ||||
-rw-r--r-- | runtime/runtime.cc | 6 | ||||
-rw-r--r-- | runtime/runtime_intrinsics.cc | 84 | ||||
-rw-r--r-- | runtime/runtime_intrinsics.h | 26 | ||||
-rwxr-xr-x | test/988-method-trace/gen_srcs.py | 6 | ||||
-rw-r--r-- | test/988-method-trace/src/art/Test988Intrinsics.java | 2 |
10 files changed, 159 insertions, 54 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 547ffbcf62..135f9c7b47 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -66,6 +66,7 @@ #include "nativehelper/ScopedLocalRef.h" #include "object_lock.h" #include "runtime.h" +#include "runtime_intrinsics.h" #include "scoped_thread_state_change-inl.h" #include "thread.h" #include "thread_list.h" @@ -365,28 +366,6 @@ std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateQuickToInterpr } #undef CREATE_TRAMPOLINE -static void SetupIntrinsic(Thread* self, - Intrinsics intrinsic, - InvokeType invoke_type, - const char* class_name, - const char* method_name, - const char* signature) - REQUIRES_SHARED(Locks::mutator_lock_) { - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - PointerSize image_size = class_linker->GetImagePointerSize(); - ObjPtr<mirror::Class> cls = class_linker->FindSystemClass(self, class_name); - if (cls == nullptr) { - LOG(FATAL) << "Could not find class of intrinsic " << class_name; - } - ArtMethod* method = cls->FindClassMethod(method_name, signature, image_size); - if (method == nullptr || method->GetDeclaringClass() != cls) { - LOG(FATAL) << "Could not find method of intrinsic " - << class_name << " " << method_name << " " << signature; - } - DCHECK_EQ(method->GetInvokeType(), invoke_type); - method->SetIntrinsic(static_cast<uint32_t>(intrinsic)); -} - void CompilerDriver::CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings) { @@ -405,14 +384,7 @@ void CompilerDriver::CompileAll(jobject class_loader, // We don't need to setup the intrinsics for non boot image compilation, as // those compilations will pick up a boot image that have the ArtMethod already // set with the intrinsics flag. - ScopedObjectAccess soa(Thread::Current()); -#define SETUP_INTRINSICS(Name, InvokeType, NeedsEnvironmentOrCache, SideEffects, Exceptions, \ - ClassName, MethodName, Signature) \ - SetupIntrinsic(soa.Self(), Intrinsics::k##Name, InvokeType, ClassName, MethodName, Signature); -#include "intrinsics_list.h" - INTRINSICS_LIST(SETUP_INTRINSICS) -#undef INTRINSICS_LIST -#undef SETUP_INTRINSICS + InitializeIntrinsics(); } // Compile: // 1) Compile all classes and methods enabled for compilation. May fall back to dex-to-dex diff --git a/runtime/Android.bp b/runtime/Android.bp index a615437985..3258aaee2a 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -203,6 +203,7 @@ cc_defaults { "runtime.cc", "runtime_callbacks.cc", "runtime_common.cc", + "runtime_intrinsics.cc", "runtime_options.cc", "scoped_thread_state_change.cc", "signal_catcher.cc", diff --git a/runtime/interpreter/interpreter_intrinsics.cc b/runtime/interpreter/interpreter_intrinsics.cc index 26de6b4ff7..bb827883b5 100644 --- a/runtime/interpreter/interpreter_intrinsics.cc +++ b/runtime/interpreter/interpreter_intrinsics.cc @@ -16,8 +16,8 @@ #include "interpreter/interpreter_intrinsics.h" -#include "compiler/intrinsics_enum.h" #include "dex_instruction.h" +#include "intrinsics_enum.h" #include "interpreter/interpreter_common.h" namespace art { diff --git a/compiler/intrinsics_enum.h b/runtime/intrinsics_enum.h index 55281812e4..d46d0cc00f 100644 --- a/compiler/intrinsics_enum.h +++ b/runtime/intrinsics_enum.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ART_COMPILER_INTRINSICS_ENUM_H_ -#define ART_COMPILER_INTRINSICS_ENUM_H_ +#ifndef ART_RUNTIME_INTRINSICS_ENUM_H_ +#define ART_RUNTIME_INTRINSICS_ENUM_H_ namespace art { @@ -32,4 +32,4 @@ std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic); } // namespace art -#endif // ART_COMPILER_INTRINSICS_ENUM_H_ +#endif // ART_RUNTIME_INTRINSICS_ENUM_H_ diff --git a/compiler/intrinsics_list.h b/runtime/intrinsics_list.h index bfefead394..3b9b521d24 100644 --- a/compiler/intrinsics_list.h +++ b/runtime/intrinsics_list.h @@ -14,22 +14,38 @@ * limitations under the License. */ -#ifndef ART_COMPILER_INTRINSICS_LIST_H_ -#define ART_COMPILER_INTRINSICS_LIST_H_ - -// All intrinsics supported by ART. Format is name, then whether it is expected -// to be a HInvokeStaticOrDirect node (compared to HInvokeVirtual), then whether it requires an -// environment, may have side effects, or may throw exceptions. +#ifndef ART_RUNTIME_INTRINSICS_LIST_H_ +#define ART_RUNTIME_INTRINSICS_LIST_H_ +// This file defines the set of intrinsics that are supported by ART +// in the compiler and runtime. Neither compiler nor runtime has +// intrinsics for all methods here. +// +// The entries in the INTRINSICS_LIST below have the following format: +// +// 1. name +// 2. invocation-type (art::InvokeType value). +// 3. needs-environment (art::IntrinsicNeedsEnvironmentOrCache value) +// 4. side-effects (art::IntrinsicSideEffects value) +// 5. exception-info (art::::IntrinsicExceptions value) +// 6. declaring class descriptor +// 7. method name +// 8. method descriptor +// +// The needs-environment, side-effects and exception-info are compiler +// related properties (compiler/optimizing/nodes.h) that should not be +// used outside of the compiler. +// // Note: adding a new intrinsic requires an art image version change, // as the modifiers flag for some ArtMethods will need to be changed. - -// Note: j.l.Integer.valueOf says kNoThrow even though it could throw an OOME. -// The kNoThrow should be renamed to kNoVisibleThrow, as it is ok to GVN Integer.valueOf -// (kNoSideEffects), and it is also OK to remove it if it's unused. - -// Note: Thread.interrupted is marked with kAllSideEffects due to the lack of finer grain -// side effects representation. +// +// Note: j.l.Integer.valueOf says kNoThrow even though it could throw an +// OOME. The kNoThrow should be renamed to kNoVisibleThrow, as it is ok to +// GVN Integer.valueOf (kNoSideEffects), and it is also OK to remove it if +// it's unused. +// +// Note: Thread.interrupted is marked with kAllSideEffects due to the lack +// of finer grain side effects representation. #define INTRINSICS_LIST(V) \ V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "doubleToRawLongBits", "(D)J") \ @@ -163,7 +179,7 @@ V(VarHandleAcquireFence, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kNoThrow, "Ljava/lang/invoke/VarHandle;", "acquireFence", "()V") \ V(VarHandleReleaseFence, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kNoThrow, "Ljava/lang/invoke/VarHandle;", "releaseFence", "()V") \ V(VarHandleLoadLoadFence, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kNoThrow, "Ljava/lang/invoke/VarHandle;", "loadLoadFence", "()V") \ - V(VarHandleStoreStoreFence, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow, "Ljava/lang/invoke/VarHandle;", "storeStoreFence", "()V") \ + V(VarHandleStoreStoreFence, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow, "Ljava/lang/invoke/VarHandle;", "storeStoreFence", "()V") -#endif // ART_COMPILER_INTRINSICS_LIST_H_ -#undef ART_COMPILER_INTRINSICS_LIST_H_ // #define is only for lint. +#endif // ART_RUNTIME_INTRINSICS_LIST_H_ +#undef ART_RUNTIME_INTRINSICS_LIST_H_ // #define is only for lint. diff --git a/runtime/runtime.cc b/runtime/runtime.cc index c88799cc28..ec210d0aef 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -143,6 +143,7 @@ #include "quick/quick_method_frame_info.h" #include "reflection.h" #include "runtime_callbacks.h" +#include "runtime_intrinsics.h" #include "runtime_options.h" #include "scoped_thread_state_change-inl.h" #include "sigchain.h" @@ -738,6 +739,11 @@ bool Runtime::Start() { InitNativeMethods(); } + // IntializeIntrinsics needs to be called after the WellKnownClasses::Init in InitNativeMethods + // because in checking the invocation types of intrinsic methods ArtMethod::GetInvokeType() + // needs the SignaturePolymorphic annotation class which is initialized in WellKnownClasses::Init. + InitializeIntrinsics(); + // Initialize well known thread group values that may be accessed threads while attaching. InitThreadGroups(self); diff --git a/runtime/runtime_intrinsics.cc b/runtime/runtime_intrinsics.cc new file mode 100644 index 0000000000..f710ebeb4c --- /dev/null +++ b/runtime/runtime_intrinsics.cc @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 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. + */ + +#include "runtime_intrinsics.h" + +#include "art_method-inl.h" +#include "class_linker.h" +#include "intrinsics_enum.h" +#include "invoke_type.h" +#include "mirror/class.h" +#include "runtime.h" +#include "scoped_thread_state_change-inl.h" +#include "thread.h" + +namespace art { + +namespace { + +// Initialize an intrinsic. Returns true if the intrinsic is already +// initialized, false otherwise. +bool InitializeIntrinsic(Thread* self, + Intrinsics intrinsic, + InvokeType invoke_type, + const char* class_name, + const char* method_name, + const char* signature) + REQUIRES_SHARED(Locks::mutator_lock_) { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + PointerSize image_size = class_linker->GetImagePointerSize(); + ObjPtr<mirror::Class> cls = class_linker->FindSystemClass(self, class_name); + if (cls == nullptr) { + LOG(FATAL) << "Could not find class of intrinsic " << class_name; + } + + ArtMethod* method = cls->FindClassMethod(method_name, signature, image_size); + if (method == nullptr || method->GetDeclaringClass() != cls) { + LOG(FATAL) << "Could not find method of intrinsic " + << class_name << " " << method_name << " " << signature; + } + + CHECK_EQ(method->GetInvokeType(), invoke_type); + if (method->IsIntrinsic()) { + CHECK_EQ(method->GetIntrinsic(), static_cast<uint32_t>(intrinsic)); + return true; + } else { + method->SetIntrinsic(static_cast<uint32_t>(intrinsic)); + return false; + } +} + +} // namespace + +void InitializeIntrinsics() { + ScopedObjectAccess soa(Thread::Current()); + // Initialization here uses the short-circuit operator || to stop + // initializing if there's an already initialized intrinsic. +#define SETUP_INTRINSICS(Name, InvokeType, _, __, ___, ClassName, MethodName, Signature) \ + InitializeIntrinsic(soa.Self(), \ + Intrinsics::k##Name, \ + InvokeType, \ + ClassName, \ + MethodName, \ + Signature) || +#include "intrinsics_list.h" + INTRINSICS_LIST(SETUP_INTRINSICS) +#undef INTRINSICS_LIST +#undef SETUP_INTRINSICS + true; +} + +} // namespace art diff --git a/runtime/runtime_intrinsics.h b/runtime/runtime_intrinsics.h new file mode 100644 index 0000000000..98dc9bc8c9 --- /dev/null +++ b/runtime/runtime_intrinsics.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef ART_RUNTIME_RUNTIME_INTRINSICS_H_ +#define ART_RUNTIME_RUNTIME_INTRINSICS_H_ + +namespace art { + +void InitializeIntrinsics(); + +} // namespace art + +#endif // ART_RUNTIME_RUNTIME_INTRINSICS_H_ diff --git a/test/988-method-trace/gen_srcs.py b/test/988-method-trace/gen_srcs.py index 8f1082ffbe..9d26032edc 100755 --- a/test/988-method-trace/gen_srcs.py +++ b/test/988-method-trace/gen_srcs.py @@ -28,8 +28,8 @@ import sys from string import Template -# Relative path to art/compiler/intrinsics_list.h -INTRINSICS_LIST_H = os.path.dirname(os.path.realpath(__file__)) + "/../../compiler/intrinsics_list.h" +# Relative path to art/runtime/intrinsics_list.h +INTRINSICS_LIST_H = os.path.dirname(os.path.realpath(__file__)) + "/../../runtime/intrinsics_list.h" # Macro parameter index to V(). Negative means from the end. IDX_STATIC_OR_VIRTUAL = 1 @@ -90,7 +90,7 @@ $initialize_classes } static void test() { - // Call each intrinsic from art/compiler/intrinsics_list.h to make sure they are traced. + // Call each intrinsic from art/runtime/intrinsics_list.h to make sure they are traced. $test_body } } diff --git a/test/988-method-trace/src/art/Test988Intrinsics.java b/test/988-method-trace/src/art/Test988Intrinsics.java index 099fbf2ce8..3069f1a2c3 100644 --- a/test/988-method-trace/src/art/Test988Intrinsics.java +++ b/test/988-method-trace/src/art/Test988Intrinsics.java @@ -44,7 +44,7 @@ class Test988Intrinsics { } static void test() { - // Call each intrinsic from art/compiler/intrinsics_list.h to make sure they are traced. + // Call each intrinsic from art/runtime/intrinsics_list.h to make sure they are traced. java.lang.Double.doubleToRawLongBits(0.0); java.lang.Double.doubleToLongBits(0.0); java.lang.Double.isInfinite(0.0); |