compiler_driver_test.cc revision 700a402244a1a423da4f3ba8032459f4b65fa18f
113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi/*
213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * Copyright (C) 2011 The Android Open Source Project
313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *
413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License");
513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * you may not use this file except in compliance with the License.
613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * You may obtain a copy of the License at
713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *
813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *      http://www.apache.org/licenses/LICENSE-2.0
913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi *
1013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software
1113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS,
1213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * See the License for the specific language governing permissions and
1413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi * limitations under the License.
1513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi */
1613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
17bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include "driver/compiler_driver.h"
18bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi
19bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi#include <stdint.h>
206b1182bd1c2354ae8d8579b5a2941a21b42540a9Dongwon Kang#include <stdio.h>
216b1182bd1c2354ae8d8579b5a2941a21b42540a9Dongwon Kang#include <memory>
226b1182bd1c2354ae8d8579b5a2941a21b42540a9Dongwon Kang
234ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "class_linker.h"
244ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "common_compiler_test.h"
254ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "dex_file.h"
264ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "gc/heap.h"
274ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "mirror/art_method-inl.h"
284ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "mirror/class.h"
294ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi#include "mirror/class-inl.h"
3013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "mirror/dex_cache-inl.h"
3113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "mirror/object_array-inl.h"
3213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "mirror/object-inl.h"
3313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi#include "handle_scope-inl.h"
34bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi
35bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivinamespace art {
360f92f48017588949daf7d24a339423e149bb2555Glenn Kasten
37bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Triviclass CompilerDriverTest : public CommonCompilerTest {
38bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi protected:
39bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi  void CompileAll(jobject class_loader) LOCKS_EXCLUDED(Locks::mutator_lock_) {
40bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    TimingLogger timings("CompilerDriverTest::CompileAll", false, false);
41bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    timings.StartSplit("CompileAll");
427f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    compiler_driver_->CompileAll(class_loader,
437f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                                 Runtime::Current()->GetCompileTimeClassPath(class_loader),
440f92f48017588949daf7d24a339423e149bb2555Glenn Kasten                                 &timings);
457f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    MakeAllExecutable(class_loader);
467f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    timings.EndSplit();
477f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi  }
487f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
497349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten  void EnsureCompiled(jobject class_loader, const char* class_name, const char* method,
5013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                      const char* signature, bool is_virtual)
5113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      LOCKS_EXCLUDED(Locks::mutator_lock_) {
5213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    CompileAll(class_loader);
5313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    Thread::Current()->TransitionFromSuspendedToRunnable();
549bf773df2b8a0cf788f394c326960bc3a5af7c60Chih-Hung Hsieh    bool started = runtime_->Start();
5513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    CHECK(started);
5613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    env_ = Thread::Current()->GetJniEnv();
57e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    class_ = env_->FindClass(class_name);
58e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    CHECK(class_ != NULL) << "Class not found: " << class_name;
5913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    if (is_virtual) {
6013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      mid_ = env_->GetMethodID(class_, method, signature);
615050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    } else {
6213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      mid_ = env_->GetStaticMethodID(class_, method, signature);
6391540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten    }
647f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    CHECK(mid_ != NULL) << "Method not found: " << class_name << "." << method << signature;
657f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi  }
667f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi
677f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi  void MakeAllExecutable(jobject class_loader) {
687f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    const std::vector<const DexFile*>& class_path
6913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        = Runtime::Current()->GetCompileTimeClassPath(class_loader);
7013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    for (size_t i = 0; i != class_path.size(); ++i) {
7113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      const DexFile* dex_file = class_path[i];
727f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      CHECK(dex_file != NULL);
737f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi      MakeDexFileExecutable(class_loader, *dex_file);
7454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    }
7513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  }
7613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
7713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  void MakeDexFileExecutable(jobject class_loader, const DexFile& dex_file) {
7813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
7913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    for (size_t i = 0; i < dex_file.NumClassDefs(); i++) {
807349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten      const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
8113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      const char* descriptor = dex_file.GetClassDescriptor(class_def);
8213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      ScopedObjectAccess soa(Thread::Current());
8313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      StackHandleScope<1> hs(soa.Self());
8413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      Handle<mirror::ClassLoader> loader(
8513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi          hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader)));
8613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      mirror::Class* c = class_linker->FindClass(soa.Self(), descriptor, loader);
8713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      CHECK(c != NULL);
8813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      for (size_t i = 0; i < c->NumDirectMethods(); i++) {
8913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        MakeExecutable(c->GetDirectMethod(i));
9013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      }
9113837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      for (size_t i = 0; i < c->NumVirtualMethods(); i++) {
9213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi        MakeExecutable(c->GetVirtualMethod(i));
9313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi      }
9454cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    }
9513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  }
9654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi
9713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  JNIEnv* env_;
9813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  jclass class_;
9913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  jmethodID mid_;
100e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi};
1019fc34129185026cefe3760a714990879435b9449Dongwon Kang
102e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi// Disabled due to 10 second runtime on host
103e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel TriviTEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) {
10413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  CompileAll(NULL);
10513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
10613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  // All libcore references should resolve
1075050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi  ScopedObjectAccess soa(Thread::Current());
10813837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  const DexFile* dex = java_lang_dex_file_;
10913837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  mirror::DexCache* dex_cache = class_linker_->FindDexCache(*dex);
11013837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
111e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi  for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
112e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    const mirror::String* string = dex_cache->GetResolvedString(i);
113e6ded5c61944a87fa9e472dec3a6929855d42aebJean-Michel Trivi    EXPECT_TRUE(string != NULL) << "string_idx=" << i;
11413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  }
11513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes());
11613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
11713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi    mirror::Class* type = dex_cache->GetResolvedType(i);
1185050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi    EXPECT_TRUE(type != NULL) << "type_idx=" << i
1195050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi                              << " " << dex->GetTypeDescriptor(dex->GetTypeId(i));
1205050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi  }
1215050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi  EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods());
12213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
1237f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    mirror::ArtMethod* method = dex_cache->GetResolvedMethod(i);
1247f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi    EXPECT_TRUE(method != NULL) << "method_idx=" << i
1257f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                                << " " << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
12691540f92d7f1bcda423859af6bd82df083c2afabGlenn Kasten                                << " " << dex->GetMethodName(dex->GetMethodId(i));
12754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    EXPECT_TRUE(method->GetEntryPointFromQuickCompiledCode() != NULL) << "method_idx=" << i
1287f5cc1afe49395fefaad9b2bbd728a45d1bfda6aJean-Michel Trivi                                           << " "
1297349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten                                           << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
1307349b2e742b2cedc6d149fac62ed661ad7d47decGlenn Kasten                                           << " " << dex->GetMethodName(dex->GetMethodId(i));
131bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi    EXPECT_TRUE(method->GetEntryPointFromPortableCompiledCode() != NULL) << "method_idx=" << i
13213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi                                           << " "
1334ee246c55533bdab8ab5fa0f0581744fe58e7c91Jean-Michel Trivi                                           << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
1345050a75e342ce45794d56666cddde3d46472acc7Jean-Michel Trivi                                           << " " << dex->GetMethodName(dex->GetMethodId(i));
13513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  }
13654cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi  EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
13754cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi  for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
13854cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    mirror::ArtField* field = dex_cache->GetResolvedField(i);
13954cad4f35a090a06e655fcc9e072e1d38f9e7689Jean-Michel Trivi    EXPECT_TRUE(field != NULL) << "field_idx=" << i
1403597268c2bf4ff71521e3cbe522d7ee02c41f175Jean-Michel Trivi                               << " " << dex->GetFieldDeclaringClassDescriptor(dex->GetFieldId(i))
1413597268c2bf4ff71521e3cbe522d7ee02c41f175Jean-Michel Trivi                               << " " << dex->GetFieldName(dex->GetFieldId(i));
14213837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  }
14313837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14413837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  // TODO check Class::IsVerified for all classes
14513837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi
14613837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi  // TODO: check that all Method::GetCode() values are non-null
14713837cf3f7be0eb8b1a9552bd99a89f98c987720Jean-Michel Trivi}
148bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel Trivi
149bb832e853d4afb11b0a3287b2eb0cad87696d631Jean-Michel TriviTEST_F(CompilerDriverTest, AbstractMethodErrorStub) {
150  TEST_DISABLED_FOR_PORTABLE();
151  TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING();
152  jobject class_loader;
153  {
154    ScopedObjectAccess soa(Thread::Current());
155    StackHandleScope<1> hs(soa.Self());
156    auto null_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
157    CompileVirtualMethod(null_loader, "java.lang.Class", "isFinalizable", "()Z");
158    CompileDirectMethod(null_loader, "java.lang.Object", "<init>", "()V");
159    class_loader = LoadDex("AbstractMethod");
160  }
161  ASSERT_TRUE(class_loader != NULL);
162  EnsureCompiled(class_loader, "AbstractClass", "foo", "()V", true);
163
164  // Create a jobj_ of ConcreteClass, NOT AbstractClass.
165  jclass c_class = env_->FindClass("ConcreteClass");
166  jmethodID constructor = env_->GetMethodID(c_class, "<init>", "()V");
167  jobject jobj_ = env_->NewObject(c_class, constructor);
168  ASSERT_TRUE(jobj_ != NULL);
169
170  // Force non-virtual call to AbstractClass foo, will throw AbstractMethodError exception.
171  env_->CallNonvirtualVoidMethod(jobj_, class_, mid_);
172  EXPECT_EQ(env_->ExceptionCheck(), JNI_TRUE);
173  jthrowable exception = env_->ExceptionOccurred();
174  env_->ExceptionClear();
175  jclass jlame = env_->FindClass("java/lang/AbstractMethodError");
176  EXPECT_TRUE(env_->IsInstanceOf(exception, jlame));
177  Thread::Current()->ClearException();
178}
179
180// TODO: need check-cast test (when stub complete & we can throw/catch
181
182}  // namespace art
183