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 17e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 1862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "callee_save_frame.h" 196f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers#include "entrypoints/runtime_asm_entrypoints.h" 20725a957985171d712d5c048cc3d00ff14968784bjeffhao#include "instrumentation.h" 2162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "mirror/object-inl.h" 22725a957985171d712d5c048cc3d00ff14968784bjeffhao#include "runtime.h" 2304d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers#include "thread-inl.h" 24725a957985171d712d5c048cc3d00ff14968784bjeffhao 25725a957985171d712d5c048cc3d00ff14968784bjeffhaonamespace art { 26725a957985171d712d5c048cc3d00ff14968784bjeffhao 27e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" const void* artInstrumentationMethodEntryFromCode(ArtMethod* method, 2862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Object* this_object, 292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Thread* self, 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uintptr_t lr) 3190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 323b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe // Instrumentation changes the stack. Thus, when exiting, the stack cannot be verified, so skip 333b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe // that part. 343b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe ScopedQuickEntrypointChecks sqec(self, kIsDebugBuild, false); 3562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 36320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz const void* result; 37320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz if (instrumentation->IsDeoptimized(method)) { 38320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz result = GetQuickToInterpreterBridge(); 39320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz } else { 40a7dd0386f35c0ba4aef3f5b16bc84c6f4e2fc702Mathieu Chartier result = instrumentation->GetQuickCodeFor(method, sizeof(void*)); 418315ee03dbee3c48881191b3aedb108d1b626c0bSebastien Hertz DCHECK(!Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge(result)); 42320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz } 43848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers bool interpreter_entry = (result == GetQuickToInterpreterBridge()); 44320deb2ebe5cce96ca2779875c82853182326685Sebastien Hertz instrumentation->PushInstrumentationStackFrame(self, method->IsStatic() ? nullptr : this_object, 459a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao method, lr, interpreter_entry); 462cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(result != nullptr) << PrettyMethod(method); 4762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return result; 48725a957985171d712d5c048cc3d00ff14968784bjeffhao} 49725a957985171d712d5c048cc3d00ff14968784bjeffhao 50e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierextern "C" TwoWordReturn artInstrumentationMethodExitFromCode(Thread* self, ArtMethod** sp, 51d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe uint64_t gpr_result, 52d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe uint64_t fpr_result) 5390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 540747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz // Instrumentation exit stub must not be entered with a pending exception. 550747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz CHECK(!self->IsExceptionPending()) << "Enter instrumentation exit stub with pending exception " 560747466fca310eedea5fc49e37d54f240a0b3c0fSebastien Hertz << self->GetException()->Dump(); 571d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Compute address of return PC and sanity check that it currently holds 0. 58c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers size_t return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, Runtime::kRefsOnly); 5913735955f39b3b304c37d2b2840663c131262c18Ian Rogers uintptr_t* return_pc = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) + 604c1c510bea6f20f4d8b09e15547cd2967ad51c88Vladimir Marko return_pc_offset); 614274889d48ef82369bf2c1ca70d84689b4f9e93aBrian Carlstrom CHECK_EQ(*return_pc, 0U); 621d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers 631d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // Pop the frame filling in the return pc. The low half of the return value is 0 when 641d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // deoptimization shouldn't be performed with the high-half having the return address. When 651d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // deoptimization should be performed the low half is zero and the high-half the address of the 661d8cdbc5202378a5f1a4b3a1fba610675ed4dcd5Ian Rogers // deoptimization entry point. 6762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 68d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe TwoWordReturn return_or_deoptimize_pc = instrumentation->PopInstrumentationStackFrame( 69d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe self, return_pc, gpr_result, fpr_result); 7062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return return_or_deoptimize_pc; 71725a957985171d712d5c048cc3d00ff14968784bjeffhao} 72725a957985171d712d5c048cc3d00ff14968784bjeffhao 73725a957985171d712d5c048cc3d00ff14968784bjeffhao} // namespace art 74