diff options
author | 2013-07-12 13:46:57 -0700 | |
---|---|---|
committer | 2013-07-12 17:49:01 -0700 | |
commit | 7940e44f4517de5e2634a7e07d58d0fb26160513 (patch) | |
tree | ac90242d96229a6942f6e24ab137bc1f8f2e0025 /compiler/jni/quick/calling_convention.cc | |
parent | 5cd9e3b122f276f610980cbaf0d2ad6ed4cd9088 (diff) |
Create separate Android.mk for main build targets
The runtime, compiler, dex2oat, and oatdump now are in seperate trees
to prevent dependency creep. They can now be individually built
without rebuilding the rest of the art projects. dalvikvm and jdwpspy
were already this way. Builds in the art directory should behave as
before, building everything including tests.
Change-Id: Ic6b1151e5ed0f823c3dd301afd2b13eb2d8feb81
Diffstat (limited to 'compiler/jni/quick/calling_convention.cc')
-rw-r--r-- | compiler/jni/quick/calling_convention.cc | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/compiler/jni/quick/calling_convention.cc b/compiler/jni/quick/calling_convention.cc new file mode 100644 index 0000000000..5d5eaf2ea9 --- /dev/null +++ b/compiler/jni/quick/calling_convention.cc @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "calling_convention.h" + +#include "base/logging.h" +#include "jni/quick/arm/calling_convention_arm.h" +#include "jni/quick/mips/calling_convention_mips.h" +#include "jni/quick/x86/calling_convention_x86.h" +#include "utils.h" + +namespace art { + +// Offset of Method within the frame +FrameOffset CallingConvention::MethodStackOffset() { + return displacement_; +} + +// Managed runtime calling convention + +ManagedRuntimeCallingConvention* ManagedRuntimeCallingConvention::Create( + bool is_static, bool is_synchronized, const char* shorty, InstructionSet instruction_set) { + switch (instruction_set) { + case kArm: + case kThumb2: + return new arm::ArmManagedRuntimeCallingConvention(is_static, is_synchronized, shorty); + case kMips: + return new mips::MipsManagedRuntimeCallingConvention(is_static, is_synchronized, shorty); + case kX86: + return new x86::X86ManagedRuntimeCallingConvention(is_static, is_synchronized, shorty); + default: + LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; + return NULL; + } +} + +bool ManagedRuntimeCallingConvention::HasNext() { + return itr_args_ < NumArgs(); +} + +void ManagedRuntimeCallingConvention::Next() { + CHECK(HasNext()); + if (IsCurrentArgExplicit() && // don't query parameter type of implicit args + IsParamALongOrDouble(itr_args_)) { + itr_longs_and_doubles_++; + itr_slots_++; + } + if (IsCurrentParamAReference()) { + itr_refs_++; + } + itr_args_++; + itr_slots_++; +} + +bool ManagedRuntimeCallingConvention::IsCurrentArgExplicit() { + // Static methods have no implicit arguments, others implicitly pass this + return IsStatic() || (itr_args_ != 0); +} + +bool ManagedRuntimeCallingConvention::IsCurrentArgPossiblyNull() { + return IsCurrentArgExplicit(); // any user parameter may be null +} + +size_t ManagedRuntimeCallingConvention::CurrentParamSize() { + return ParamSize(itr_args_); +} + +bool ManagedRuntimeCallingConvention::IsCurrentParamAReference() { + return IsParamAReference(itr_args_); +} + +// JNI calling convention + +JniCallingConvention* JniCallingConvention::Create(bool is_static, bool is_synchronized, + const char* shorty, + InstructionSet instruction_set) { + switch (instruction_set) { + case kArm: + case kThumb2: + return new arm::ArmJniCallingConvention(is_static, is_synchronized, shorty); + case kMips: + return new mips::MipsJniCallingConvention(is_static, is_synchronized, shorty); + case kX86: + return new x86::X86JniCallingConvention(is_static, is_synchronized, shorty); + default: + LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; + return NULL; + } +} + +size_t JniCallingConvention::ReferenceCount() const { + return NumReferenceArgs() + (IsStatic() ? 1 : 0); +} + +FrameOffset JniCallingConvention::SavedLocalReferenceCookieOffset() const { + size_t start_of_sirt = SirtLinkOffset().Int32Value() + kPointerSize; + size_t references_size = kPointerSize * ReferenceCount(); // size excluding header + return FrameOffset(start_of_sirt + references_size); +} + +FrameOffset JniCallingConvention::ReturnValueSaveLocation() const { + // Segment state is 4 bytes long + return FrameOffset(SavedLocalReferenceCookieOffset().Int32Value() + 4); +} + +bool JniCallingConvention::HasNext() { + if (itr_args_ <= kObjectOrClass) { + return true; + } else { + unsigned int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(); + return arg_pos < NumArgs(); + } +} + +void JniCallingConvention::Next() { + CHECK(HasNext()); + if (itr_args_ > kObjectOrClass) { + int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(); + if (IsParamALongOrDouble(arg_pos)) { + itr_longs_and_doubles_++; + itr_slots_++; + } + } + if (IsCurrentParamAReference()) { + itr_refs_++; + } + itr_args_++; + itr_slots_++; +} + +bool JniCallingConvention::IsCurrentParamAReference() { + switch (itr_args_) { + case kJniEnv: + return false; // JNIEnv* + case kObjectOrClass: + return true; // jobject or jclass + default: { + int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(); + return IsParamAReference(arg_pos); + } + } +} + +// Return position of SIRT entry holding reference at the current iterator +// position +FrameOffset JniCallingConvention::CurrentParamSirtEntryOffset() { + CHECK(IsCurrentParamAReference()); + CHECK_GT(SirtLinkOffset(), SirtNumRefsOffset()); + // Address of 1st SIRT entry + int result = SirtLinkOffset().Int32Value() + kPointerSize; + result += itr_refs_ * kPointerSize; + CHECK_GT(result, SirtLinkOffset().Int32Value()); + return FrameOffset(result); +} + +size_t JniCallingConvention::CurrentParamSize() { + if (itr_args_ <= kObjectOrClass) { + return kPointerSize; // JNIEnv or jobject/jclass + } else { + int arg_pos = itr_args_ - NumberOfExtraArgumentsForJni(); + return ParamSize(arg_pos); + } +} + +size_t JniCallingConvention::NumberOfExtraArgumentsForJni() { + // The first argument is the JNIEnv*. + // Static methods have an extra argument which is the jclass. + return IsStatic() ? 2 : 1; +} + +} // namespace art |