blob: f48568271d08ce06939c73b2801bf65a4751e6b2 [file] [log] [blame]
Mathieu Chartiere5f13e52015-02-24 09:37:21 -08001/*
2 * Copyright 2014 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 "jit_instrumentation.h"
18
Mathieu Chartiere401d142015-04-22 13:56:20 -070019#include "art_method-inl.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080020#include "jit.h"
21#include "jit_code_cache.h"
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080022#include "scoped_thread_state_change.h"
23
24namespace art {
25namespace jit {
26
27class JitCompileTask : public Task {
28 public:
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010029 explicit JitCompileTask(ArtMethod* method) : method_(method) {}
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080030
31 virtual void Run(Thread* self) OVERRIDE {
32 ScopedObjectAccess soa(self);
33 VLOG(jit) << "JitCompileTask compiling method " << PrettyMethod(method_);
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010034 if (!Runtime::Current()->GetJit()->CompileMethod(method_, self)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080035 VLOG(jit) << "Failed to compile method " << PrettyMethod(method_);
36 }
37 }
38
39 virtual void Finalize() OVERRIDE {
40 delete this;
41 }
42
43 private:
Mathieu Chartiere401d142015-04-22 13:56:20 -070044 ArtMethod* const method_;
Mathieu Chartier3130cdf2015-05-03 15:20:23 -070045
46 DISALLOW_IMPLICIT_CONSTRUCTORS(JitCompileTask);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080047};
48
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010049JitInstrumentationCache::JitInstrumentationCache(size_t hot_method_threshold,
50 size_t warm_method_threshold)
51 : hot_method_threshold_(hot_method_threshold),
52 warm_method_threshold_(warm_method_threshold) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080053}
54
55void JitInstrumentationCache::CreateThreadPool() {
56 thread_pool_.reset(new ThreadPool("Jit thread pool", 1));
57}
58
59void JitInstrumentationCache::DeleteThreadPool() {
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010060 DCHECK(Runtime::Current()->IsShuttingDown(Thread::Current()));
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080061 thread_pool_.reset();
62}
63
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010064void JitInstrumentationCache::AddSamples(Thread* self, ArtMethod* method, size_t) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080065 ScopedObjectAccessUnchecked soa(self);
66 // Since we don't have on-stack replacement, some methods can remain in the interpreter longer
67 // than we want resulting in samples even after the method is compiled.
Mathieu Chartier70f7d982015-05-08 17:05:01 -070068 if (method->IsClassInitializer() || method->IsNative() ||
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080069 Runtime::Current()->GetJit()->GetCodeCache()->ContainsMethod(method)) {
70 return;
71 }
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010072 if (thread_pool_.get() == nullptr) {
73 DCHECK(Runtime::Current()->IsShuttingDown(self));
74 return;
75 }
76 uint16_t sample_count = method->IncrementCounter();
77 if (sample_count == warm_method_threshold_) {
78 ProfilingInfo* info = method->CreateProfilingInfo();
79 if (info != nullptr) {
80 VLOG(jit) << "Start profiling " << PrettyMethod(method);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080081 }
82 }
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010083 if (sample_count == hot_method_threshold_) {
84 thread_pool_->AddTask(self, new JitCompileTask(
85 method->GetInterfaceMethodIfProxy(sizeof(void*))));
86 thread_pool_->StartWorkers(self);
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080087 }
88}
89
90JitInstrumentationListener::JitInstrumentationListener(JitInstrumentationCache* cache)
91 : instrumentation_cache_(cache) {
92 CHECK(instrumentation_cache_ != nullptr);
93}
94
Nicolas Geoffray5550ca82015-08-21 18:38:30 +010095void JitInstrumentationListener::InvokeVirtualOrInterface(Thread* thread,
96 mirror::Object* this_object,
97 ArtMethod* caller,
98 uint32_t dex_pc,
99 ArtMethod* callee ATTRIBUTE_UNUSED) {
100 DCHECK(this_object != nullptr);
101 ProfilingInfo* info = caller->GetProfilingInfo();
102 if (info != nullptr) {
103 info->AddInvokeInfo(thread, dex_pc, this_object->GetClass());
104 }
105}
106
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800107} // namespace jit
108} // namespace art