Home | History | Annotate | Download | only in quick
      1 /*
      2  * Copyright (C) 2012 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 #ifndef ART_RUNTIME_ENTRYPOINTS_QUICK_CALLEE_SAVE_FRAME_H_
     18 #define ART_RUNTIME_ENTRYPOINTS_QUICK_CALLEE_SAVE_FRAME_H_
     19 
     20 #include "base/mutex.h"
     21 #include "instruction_set.h"
     22 #include "thread-inl.h"
     23 
     24 // Specific frame size code is in architecture-specific files. We include this to compile-time
     25 // specialize the code.
     26 #include "arch/arm/quick_method_frame_info_arm.h"
     27 #include "arch/arm64/quick_method_frame_info_arm64.h"
     28 #include "arch/mips/quick_method_frame_info_mips.h"
     29 #include "arch/x86/quick_method_frame_info_x86.h"
     30 #include "arch/x86_64/quick_method_frame_info_x86_64.h"
     31 
     32 namespace art {
     33 namespace mirror {
     34 class ArtMethod;
     35 }  // namespace mirror
     36 
     37 // Place a special frame at the TOS that will save the callee saves for the given type.
     38 static inline void FinishCalleeSaveFrameSetup(Thread* self, StackReference<mirror::ArtMethod>* sp,
     39                                               Runtime::CalleeSaveType type)
     40     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     41   // Be aware the store below may well stomp on an incoming argument.
     42   Locks::mutator_lock_->AssertSharedHeld(self);
     43   sp->Assign(Runtime::Current()->GetCalleeSaveMethod(type));
     44   self->SetTopOfStack(sp, 0);
     45   self->VerifyStack();
     46 }
     47 
     48 static constexpr size_t GetCalleeSaveFrameSize(InstructionSet isa, Runtime::CalleeSaveType type) {
     49   // constexpr must be a return statement.
     50   return (isa == kArm || isa == kThumb2) ? arm::ArmCalleeSaveFrameSize(type) :
     51          isa == kArm64 ? arm64::Arm64CalleeSaveFrameSize(type) :
     52          isa == kMips ? mips::MipsCalleeSaveFrameSize(type) :
     53          isa == kX86 ? x86::X86CalleeSaveFrameSize(type) :
     54          isa == kX86_64 ? x86_64::X86_64CalleeSaveFrameSize(type) :
     55          isa == kNone ? (LOG(FATAL) << "kNone has no frame size", 0) :
     56          (LOG(FATAL) << "Unknown instruction set" << isa, 0);
     57 }
     58 
     59 // Note: this specialized statement is sanity-checked in the quick-trampoline gtest.
     60 static constexpr size_t GetConstExprPointerSize(InstructionSet isa) {
     61   // constexpr must be a return statement.
     62   return (isa == kArm || isa == kThumb2) ? kArmPointerSize :
     63          isa == kArm64 ? kArm64PointerSize :
     64          isa == kMips ? kMipsPointerSize :
     65          isa == kX86 ? kX86PointerSize :
     66          isa == kX86_64 ? kX86_64PointerSize :
     67          isa == kNone ? (LOG(FATAL) << "kNone has no pointer size", 0) :
     68          (LOG(FATAL) << "Unknown instruction set" << isa, 0);
     69 }
     70 
     71 // Note: this specialized statement is sanity-checked in the quick-trampoline gtest.
     72 static constexpr size_t GetCalleeSavePCOffset(InstructionSet isa, Runtime::CalleeSaveType type) {
     73   return GetCalleeSaveFrameSize(isa, type) - GetConstExprPointerSize(isa);
     74 }
     75 
     76 }  // namespace art
     77 
     78 #endif  // ART_RUNTIME_ENTRYPOINTS_QUICK_CALLEE_SAVE_FRAME_H_
     79