quick_instrumentation_entrypoints.cc revision 2cebb24bfc3247d3e9be138a3350106737455918
1725a957985171d712d5c048cc3d00ff14968784bjeffhao/*
2725a957985171d712d5c048cc3d00ff14968784bjeffhao * Copyright (C) 2012 The Android Open Source Project
3725a957985171d712d5c048cc3d00ff14968784bjeffhao *
4725a957985171d712d5c048cc3d00ff14968784bjeffhao * Licensed under the Apache License, Version 2.0 (the "License");
5725a957985171d712d5c048cc3d00ff14968784bjeffhao * you may not use this file except in compliance with the License.
6725a957985171d712d5c048cc3d00ff14968784bjeffhao * You may obtain a copy of the License at
7725a957985171d712d5c048cc3d00ff14968784bjeffhao *
8725a957985171d712d5c048cc3d00ff14968784bjeffhao *      http://www.apache.org/licenses/LICENSE-2.0
9725a957985171d712d5c048cc3d00ff14968784bjeffhao *
10725a957985171d712d5c048cc3d00ff14968784bjeffhao * Unless required by applicable law or agreed to in writing, software
11725a957985171d712d5c048cc3d00ff14968784bjeffhao * distributed under the License is distributed on an "AS IS" BASIS,
12725a957985171d712d5c048cc3d00ff14968784bjeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13725a957985171d712d5c048cc3d00ff14968784bjeffhao * See the License for the specific language governing permissions and
14725a957985171d712d5c048cc3d00ff14968784bjeffhao * limitations under the License.
15725a957985171d712d5c048cc3d00ff14968784bjeffhao */
16725a957985171d712d5c048cc3d00ff14968784bjeffhao
1762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "callee_save_frame.h"
186f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers#include "entrypoints/runtime_asm_entrypoints.h"
19725a957985171d712d5c048cc3d00ff14968784bjeffhao#include "instrumentation.h"
20ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h"
2162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "mirror/object-inl.h"
22725a957985171d712d5c048cc3d00ff14968784bjeffhao#include "runtime.h"
2304d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers#include "thread-inl.h"
24725a957985171d712d5c048cc3d00ff14968784bjeffhao
25725a957985171d712d5c048cc3d00ff14968784bjeffhaonamespace art {
26725a957985171d712d5c048cc3d00ff14968784bjeffhao
27ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromextern "C" const void* artInstrumentationMethodEntryFromCode(mirror::ArtMethod* method,
2862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                                             mirror::Object* this_object,
292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                             Thread* self,
302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                             uintptr_t lr)
31306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
321d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers  ScopedQuickEntrypointChecks sqec(self);
3362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
34320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz  const void* result;
35320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz  if (instrumentation->IsDeoptimized(method)) {
36320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz    result = GetQuickToInterpreterBridge();
37320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz  } else {
38a7dd0386f35c0ba4aef3f5b16bc84c6f4e2fc702Mathieu Chartier    result = instrumentation->GetQuickCodeFor(method, sizeof(void*));
398315ee03dbee3c48881191b3aedb108d1b626c0bSebastien Hertz    DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge(result));
40320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz  }
41848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  bool interpreter_entry = (result == GetQuickToInterpreterBridge());
42320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz  instrumentation->PushInstrumentationStackFrame(self, method->IsStatic() ? nullptr : this_object,
439a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao                                                 method, lr, interpreter_entry);
442cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  CHECK(result != nullptr) << PrettyMethod(method);
4562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  return result;
46725a957985171d712d5c048cc3d00ff14968784bjeffhao}
47725a957985171d712d5c048cc3d00ff14968784bjeffhao
48d58342caa97108ba413bad467c285c0377f138f5Andreas Gampeextern "C" TwoWordReturn artInstrumentationMethodExitFromCode(Thread* self,
49d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe                                                              StackReference<mirror::ArtMethod>* sp,
50d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe                                                              uint64_t gpr_result,
51d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe                                                              uint64_t fpr_result)
52306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
531d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers  // Compute address of return PC and sanity check that it currently holds 0.
54c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers  size_t return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, Runtime::kRefsOnly);
5513735955f39b3b304c37d2b2840663c131262c18Ian Rogers  uintptr_t* return_pc = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) +
564c1c510bea6f20f4d8b09e15547cd2967ad51c88Vladimir Marko                                                      return_pc_offset);
574274889d48ef82369bf2c1ca70d84689b4f9e93aBrian Carlstrom  CHECK_EQ(*return_pc, 0U);
581d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers
591d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers  // Pop the frame filling in the return pc. The low half of the return value is 0 when
601d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers  // deoptimization shouldn't be performed with the high-half having the return address. When
611d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers  // deoptimization should be performed the low half is zero and the high-half the address of the
621d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers  // deoptimization entry point.
6362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
64d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe  TwoWordReturn return_or_deoptimize_pc = instrumentation->PopInstrumentationStackFrame(
65d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe      self, return_pc, gpr_result, fpr_result);
6662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  return return_or_deoptimize_pc;
67725a957985171d712d5c048cc3d00ff14968784bjeffhao}
68725a957985171d712d5c048cc3d00ff14968784bjeffhao
69725a957985171d712d5c048cc3d00ff14968784bjeffhao}  // namespace art
70