diff options
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 124 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.h | 9 | ||||
-rw-r--r-- | compiler/optimizing/intrinsics_arm.cc | 34 | ||||
-rw-r--r-- | runtime/class_linker_test.cc | 8 | ||||
-rw-r--r-- | runtime/mirror/abstract_method.h | 4 | ||||
-rw-r--r-- | runtime/mirror/class.h | 2 | ||||
-rw-r--r-- | runtime/mirror/executable.h | 43 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_AbstractMethod.cc | 33 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_Constructor.cc | 63 | ||||
-rw-r--r-- | runtime/native/java_lang_reflect_Method.cc | 24 |
10 files changed, 137 insertions, 207 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 4ea17a9271..d8866a92c1 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -74,8 +74,10 @@ class NullCheckSlowPathARM : public SlowPathCode { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - arm_codegen->InvokeRuntime( - QUICK_ENTRY_POINT(pThrowNullPointer), instruction_, instruction_->GetDexPc(), this); + arm_codegen->InvokeRuntime(kQuickThrowNullPointer, + instruction_, + instruction_->GetDexPc(), + this); CheckEntrypointTypes<kQuickThrowNullPointer, void, void>(); } @@ -98,8 +100,7 @@ class DivZeroCheckSlowPathARM : public SlowPathCode { // Live registers will be restored in the catch block if caught. SaveLiveRegisters(codegen, instruction_->GetLocations()); } - arm_codegen->InvokeRuntime( - QUICK_ENTRY_POINT(pThrowDivZero), instruction_, instruction_->GetDexPc(), this); + arm_codegen->InvokeRuntime(kQuickThrowDivZero, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowDivZero, void, void>(); } @@ -119,8 +120,7 @@ class SuspendCheckSlowPathARM : public SlowPathCode { void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); __ Bind(GetEntryLabel()); - arm_codegen->InvokeRuntime( - QUICK_ENTRY_POINT(pTestSuspend), instruction_, instruction_->GetDexPc(), this); + arm_codegen->InvokeRuntime(kQuickTestSuspend, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickTestSuspend, void, void>(); if (successor_ == nullptr) { __ b(GetReturnLabel()); @@ -174,10 +174,10 @@ class BoundsCheckSlowPathARM : public SlowPathCode { locations->InAt(1), Location::RegisterLocation(calling_convention.GetRegisterAt(1)), Primitive::kPrimInt); - uint32_t entry_point_offset = instruction_->AsBoundsCheck()->IsStringCharAt() - ? QUICK_ENTRY_POINT(pThrowStringBounds) - : QUICK_ENTRY_POINT(pThrowArrayBounds); - arm_codegen->InvokeRuntime(entry_point_offset, instruction_, instruction_->GetDexPc(), this); + QuickEntrypointEnum entrypoint = instruction_->AsBoundsCheck()->IsStringCharAt() + ? kQuickThrowStringBounds + : kQuickThrowArrayBounds; + arm_codegen->InvokeRuntime(entrypoint, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickThrowStringBounds, void, int32_t, int32_t>(); CheckEntrypointTypes<kQuickThrowArrayBounds, void, int32_t, int32_t>(); } @@ -209,10 +209,9 @@ class LoadClassSlowPathARM : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; __ LoadImmediate(calling_convention.GetRegisterAt(0), cls_->GetTypeIndex()); - int32_t entry_point_offset = do_clinit_ - ? QUICK_ENTRY_POINT(pInitializeStaticStorage) - : QUICK_ENTRY_POINT(pInitializeType); - arm_codegen->InvokeRuntime(entry_point_offset, at_, dex_pc_, this); + QuickEntrypointEnum entrypoint = do_clinit_ ? kQuickInitializeStaticStorage + : kQuickInitializeType; + arm_codegen->InvokeRuntime(entrypoint, at_, dex_pc_, this); if (do_clinit_) { CheckEntrypointTypes<kQuickInitializeStaticStorage, void*, uint32_t>(); } else { @@ -263,8 +262,7 @@ class LoadStringSlowPathARM : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; const uint32_t string_index = instruction_->AsLoadString()->GetStringIndex(); __ LoadImmediate(calling_convention.GetRegisterAt(0), string_index); - arm_codegen->InvokeRuntime( - QUICK_ENTRY_POINT(pResolveString), instruction_, instruction_->GetDexPc(), this); + arm_codegen->InvokeRuntime(kQuickResolveString, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickResolveString, void*, uint32_t>(); arm_codegen->Move32(locations->Out(), Location::RegisterLocation(R0)); @@ -309,7 +307,7 @@ class TypeCheckSlowPathARM : public SlowPathCode { Primitive::kPrimNot); if (instruction_->IsInstanceOf()) { - arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial), + arm_codegen->InvokeRuntime(kQuickInstanceofNonTrivial, instruction_, instruction_->GetDexPc(), this); @@ -318,10 +316,7 @@ class TypeCheckSlowPathARM : public SlowPathCode { arm_codegen->Move32(locations->Out(), Location::RegisterLocation(R0)); } else { DCHECK(instruction_->IsCheckCast()); - arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast), - instruction_, - instruction_->GetDexPc(), - this); + arm_codegen->InvokeRuntime(kQuickCheckCast, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickCheckCast, void, const mirror::Class*, const mirror::Class*>(); } @@ -350,10 +345,7 @@ class DeoptimizationSlowPathARM : public SlowPathCode { CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); __ Bind(GetEntryLabel()); SaveLiveRegisters(codegen, instruction_->GetLocations()); - arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pDeoptimize), - instruction_, - instruction_->GetDexPc(), - this); + arm_codegen->InvokeRuntime(kQuickDeoptimize, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickDeoptimize, void, void>(); } @@ -392,10 +384,7 @@ class ArraySetSlowPathARM : public SlowPathCode { codegen->GetMoveResolver()->EmitNativeCode(¶llel_move); CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); - arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject), - instruction_, - instruction_->GetDexPc(), - this); + arm_codegen->InvokeRuntime(kQuickAputObject, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes<kQuickAputObject, void, mirror::Array*, int32_t, mirror::Object*>(); RestoreLiveRegisters(codegen, locations); __ b(GetExitLabel()); @@ -613,10 +602,7 @@ class ReadBarrierForHeapReferenceSlowPathARM : public SlowPathCode { codegen->GetMoveResolver()->EmitNativeCode(¶llel_move); __ LoadImmediate(calling_convention.GetRegisterAt(2), offset_); } - arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierSlow), - instruction_, - instruction_->GetDexPc(), - this); + arm_codegen->InvokeRuntime(kQuickReadBarrierSlow, instruction_, instruction_->GetDexPc(), this); CheckEntrypointTypes< kQuickReadBarrierSlow, mirror::Object*, mirror::Object*, mirror::Object*, uint32_t>(); arm_codegen->Move32(out_, Location::RegisterLocation(R0)); @@ -680,7 +666,7 @@ class ReadBarrierForRootSlowPathARM : public SlowPathCode { InvokeRuntimeCallingConvention calling_convention; CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); arm_codegen->Move32(Location::RegisterLocation(calling_convention.GetRegisterAt(0)), root_); - arm_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pReadBarrierForRootSlow), + arm_codegen->InvokeRuntime(kQuickReadBarrierForRootSlow, instruction_, instruction_->GetDexPc(), this); @@ -1221,19 +1207,8 @@ void CodeGeneratorARM::InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, SlowPathCode* slow_path) { - InvokeRuntime(GetThreadOffset<kArmPointerSize>(entrypoint).Int32Value(), - instruction, - dex_pc, - slow_path); -} - -void CodeGeneratorARM::InvokeRuntime(int32_t entry_point_offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path) { ValidateInvokeRuntime(instruction, slow_path); - __ LoadFromOffset(kLoadWord, LR, TR, entry_point_offset); - __ blx(LR); + GenerateInvokeRuntime(GetThreadOffset<kArmPointerSize>(entrypoint).Int32Value()); RecordPcInfo(instruction, dex_pc, slow_path); } @@ -1241,6 +1216,10 @@ void CodeGeneratorARM::InvokeRuntimeWithoutRecordingPcInfo(int32_t entry_point_o HInstruction* instruction, SlowPathCode* slow_path) { ValidateInvokeRuntimeWithoutRecordingPcInfo(instruction, slow_path); + GenerateInvokeRuntime(entry_point_offset); +} + +void CodeGeneratorARM::GenerateInvokeRuntime(int32_t entry_point_offset) { __ LoadFromOffset(kLoadWord, LR, TR, entry_point_offset); __ blx(LR); } @@ -2374,19 +2353,13 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimFloat: // Processing a Dex `float-to-long' instruction. - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pF2l), - conversion, - conversion->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickF2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickF2l, int64_t, float>(); break; case Primitive::kPrimDouble: // Processing a Dex `double-to-long' instruction. - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pD2l), - conversion, - conversion->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickD2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickD2l, int64_t, double>(); break; @@ -2433,10 +2406,7 @@ void InstructionCodeGeneratorARM::VisitTypeConversion(HTypeConversion* conversio case Primitive::kPrimLong: // Processing a Dex `long-to-float' instruction. - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pL2f), - conversion, - conversion->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickL2f, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickL2f, float, int64_t>(); break; @@ -2968,7 +2938,7 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) { DCHECK_EQ(calling_convention.GetRegisterAt(1), second.AsRegister<Register>()); DCHECK_EQ(R0, out.AsRegister<Register>()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pIdivmod), div, div->GetDexPc(), nullptr); + codegen_->InvokeRuntime(kQuickIdivmod, div, div->GetDexPc()); CheckEntrypointTypes<kQuickIdivmod, int32_t, int32_t, int32_t>(); } break; @@ -2983,7 +2953,7 @@ void InstructionCodeGeneratorARM::VisitDiv(HDiv* div) { DCHECK_EQ(R0, out.AsRegisterPairLow<Register>()); DCHECK_EQ(R1, out.AsRegisterPairHigh<Register>()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLdiv), div, div->GetDexPc(), nullptr); + codegen_->InvokeRuntime(kQuickLdiv, div, div->GetDexPc()); CheckEntrypointTypes<kQuickLdiv, int64_t, int64_t, int64_t>(); break; } @@ -3112,26 +3082,26 @@ void InstructionCodeGeneratorARM::VisitRem(HRem* rem) { DCHECK_EQ(calling_convention.GetRegisterAt(1), second.AsRegister<Register>()); DCHECK_EQ(R1, out.AsRegister<Register>()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pIdivmod), rem, rem->GetDexPc(), nullptr); + codegen_->InvokeRuntime(kQuickIdivmod, rem, rem->GetDexPc()); CheckEntrypointTypes<kQuickIdivmod, int32_t, int32_t, int32_t>(); } break; } case Primitive::kPrimLong: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLmod), rem, rem->GetDexPc(), nullptr); + codegen_->InvokeRuntime(kQuickLmod, rem, rem->GetDexPc()); CheckEntrypointTypes<kQuickLmod, int64_t, int64_t, int64_t>(); break; } case Primitive::kPrimFloat: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmodf), rem, rem->GetDexPc(), nullptr); + codegen_->InvokeRuntime(kQuickFmodf, rem, rem->GetDexPc()); CheckEntrypointTypes<kQuickFmodf, float, float, float>(); break; } case Primitive::kPrimDouble: { - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pFmod), rem, rem->GetDexPc(), nullptr); + codegen_->InvokeRuntime(kQuickFmod, rem, rem->GetDexPc()); CheckEntrypointTypes<kQuickFmod, double, double, double>(); break; } @@ -3571,10 +3541,7 @@ void InstructionCodeGeneratorARM::VisitNewInstance(HNewInstance* instruction) { __ blx(LR); codegen_->RecordPcInfo(instruction, instruction->GetDexPc()); } else { - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocObjectWithAccessCheck, void*, uint32_t, ArtMethod*>(); } } @@ -3594,10 +3561,7 @@ void InstructionCodeGeneratorARM::VisitNewArray(HNewArray* instruction) { __ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex()); // Note: if heap poisoning is enabled, the entry point takes cares // of poisoning the reference. - codegen_->InvokeRuntime(instruction->GetEntrypoint(), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayWithAccessCheck, void*, uint32_t, int32_t, ArtMethod*>(); } @@ -5432,10 +5396,7 @@ void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) { LocationSummary* locations = cls->GetLocations(); if (cls->NeedsAccessCheck()) { codegen_->MoveConstant(locations->GetTemp(0), cls->GetTypeIndex()); - codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pInitializeTypeAndVerifyAccess), - cls, - cls->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(kQuickInitializeTypeAndVerifyAccess, cls, cls->GetDexPc()); CheckEntrypointTypes<kQuickInitializeTypeAndVerifyAccess, void*, uint32_t>(); return; } @@ -5694,8 +5655,7 @@ void LocationsBuilderARM::VisitThrow(HThrow* instruction) { } void InstructionCodeGeneratorARM::VisitThrow(HThrow* instruction) { - codegen_->InvokeRuntime( - QUICK_ENTRY_POINT(pDeliverException), instruction, instruction->GetDexPc(), nullptr); + codegen_->InvokeRuntime(kQuickDeliverException, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickDeliverException, void, mirror::Object*>(); } @@ -6095,11 +6055,9 @@ void LocationsBuilderARM::VisitMonitorOperation(HMonitorOperation* instruction) } void InstructionCodeGeneratorARM::VisitMonitorOperation(HMonitorOperation* instruction) { - codegen_->InvokeRuntime(instruction->IsEnter() - ? QUICK_ENTRY_POINT(pLockObject) : QUICK_ENTRY_POINT(pUnlockObject), - instruction, - instruction->GetDexPc(), - nullptr); + codegen_->InvokeRuntime(instruction->IsEnter() ? kQuickLockObject : kQuickUnlockObject, + instruction, + instruction->GetDexPc()); if (instruction->IsEnter()) { CheckEntrypointTypes<kQuickLockObject, void, mirror::Object*>(); } else { diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index 5d9b2dce1c..a07dd6b5ef 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -390,12 +390,7 @@ class CodeGeneratorARM : public CodeGenerator { void InvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, uint32_t dex_pc, - SlowPathCode* slow_path) OVERRIDE; - - void InvokeRuntime(int32_t offset, - HInstruction* instruction, - uint32_t dex_pc, - SlowPathCode* slow_path); + SlowPathCode* slow_path = nullptr) OVERRIDE; // Generate code to invoke a runtime entry point, but do not record // PC-related information in a stack map. @@ -403,6 +398,8 @@ class CodeGeneratorARM : public CodeGenerator { HInstruction* instruction, SlowPathCode* slow_path); + void GenerateInvokeRuntime(int32_t entry_point_offset); + // Emit a write barrier. void MarkGCCard(Register temp, Register card, Register object, Register value, bool can_be_null); diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc index df7cb85a4c..a1fc7c3b84 100644 --- a/compiler/optimizing/intrinsics_arm.cc +++ b/compiler/optimizing/intrinsics_arm.cc @@ -1291,10 +1291,8 @@ static void GenerateVisitStringIndexOf(HInvoke* invoke, __ LoadImmediate(tmp_reg, 0); } - __ LoadFromOffset(kLoadWord, LR, TR, - QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pIndexOf).Int32Value()); + codegen->InvokeRuntime(kQuickIndexOf, invoke, invoke->GetDexPc(), slow_path); CheckEntrypointTypes<kQuickIndexOf, int32_t, void*, uint32_t, uint32_t>(); - __ blx(LR); if (slow_path != nullptr) { __ Bind(slow_path->GetExitLabel()); @@ -1361,13 +1359,8 @@ void IntrinsicCodeGeneratorARM::VisitStringNewStringFromBytes(HInvoke* invoke) { codegen_->AddSlowPath(slow_path); __ b(slow_path->GetEntryLabel(), EQ); - __ LoadFromOffset(kLoadWord, - LR, - TR, - QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pAllocStringFromBytes).Int32Value()); + codegen_->InvokeRuntime(kQuickAllocStringFromBytes, invoke, invoke->GetDexPc(), slow_path); CheckEntrypointTypes<kQuickAllocStringFromBytes, void*, void*, int32_t, int32_t, int32_t>(); - __ blx(LR); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); __ Bind(slow_path->GetExitLabel()); } @@ -1383,21 +1376,14 @@ void IntrinsicLocationsBuilderARM::VisitStringNewStringFromChars(HInvoke* invoke } void IntrinsicCodeGeneratorARM::VisitStringNewStringFromChars(HInvoke* invoke) { - ArmAssembler* assembler = GetAssembler(); - // No need to emit code checking whether `locations->InAt(2)` is a null // pointer, as callers of the native method // // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) // // all include a null check on `data` before calling that method. - __ LoadFromOffset(kLoadWord, - LR, - TR, - QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pAllocStringFromChars).Int32Value()); + codegen_->InvokeRuntime(kQuickAllocStringFromChars, invoke, invoke->GetDexPc()); CheckEntrypointTypes<kQuickAllocStringFromChars, void*, int32_t, int32_t, void*>(); - __ blx(LR); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } void IntrinsicLocationsBuilderARM::VisitStringNewStringFromString(HInvoke* invoke) { @@ -1419,11 +1405,9 @@ void IntrinsicCodeGeneratorARM::VisitStringNewStringFromString(HInvoke* invoke) codegen_->AddSlowPath(slow_path); __ b(slow_path->GetEntryLabel(), EQ); - __ LoadFromOffset(kLoadWord, - LR, TR, QUICK_ENTRYPOINT_OFFSET(kArmPointerSize, pAllocStringFromString).Int32Value()); + codegen_->InvokeRuntime(kQuickAllocStringFromString, invoke, invoke->GetDexPc(), slow_path); CheckEntrypointTypes<kQuickAllocStringFromString, void*, void*>(); - __ blx(LR); - codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); + __ Bind(slow_path->GetExitLabel()); } @@ -1999,13 +1983,11 @@ static void GenFPToFPCall(HInvoke* invoke, DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(0))); DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(1))); - __ LoadFromOffset(kLoadWord, LR, TR, GetThreadOffset<kArmPointerSize>(entry).Int32Value()); // Native code uses the soft float ABI. __ vmovrrd(calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1), FromLowSToD(locations->InAt(0).AsFpuRegisterPairLow<SRegister>())); - __ blx(LR); - codegen->RecordPcInfo(invoke, invoke->GetDexPc()); + codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc()); __ vmovdrr(FromLowSToD(locations->Out().AsFpuRegisterPairLow<SRegister>()), calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1)); @@ -2025,7 +2007,6 @@ static void GenFPFPToFPCall(HInvoke* invoke, DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(2))); DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(calling_convention.GetRegisterAt(3))); - __ LoadFromOffset(kLoadWord, LR, TR, GetThreadOffset<kArmPointerSize>(entry).Int32Value()); // Native code uses the soft float ABI. __ vmovrrd(calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1), @@ -2033,8 +2014,7 @@ static void GenFPFPToFPCall(HInvoke* invoke, __ vmovrrd(calling_convention.GetRegisterAt(2), calling_convention.GetRegisterAt(3), FromLowSToD(locations->InAt(1).AsFpuRegisterPairLow<SRegister>())); - __ blx(LR); - codegen->RecordPcInfo(invoke, invoke->GetDexPc()); + codegen->InvokeRuntime(entry, invoke, invoke->GetDexPc()); __ vmovdrr(FromLowSToD(locations->Out().AsFpuRegisterPairLow<SRegister>()), calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1)); diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 7999aeff84..5f225bea78 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -32,6 +32,7 @@ #include "mirror/accessible_object.h" #include "mirror/class-inl.h" #include "mirror/dex_cache.h" +#include "mirror/executable.h" #include "mirror/field.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" @@ -691,6 +692,12 @@ struct FieldOffsets : public CheckOffsets<mirror::Field> { }; }; +struct ExecutableOffsets : public CheckOffsets<mirror::Executable> { + ExecutableOffsets() : CheckOffsets<mirror::Executable>( + false, "Ljava/lang/reflect/Executable;") { + }; +}; + struct AbstractMethodOffsets : public CheckOffsets<mirror::AbstractMethod> { AbstractMethodOffsets() : CheckOffsets<mirror::AbstractMethod>( false, "Ljava/lang/reflect/AbstractMethod;") { @@ -720,6 +727,7 @@ TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) { EXPECT_TRUE(FinalizerReferenceOffsets().Check()); EXPECT_TRUE(AccessibleObjectOffsets().Check()); EXPECT_TRUE(FieldOffsets().Check()); + EXPECT_TRUE(ExecutableOffsets().Check()); EXPECT_TRUE(AbstractMethodOffsets().Check()); } diff --git a/runtime/mirror/abstract_method.h b/runtime/mirror/abstract_method.h index cfbe4926f4..4f714a6a13 100644 --- a/runtime/mirror/abstract_method.h +++ b/runtime/mirror/abstract_method.h @@ -17,7 +17,7 @@ #ifndef ART_RUNTIME_MIRROR_ABSTRACT_METHOD_H_ #define ART_RUNTIME_MIRROR_ABSTRACT_METHOD_H_ -#include "accessible_object.h" +#include "executable.h" #include "gc_root.h" #include "object.h" #include "object_callbacks.h" @@ -31,7 +31,7 @@ class ArtMethod; namespace mirror { // C++ mirror of java.lang.reflect.AbstractMethod. -class MANAGED AbstractMethod : public AccessibleObject { +class MANAGED AbstractMethod : public Executable { public: // Called from Constructor::CreateFromArtMethod, Method::CreateFromArtMethod. template <PointerSize kPointerSize, bool kTransactionActive> diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index e2cd649d99..21af15ed33 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -571,7 +571,7 @@ class MANAGED Class FINAL : public Object { // The size of java.lang.Class.class. static uint32_t ClassClassSize(PointerSize pointer_size) { // The number of vtable entries in java.lang.Class. - uint32_t vtable_entries = Object::kVTableLength + 70; + uint32_t vtable_entries = Object::kVTableLength + 71; return ComputeClassSize(true, vtable_entries, 0, 0, 4, 1, 0, pointer_size); } diff --git a/runtime/mirror/executable.h b/runtime/mirror/executable.h new file mode 100644 index 0000000000..87866579f5 --- /dev/null +++ b/runtime/mirror/executable.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 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. + */ + +#ifndef ART_RUNTIME_MIRROR_EXECUTABLE_H_ +#define ART_RUNTIME_MIRROR_EXECUTABLE_H_ + +#include "accessible_object.h" +#include "gc_root.h" +#include "object.h" +#include "object_callbacks.h" +#include "read_barrier_option.h" + +namespace art { + +struct ExecutableOffsets; +class ArtMethod; + +namespace mirror { + +// C++ mirror of java.lang.reflect.Executable. +class MANAGED Executable : public AccessibleObject { + private: + friend struct art::ExecutableOffsets; // for verifying offset information + DISALLOW_IMPLICIT_CONSTRUCTORS(Executable); +}; + +} // namespace mirror +} // namespace art + +#endif // ART_RUNTIME_MIRROR_EXECUTABLE_H_ diff --git a/runtime/native/java_lang_reflect_AbstractMethod.cc b/runtime/native/java_lang_reflect_AbstractMethod.cc index 7e11c11438..33e0daef1f 100644 --- a/runtime/native/java_lang_reflect_AbstractMethod.cc +++ b/runtime/native/java_lang_reflect_AbstractMethod.cc @@ -41,6 +41,21 @@ static jobjectArray AbstractMethod_getDeclaredAnnotations(JNIEnv* env, jobject j return soa.AddLocalReference<jobjectArray>(method->GetDexFile()->GetAnnotationsForMethod(method)); } +static jobject AbstractMethod_getAnnotationNative(JNIEnv* env, + jobject javaMethod, + jclass annotationType) { + ScopedFastNativeObjectAccess soa(env); + StackHandleScope<1> hs(soa.Self()); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + if (method->IsProxyMethod()) { + return nullptr; + } else { + Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + return soa.AddLocalReference<jobject>( + method->GetDexFile()->GetAnnotationForMethod(method, klass)); + } +} + static jobjectArray AbstractMethod_getSignatureAnnotation(JNIEnv* env, jobject javaMethod) { ScopedFastNativeObjectAccess soa(env); ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); @@ -53,7 +68,19 @@ static jobjectArray AbstractMethod_getSignatureAnnotation(JNIEnv* env, jobject j } -static jboolean AbstractMethod_isAnnotationPresentNative(JNIEnv* env, jobject javaMethod, +static jobjectArray AbstractMethod_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) { + ScopedFastNativeObjectAccess soa(env); + ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); + if (method->IsProxyMethod()) { + return nullptr; + } else { + return soa.AddLocalReference<jobjectArray>( + method->GetDexFile()->GetParameterAnnotations(method)); + } +} + +static jboolean AbstractMethod_isAnnotationPresentNative(JNIEnv* env, + jobject javaMethod, jclass annotationType) { ScopedFastNativeObjectAccess soa(env); ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); @@ -66,7 +93,11 @@ static jboolean AbstractMethod_isAnnotationPresentNative(JNIEnv* env, jobject ja } static JNINativeMethod gMethods[] = { + NATIVE_METHOD(AbstractMethod, getAnnotationNative, + "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"), NATIVE_METHOD(AbstractMethod, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"), + NATIVE_METHOD(AbstractMethod, getParameterAnnotationsNative, + "!()[[Ljava/lang/annotation/Annotation;"), NATIVE_METHOD(AbstractMethod, getSignatureAnnotation, "!()[Ljava/lang/String;"), NATIVE_METHOD(AbstractMethod, isAnnotationPresentNative, "!(Ljava/lang/Class;)Z"), }; diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc index dd46233cdb..f699d6bd75 100644 --- a/runtime/native/java_lang_reflect_Constructor.cc +++ b/runtime/native/java_lang_reflect_Constructor.cc @@ -30,39 +30,6 @@ namespace art { -static jobject Constructor_getAnnotationNative(JNIEnv* env, jobject javaMethod, - jclass annotationType) { - ScopedFastNativeObjectAccess soa(env); - StackHandleScope<1> hs(soa.Self()); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->IsProxyMethod()) { - return nullptr; - } else { - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); - return soa.AddLocalReference<jobject>( - method->GetDexFile()->GetAnnotationForMethod(method, klass)); - } -} - -static jobjectArray Constructor_getDeclaredAnnotations(JNIEnv* env, jobject javaMethod) { - ScopedFastNativeObjectAccess soa(env); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->IsProxyMethod()) { - mirror::Class* class_class = mirror::Class::GetJavaLangClass(); - mirror::Class* class_array_class = - Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class); - if (class_array_class == nullptr) { - return nullptr; - } - mirror::ObjectArray<mirror::Class>* empty_array = - mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0); - return soa.AddLocalReference<jobjectArray>(empty_array); - } else { - return soa.AddLocalReference<jobjectArray>( - method->GetDexFile()->GetAnnotationsForMethod(method)); - } -} - static jobjectArray Constructor_getExceptionTypes(JNIEnv* env, jobject javaMethod) { ScopedFastNativeObjectAccess soa(env); ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod) @@ -85,30 +52,6 @@ static jobjectArray Constructor_getExceptionTypes(JNIEnv* env, jobject javaMetho } } -static jobjectArray Constructor_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) { - ScopedFastNativeObjectAccess soa(env); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->IsProxyMethod()) { - return nullptr; - } else { - return soa.AddLocalReference<jobjectArray>( - method->GetDexFile()->GetParameterAnnotations(method)); - } -} - -static jboolean Constructor_isAnnotationPresentNative(JNIEnv* env, jobject javaMethod, - jclass annotationType) { - ScopedFastNativeObjectAccess soa(env); - StackHandleScope<1> hs(soa.Self()); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->IsProxyMethod()) { - // Proxies have no annotations. - return false; - } - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); - return method->GetDexFile()->IsMethodAnnotationPresent(method, klass); -} - /* * We can also safely assume the constructor isn't associated * with an interface, array, or primitive class. If this is coming from @@ -179,13 +122,7 @@ static jobject Constructor_newInstanceFromSerialization(JNIEnv* env, jclass unus } static JNINativeMethod gMethods[] = { - NATIVE_METHOD(Constructor, getAnnotationNative, - "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"), - NATIVE_METHOD(Constructor, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"), NATIVE_METHOD(Constructor, getExceptionTypes, "!()[Ljava/lang/Class;"), - NATIVE_METHOD(Constructor, getParameterAnnotationsNative, - "!()[[Ljava/lang/annotation/Annotation;"), - NATIVE_METHOD(Constructor, isAnnotationPresentNative, "!(Ljava/lang/Class;)Z"), NATIVE_METHOD(Constructor, newInstance0, "!([Ljava/lang/Object;)Ljava/lang/Object;"), NATIVE_METHOD(Constructor, newInstanceFromSerialization, "!(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;"), }; diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc index c3f2a274cc..3360f4170e 100644 --- a/runtime/native/java_lang_reflect_Method.cc +++ b/runtime/native/java_lang_reflect_Method.cc @@ -30,18 +30,6 @@ namespace art { -static jobject Method_getAnnotationNative(JNIEnv* env, jobject javaMethod, jclass annotationType) { - ScopedFastNativeObjectAccess soa(env); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->GetDeclaringClass()->IsProxyClass()) { - return nullptr; - } - StackHandleScope<1> hs(soa.Self()); - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); - return soa.AddLocalReference<jobject>( - method->GetDexFile()->GetAnnotationForMethod(method, klass)); -} - static jobject Method_getDefaultValue(JNIEnv* env, jobject javaMethod) { ScopedFastNativeObjectAccess soa(env); ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); @@ -88,15 +76,6 @@ static jobjectArray Method_getExceptionTypes(JNIEnv* env, jobject javaMethod) { } } -static jobjectArray Method_getParameterAnnotationsNative(JNIEnv* env, jobject javaMethod) { - ScopedFastNativeObjectAccess soa(env); - ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); - if (method->GetDeclaringClass()->IsProxyClass()) { - return nullptr; - } - return soa.AddLocalReference<jobjectArray>(method->GetDexFile()->GetParameterAnnotations(method)); -} - static jobject Method_invoke(JNIEnv* env, jobject javaMethod, jobject javaReceiver, jobject javaArgs) { ScopedFastNativeObjectAccess soa(env); @@ -104,11 +83,8 @@ static jobject Method_invoke(JNIEnv* env, jobject javaMethod, jobject javaReceiv } static JNINativeMethod gMethods[] = { - NATIVE_METHOD(Method, getAnnotationNative, - "!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"), NATIVE_METHOD(Method, getDefaultValue, "!()Ljava/lang/Object;"), NATIVE_METHOD(Method, getExceptionTypes, "!()[Ljava/lang/Class;"), - NATIVE_METHOD(Method, getParameterAnnotationsNative, "!()[[Ljava/lang/annotation/Annotation;"), NATIVE_METHOD(Method, invoke, "!(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"), }; |