1/*
2 * Copyright (C) 2015 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
17#include "common_runtime_test.h"
18
19#include "art_method-inl.h"
20#include "class_linker.h"
21#include "jit_code_cache.h"
22#include "scoped_thread_state_change.h"
23#include "thread-inl.h"
24
25namespace art {
26namespace jit {
27
28class JitCodeCacheTest : public CommonRuntimeTest {
29 public:
30};
31
32TEST_F(JitCodeCacheTest, TestCoverage) {
33  std::string error_msg;
34  constexpr size_t kSize = 1 * MB;
35  std::unique_ptr<JitCodeCache> code_cache(
36      JitCodeCache::Create(kSize, &error_msg));
37  ASSERT_TRUE(code_cache.get() != nullptr) << error_msg;
38  ASSERT_TRUE(code_cache->CodeCachePtr() != nullptr);
39  ASSERT_EQ(code_cache->CodeCacheSize(), 0u);
40  ASSERT_GT(code_cache->CodeCacheRemain(), 0u);
41  ASSERT_TRUE(code_cache->DataCachePtr() != nullptr);
42  ASSERT_EQ(code_cache->DataCacheSize(), 0u);
43  ASSERT_GT(code_cache->DataCacheRemain(), 0u);
44  ASSERT_EQ(code_cache->CodeCacheRemain() + code_cache->DataCacheRemain(), kSize);
45  ASSERT_EQ(code_cache->NumMethods(), 0u);
46  ScopedObjectAccess soa(Thread::Current());
47  StackHandleScope<1> hs(soa.Self());
48  uint8_t* const reserved_code = code_cache->ReserveCode(soa.Self(), 4 * KB);
49  ASSERT_TRUE(reserved_code != nullptr);
50  ASSERT_TRUE(code_cache->ContainsCodePtr(reserved_code));
51  ASSERT_EQ(code_cache->NumMethods(), 1u);
52  ClassLinker* const cl = Runtime::Current()->GetClassLinker();
53  auto* method = cl->AllocArtMethodArray(soa.Self(), 1);
54  ASSERT_FALSE(code_cache->ContainsMethod(method));
55  method->SetEntryPointFromQuickCompiledCode(reserved_code);
56  ASSERT_TRUE(code_cache->ContainsMethod(method));
57  ASSERT_EQ(code_cache->GetCodeFor(method), reserved_code);
58  // Save the code and then change it.
59  code_cache->SaveCompiledCode(method, reserved_code);
60  method->SetEntryPointFromQuickCompiledCode(nullptr);
61  ASSERT_EQ(code_cache->GetCodeFor(method), reserved_code);
62  const uint8_t data_arr[] = {1, 2, 3, 4, 5};
63  uint8_t* data_ptr = code_cache->AddDataArray(soa.Self(), data_arr, data_arr + sizeof(data_arr));
64  ASSERT_TRUE(data_ptr != nullptr);
65  ASSERT_EQ(memcmp(data_ptr, data_arr, sizeof(data_arr)), 0);
66}
67
68TEST_F(JitCodeCacheTest, TestOverflow) {
69  std::string error_msg;
70  constexpr size_t kSize = 1 * MB;
71  std::unique_ptr<JitCodeCache> code_cache(
72      JitCodeCache::Create(kSize, &error_msg));
73  ASSERT_TRUE(code_cache.get() != nullptr) << error_msg;
74  ASSERT_TRUE(code_cache->CodeCachePtr() != nullptr);
75  size_t code_bytes = 0;
76  size_t data_bytes = 0;
77  constexpr size_t kCodeArrSize = 4 * KB;
78  constexpr size_t kDataArrSize = 4 * KB;
79  uint8_t data_arr[kDataArrSize];
80  std::fill_n(data_arr, arraysize(data_arr), 53);
81  // Add code and data until we are full.
82  uint8_t* code_ptr = nullptr;
83  uint8_t* data_ptr = nullptr;
84  do {
85    code_ptr = code_cache->ReserveCode(Thread::Current(), kCodeArrSize);
86    data_ptr = code_cache->AddDataArray(Thread::Current(), data_arr, data_arr + kDataArrSize);
87    if (code_ptr != nullptr) {
88      code_bytes += kCodeArrSize;
89    }
90    if (data_ptr != nullptr) {
91      data_bytes += kDataArrSize;
92    }
93  } while (code_ptr != nullptr || data_ptr != nullptr);
94  // Make sure we added a reasonable amount
95  CHECK_GT(code_bytes, 0u);
96  CHECK_LE(code_bytes, kSize);
97  CHECK_GT(data_bytes, 0u);
98  CHECK_LE(data_bytes, kSize);
99  CHECK_GE(code_bytes + data_bytes, kSize * 4 / 5);
100}
101
102}  // namespace jit
103}  // namespace art
104