diff options
author | 2017-01-11 18:58:15 +0000 | |
---|---|---|
committer | 2017-01-11 19:17:33 +0000 | |
commit | 0fb5af1c8287b1ec85c55c306a1c43820c38a337 (patch) | |
tree | 66239e7f745fae54e1630e91fb44a859bff615d6 | |
parent | 02e3092f8d98f339588e48691db77f227b48ac1e (diff) |
Revert "ART: Compiler support for invoke-polymorphic."
This reverts commit 02e3092f8d98f339588e48691db77f227b48ac1e.
Reasons for revert:
- Breaks MIPS/MIPS64 build.
- Fails under GCStress test on x64.
- Different x64 build configuration doesn't like relocation.
Change-Id: I512555b38165d05f8a07e8aed528f00302061001
39 files changed, 72 insertions, 1189 deletions
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 86d92ff0b5..4180e0e6c9 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -487,7 +487,7 @@ TEST_F(OatTest, OatHeaderSizeCheck) { EXPECT_EQ(72U, sizeof(OatHeader)); EXPECT_EQ(4U, sizeof(OatMethodOffsets)); EXPECT_EQ(20U, sizeof(OatQuickMethodHeader)); - EXPECT_EQ(164 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)), + EXPECT_EQ(163 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)), sizeof(QuickEntryPoints)); } diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index c3e0c0ed60..402eeee65f 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -367,12 +367,6 @@ void CodeGenerator::GenerateInvokeUnresolvedRuntimeCall(HInvokeUnresolved* invok InvokeRuntime(entrypoint, invoke, invoke->GetDexPc(), nullptr); } -void CodeGenerator::GenerateInvokePolymorphicCall(HInvokePolymorphic* invoke) { - MoveConstant(invoke->GetLocations()->GetTemp(0), static_cast<int32_t>(invoke->GetType())); - QuickEntrypointEnum entrypoint = kQuickInvokePolymorphic; - InvokeRuntime(entrypoint, invoke, invoke->GetDexPc(), nullptr); -} - void CodeGenerator::CreateUnresolvedFieldLocationSummary( HInstruction* field_access, Primitive::Type field_type, diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 673a661bb4..2e2c3c00af 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -427,12 +427,12 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { } - // Performs checks pertaining to an InvokeRuntime call. + // Perfoms checks pertaining to an InvokeRuntime call. void ValidateInvokeRuntime(QuickEntrypointEnum entrypoint, HInstruction* instruction, SlowPathCode* slow_path); - // Performs checks pertaining to an InvokeRuntimeWithoutRecordingPcInfo call. + // Perfoms checks pertaining to an InvokeRuntimeWithoutRecordingPcInfo call. static void ValidateInvokeRuntimeWithoutRecordingPcInfo(HInstruction* instruction, SlowPathCode* slow_path); @@ -496,8 +496,6 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { void GenerateInvokeUnresolvedRuntimeCall(HInvokeUnresolved* invoke); - void GenerateInvokePolymorphicCall(HInvokePolymorphic* invoke); - void CreateUnresolvedFieldLocationSummary( HInstruction* field_access, Primitive::Type field_type, diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 61c64a6484..1dd526f404 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -2370,14 +2370,6 @@ void InstructionCodeGeneratorARM::VisitInvokeInterface(HInvokeInterface* invoke) codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } -void LocationsBuilderARM::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - HandleInvoke(invoke); -} - -void InstructionCodeGeneratorARM::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - codegen_->GenerateInvokePolymorphicCall(invoke); -} - void LocationsBuilderARM::VisitNeg(HNeg* neg) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(neg, LocationSummary::kNoCall); diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 4b78ee9cce..240e39df4b 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -4080,14 +4080,6 @@ void CodeGeneratorARM64::GenerateVirtualCall(HInvokeVirtual* invoke, Location te __ Blr(lr); } -void LocationsBuilderARM64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - HandleInvoke(invoke); -} - -void InstructionCodeGeneratorARM64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - codegen_->GenerateInvokePolymorphicCall(invoke); -} - vixl::aarch64::Label* CodeGeneratorARM64::NewPcRelativeStringPatch( const DexFile& dex_file, uint32_t string_index, diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 2c764dd263..cf4d94deea 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -2445,14 +2445,6 @@ void InstructionCodeGeneratorARMVIXL::VisitInvokeInterface(HInvokeInterface* inv } } -void LocationsBuilderARMVIXL::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - HandleInvoke(invoke); -} - -void InstructionCodeGeneratorARMVIXL::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - codegen_->GenerateInvokePolymorphicCall(invoke); -} - void LocationsBuilderARMVIXL::VisitNeg(HNeg* neg) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(neg, LocationSummary::kNoCall); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 40c5609ca3..29f8b2aa3c 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -5154,14 +5154,6 @@ void LocationsBuilderMIPS::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invo } } -void LocationsBuilderMIPS::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - HandleInvoke(invoke); -} - -void InstructionCodeGeneratorMIPS::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - codegen_->GenerateInvokePolymorphicCall(invoke); -} - static bool TryGenerateIntrinsicCode(HInvoke* invoke, CodeGeneratorMIPS* codegen) { if (invoke->GetLocations()->Intrinsified()) { IntrinsicCodeGeneratorMIPS intrinsic(codegen); diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 874613f000..dd3f0fee5a 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -3256,14 +3256,6 @@ void LocationsBuilderMIPS64::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* in HandleInvoke(invoke); } -void LocationsBuilderMIPS64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - HandleInvoke(invoke); -} - -void InstructionCodeGeneratorMIPS64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - codegen_->GenerateInvokePolymorphicCall(invoke); -} - static bool TryGenerateIntrinsicCode(HInvoke* invoke, CodeGeneratorMIPS64* codegen) { if (invoke->GetLocations()->Intrinsified()) { IntrinsicCodeGeneratorMIPS64 intrinsic(codegen); diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 4752051b71..786bc50345 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -2244,14 +2244,6 @@ void InstructionCodeGeneratorX86::VisitInvokeInterface(HInvokeInterface* invoke) codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } -void LocationsBuilderX86::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - HandleInvoke(invoke); -} - -void InstructionCodeGeneratorX86::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - codegen_->GenerateInvokePolymorphicCall(invoke); -} - void LocationsBuilderX86::VisitNeg(HNeg* neg) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(neg, LocationSummary::kNoCall); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 550736fdbc..06b48c489c 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -2423,14 +2423,6 @@ void InstructionCodeGeneratorX86_64::VisitInvokeInterface(HInvokeInterface* invo codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } -void LocationsBuilderX86_64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - HandleInvoke(invoke); -} - -void InstructionCodeGeneratorX86_64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) { - codegen_->GenerateInvokePolymorphicCall(invoke); -} - void LocationsBuilderX86_64::VisitNeg(HNeg* neg) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(neg, LocationSummary::kNoCall); diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index f6fba883bd..09dcefa02c 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -464,11 +464,6 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { StartAttributeStream("intrinsic") << invoke->GetIntrinsic(); } - void VisitInvokePolymorphic(HInvokePolymorphic* invoke) OVERRIDE { - VisitInvoke(invoke); - StartAttributeStream("invoke_type") << "InvokePolymorphic"; - } - void VisitInstanceFieldGet(HInstanceFieldGet* iget) OVERRIDE { StartAttributeStream("field_name") << iget->GetFieldInfo().GetDexFile().PrettyField(iget->GetFieldInfo().GetFieldIndex(), diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index d7da46bbe7..c970e5cbba 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -308,10 +308,8 @@ ArtMethod* HInliner::TryCHADevirtualization(ArtMethod* resolved_method) { } bool HInliner::TryInline(HInvoke* invoke_instruction) { - if (invoke_instruction->IsInvokeUnresolved() || - invoke_instruction->IsInvokePolymorphic()) { - return false; // Don't bother to move further if we know the method is unresolved or an - // invoke-polymorphic. + if (invoke_instruction->IsInvokeUnresolved()) { + return false; // Don't bother to move further if we know the method is unresolved. } ScopedObjectAccess soa(Thread::Current()); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 3cfabddf3a..009d549547 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1,4 +1,3 @@ - /* * Copyright (C) 2016 The Android Open Source Project * @@ -907,33 +906,6 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, false /* is_unresolved */); } -bool HInstructionBuilder::BuildInvokePolymorphic(const Instruction& instruction ATTRIBUTE_UNUSED, - uint32_t dex_pc, - uint32_t method_idx, - uint32_t proto_idx, - uint32_t number_of_vreg_arguments, - bool is_range, - uint32_t* args, - uint32_t register_index) { - const char* descriptor = dex_file_->GetShorty(proto_idx); - DCHECK_EQ(1 + ArtMethod::NumArgRegisters(descriptor), number_of_vreg_arguments); - Primitive::Type return_type = Primitive::GetType(descriptor[0]); - size_t number_of_arguments = strlen(descriptor); - HInvoke* invoke = new (arena_) HInvokePolymorphic(arena_, - number_of_arguments, - return_type, - dex_pc, - method_idx); - return HandleInvoke(invoke, - number_of_vreg_arguments, - args, - register_index, - is_range, - descriptor, - nullptr /* clinit_check */, - false /* is_unresolved */); -} - bool HInstructionBuilder::BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); @@ -1943,37 +1915,6 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, break; } - case Instruction::INVOKE_POLYMORPHIC: { - uint16_t method_idx = instruction.VRegB_45cc(); - uint16_t proto_idx = instruction.VRegH_45cc(); - uint32_t number_of_vreg_arguments = instruction.VRegA_45cc(); - uint32_t args[5]; - instruction.GetVarArgs(args); - return BuildInvokePolymorphic(instruction, - dex_pc, - method_idx, - proto_idx, - number_of_vreg_arguments, - false, - args, - -1); - } - - case Instruction::INVOKE_POLYMORPHIC_RANGE: { - uint16_t method_idx = instruction.VRegB_4rcc(); - uint16_t proto_idx = instruction.VRegH_4rcc(); - uint32_t number_of_vreg_arguments = instruction.VRegA_4rcc(); - uint32_t register_index = instruction.VRegC_4rcc(); - return BuildInvokePolymorphic(instruction, - dex_pc, - method_idx, - proto_idx, - number_of_vreg_arguments, - true, - nullptr, - register_index); - } - case Instruction::NEG_INT: { Unop_12x<HNeg>(instruction, Primitive::kPrimInt, dex_pc); break; diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index aef0b94c1f..f29e522040 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -175,17 +175,6 @@ class HInstructionBuilder : public ValueObject { uint32_t* args, uint32_t register_index); - // Builds an invocation node for invoke-polymorphic and returns whether the - // instruction is supported. - bool BuildInvokePolymorphic(const Instruction& instruction, - uint32_t dex_pc, - uint32_t method_idx, - uint32_t proto_idx, - uint32_t number_of_vreg_arguments, - bool is_range, - uint32_t* args, - uint32_t register_index); - // Builds a new array node and the instructions that fill it. void BuildFilledNewArray(uint32_t dex_pc, dex::TypeIndex type_index, diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index 4f30b11753..2856c3ea11 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -943,10 +943,6 @@ class LSEVisitor : public HGraphVisitor { HandleInvoke(invoke); } - void VisitInvokePolymorphic(HInvokePolymorphic* invoke) OVERRIDE { - HandleInvoke(invoke); - } - void VisitClinitCheck(HClinitCheck* clinit) OVERRIDE { HandleInvoke(clinit); } diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 27881922ac..db1b277990 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1291,7 +1291,6 @@ class HLoopInformationOutwardIterator : public ValueObject { M(InvokeInterface, Invoke) \ M(InvokeStaticOrDirect, Invoke) \ M(InvokeVirtual, Invoke) \ - M(InvokePolymorphic, Invoke) \ M(LessThan, Condition) \ M(LessThanOrEqual, Condition) \ M(LoadClass, Instruction) \ @@ -3984,28 +3983,6 @@ class HInvokeUnresolved FINAL : public HInvoke { DISALLOW_COPY_AND_ASSIGN(HInvokeUnresolved); }; -class HInvokePolymorphic FINAL : public HInvoke { - public: - HInvokePolymorphic(ArenaAllocator* arena, - uint32_t number_of_arguments, - Primitive::Type return_type, - uint32_t dex_pc, - uint32_t dex_method_index) - : HInvoke(arena, - number_of_arguments, - 0u /* number_of_other_inputs */, - return_type, - dex_pc, - dex_method_index, - nullptr, - kVirtual) {} - - DECLARE_INSTRUCTION(InvokePolymorphic); - - private: - DISALLOW_COPY_AND_ASSIGN(HInvokePolymorphic); -}; - class HInvokeStaticOrDirect FINAL : public HInvoke { public: // Requirements of this method call regarding the class diff --git a/compiler/utils/assembler_thumb_test_expected.cc.inc b/compiler/utils/assembler_thumb_test_expected.cc.inc index ab4f9e944c..a3fce02970 100644 --- a/compiler/utils/assembler_thumb_test_expected.cc.inc +++ b/compiler/utils/assembler_thumb_test_expected.cc.inc @@ -5610,7 +5610,7 @@ const char* const VixlJniHelpersResults[] = { " 214: ecbd 8a10 vpop {s16-s31}\n", " 218: e8bd 8de0 ldmia.w sp!, {r5, r6, r7, r8, sl, fp, pc}\n", " 21c: 4660 mov r0, ip\n", - " 21e: f8d9 c2b0 ldr.w ip, [r9, #688] ; 0x2b0\n", + " 21e: f8d9 c2ac ldr.w ip, [r9, #684] ; 0x2ac\n", " 222: 47e0 blx ip\n", nullptr }; diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 9e82f01692..4d4ebdcad8 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -2010,83 +2010,3 @@ READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg08, r8 READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg09, r9 READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg10, r10 READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg11, r11 - -.extern artInvokePolymorphic -ENTRY art_quick_invoke_polymorphic - SETUP_SAVE_REFS_AND_ARGS_FRAME r2 - mov r2, r9 @ pass Thread::Current - mov r3, sp @ pass SP - mov r0, #0 @ initialize 64-bit JValue as zero. - str r0, [sp, #-4]! - .cfi_adjust_cfa_offset 4 - str r0, [sp, #-4]! - .cfi_adjust_cfa_offset 4 - mov r0, sp @ pass JValue for return result as first argument. - bl artInvokePolymorphic @ artInvokePolymorphic(JValue, receiver, Thread*, SP) - sub r0, 'A' @ return value is descriptor of handle's return type. - cmp r0, 'Z' - 'A' @ check if value is in bounds of handler table - bgt .Lcleanup_and_return @ and clean-up if not. - adr r1, .Lhandler_table - tbb [r0, r1] @ branch to handler for return value based on return type. - -.Lstart_of_handlers: -.Lstore_boolean_result: - ldrb r0, [sp] @ Copy boolean value to return value of this function. - b .Lcleanup_and_return -.Lstore_char_result: - ldrh r0, [sp] @ Copy char value to return value of this function. - b .Lcleanup_and_return -.Lstore_float_result: - vldr s0, [sp] @ Copy float value from JValue result to the context restored by - vstr s0, [sp, #16] @ RESTORE_SAVE_REFS_AND_ARGS_FRAME. - b .Lcleanup_and_return -.Lstore_double_result: - vldr d0, [sp] @ Copy double value from JValue result to the context restored by - vstr d0, [sp, #16] @ RESTORE_SAVE_REFS_AND_ARGS_FRAME. - b .Lcleanup_and_return -.Lstore_long_result: - ldr r1, [sp, #4] @ Copy the upper bits from JValue result to the context restored by - str r1, [sp, #80] @ RESTORE_SAVE_REFS_AND_ARGS_FRAME. - // Fall-through for lower bits. -.Lstore_int_result: - ldr r0, [sp] @ Copy int value to return value of this function. - // Fall-through to clean up and return. -.Lcleanup_and_return: - add sp, #8 - .cfi_adjust_cfa_offset -8 - RESTORE_SAVE_REFS_AND_ARGS_FRAME - RETURN_OR_DELIVER_PENDING_EXCEPTION_REG r2 - -.macro HANDLER_TABLE_OFFSET handler_label - .byte (\handler_label - .Lstart_of_handlers) / 2 -.endm - -.Lhandler_table: - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // A - HANDLER_TABLE_OFFSET(.Lstore_int_result) // B (byte) - HANDLER_TABLE_OFFSET(.Lstore_char_result) // C (char) - HANDLER_TABLE_OFFSET(.Lstore_double_result) // D (double) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // E - HANDLER_TABLE_OFFSET(.Lstore_float_result) // F (float) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // G - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // H - HANDLER_TABLE_OFFSET(.Lstore_int_result) // I (int) - HANDLER_TABLE_OFFSET(.Lstore_long_result) // J (long) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // K - HANDLER_TABLE_OFFSET(.Lstore_long_result) // L (object) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // M - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // N - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // O - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // P - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // Q - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // R - HANDLER_TABLE_OFFSET(.Lstore_int_result) // S (short) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // T - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // U - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // V (void) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // W - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // X - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // Y - HANDLER_TABLE_OFFSET(.Lstore_boolean_result) // Z (boolean) -.purgem HANDLER_TABLE_OFFSET -END art_quick_invoke_polymorphic diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index eba0c8782d..8b1e0388c6 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -2567,82 +2567,3 @@ READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg26, w26, x26 READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg27, w27, x27 READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg28, w28, x28 READ_BARRIER_MARK_REG art_quick_read_barrier_mark_reg29, w29, x29 - -.extern artInvokePolymorphic -ENTRY art_quick_invoke_polymorphic - SETUP_SAVE_REFS_AND_ARGS_FRAME // Save callee saves in case allocation triggers GC. - mov x2, xSELF - mov x3, sp - INCREASE_FRAME 16 // Reserve space for JValue result. - str xzr, [sp, #0] // Initialize result to zero. - mov x0, sp // Set r0 to point to result. - bl artInvokePolymorphic // ArtInvokePolymorphic(result, receiver, thread, save_area) - uxtb w0, w0 // Result is the return type descriptor as a char. - sub w0, w0, 'A' // Convert to zero based index. - cmp w0, 'Z' - 'A' - bhi .Lcleanup_and_return // Clean-up if out-of-bounds. - adrp x1, .Lhandler_table // Compute address of handler table. - add x1, x1, :lo12:.Lhandler_table - ldrb w0, [x1, w0, uxtw] // Lookup handler offset in handler table. - adr x1, .Lstart_of_handlers - add x0, x1, w0, sxtb #2 // Convert relative offset to absolute address. - br x0 // Branch to handler. - -.Lstart_of_handlers: -.Lstore_boolean_result: - ldrb w0, [sp] - b .Lcleanup_and_return -.Lstore_char_result: - ldrh w0, [sp] - b .Lcleanup_and_return -.Lstore_float_result: - ldr s0, [sp] - str s0, [sp, #32] - b .Lcleanup_and_return -.Lstore_double_result: - ldr d0, [sp] - str d0, [sp, #32] - b .Lcleanup_and_return -.Lstore_long_result: - ldr x0, [sp] - // Fall-through -.Lcleanup_and_return: - DECREASE_FRAME 16 - RESTORE_SAVE_REFS_AND_ARGS_FRAME - RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 - - .section .rodata // Place handler table in read-only section away from text. - .align 2 -.macro HANDLER_TABLE_OFFSET handler_label - .byte (\handler_label - .Lstart_of_handlers) / 4 -.endm -.Lhandler_table: - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // A - HANDLER_TABLE_OFFSET(.Lstore_long_result) // B (byte) - HANDLER_TABLE_OFFSET(.Lstore_char_result) // C (char) - HANDLER_TABLE_OFFSET(.Lstore_double_result) // D (double) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // E - HANDLER_TABLE_OFFSET(.Lstore_float_result) // F (float) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // G - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // H - HANDLER_TABLE_OFFSET(.Lstore_long_result) // I (int) - HANDLER_TABLE_OFFSET(.Lstore_long_result) // J (long) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // K - HANDLER_TABLE_OFFSET(.Lstore_long_result) // L (object) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // M - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // N - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // O - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // P - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // Q - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // R - HANDLER_TABLE_OFFSET(.Lstore_long_result) // S (short) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // T - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // U - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // V (void) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // W - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // X - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // Y - HANDLER_TABLE_OFFSET(.Lstore_boolean_result) // Z (boolean) - .text - -END art_quick_invoke_polymorphic diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index ea95bbce7b..62c29cf268 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -468,7 +468,7 @@ TWO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_string_bounds, artThro * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting * of the target Method* in r0 and method->code_ in r1. * - * If unsuccessful, the helper will return null/null and there will be a pending exception in the + * If unsuccessful, the helper will return null/null will bea pending exception in the * thread and we branch to another stub to deliver it. * * On success this wrapper will restore arguments and *jump* to the target, leaving the lr @@ -2223,97 +2223,5 @@ DEFINE_FUNCTION art_quick_osr_stub jmp *%ebx END_FUNCTION art_quick_osr_stub -DEFINE_FUNCTION art_quick_invoke_polymorphic - SETUP_SAVE_REFS_AND_ARGS_FRAME ebx, ebx // Save frame. - mov %esp, %edx // Remember SP. - subl LITERAL(16), %esp // Make space for JValue result. - CFI_ADJUST_CFA_OFFSET(16) - movl LITERAL(0), (%esp) // Initialize result to zero. - movl LITERAL(0), 4(%esp) - mov %esp, %eax // Store pointer to JValue result in eax. - PUSH edx // pass SP - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH ecx // pass receiver (method handle) - PUSH eax // pass JResult - call SYMBOL(artInvokePolymorphic) // (result, receiver, Thread*, SP) - subl LITERAL('A'), %eax // Eliminate out of bounds options - cmpb LITERAL('Z' - 'A'), %al - ja .Lcleanup_and_return - movzbl %al, %eax - call .Lput_eip_in_ecx -.Lbranch_start: - add $(.Lhandler_table - .Lbranch_start), %eax // Add offset of handler table to index. - addl %ecx, %eax // Add EIP relative address of table. - movzbl (%eax), %eax // Lookup relative branch in table. - addl %ecx, %eax // Add EIP relative offset. - jmp *%eax // Branch to handler. - - // Handlers for different return types. -.Lstore_boolean_result: - movzbl 16(%esp), %eax // Copy boolean result to the accumulator. - jmp .Lcleanup_and_return -.Lstore_char_result: - movzwl 16(%esp), %eax // Copy char result to the accumulator. - jmp .Lcleanup_and_return -.Lstore_float_result: - movd 16(%esp), %xmm0 // Copy float result to the context restored by - movd %xmm0, 36(%esp) // RESTORE_SAVE_REFS_ONLY_FRAME. - jmp .Lcleanup_and_return -.Lstore_double_result: - movsd 16(%esp), %xmm0 // Copy double result to the context restored by - movsd %xmm0, 36(%esp) // RESTORE_SAVE_REFS_ONLY_FRAME. - jmp .Lcleanup_and_return -.Lstore_long_result: - movl 20(%esp), %edx // Copy upper-word of result to the context restored by - movl %edx, 72(%esp) // RESTORE_SAVE_REFS_ONLY_FRAME. - // Fall-through for lower bits. -.Lstore_int_result: - movl 16(%esp), %eax // Copy int result to the accumulator. - // Fall-through to clean up and return. -.Lcleanup_and_return: - addl LITERAL(32), %esp // Pop arguments and stack allocated JValue result. - CFI_ADJUST_CFA_OFFSET(-32) - RESTORE_SAVE_REFS_AND_ARGS_FRAME - RETURN_OR_DELIVER_PENDING_EXCEPTION - -.Lput_eip_in_ecx: // Internal function that puts address of - movl 0(%esp), %ecx // next instruction into ECX when CALL - ret - - // Handler table to handlers for given type. -.Lhandler_table: -MACRO1(HANDLER_TABLE_ENTRY, handler_label) - .byte RAW_VAR(handler_label) - .Lbranch_start -END_MACRO - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // A - HANDLER_TABLE_ENTRY(.Lstore_int_result) // B (byte) - HANDLER_TABLE_ENTRY(.Lstore_char_result) // C (char) - HANDLER_TABLE_ENTRY(.Lstore_double_result) // D (double) - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // E - HANDLER_TABLE_ENTRY(.Lstore_float_result) // F (float) - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // G - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // H - HANDLER_TABLE_ENTRY(.Lstore_int_result) // I (int) - HANDLER_TABLE_ENTRY(.Lstore_long_result) // J (long) - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // K - HANDLER_TABLE_ENTRY(.Lstore_int_result) // L (object) - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // M - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // N - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // O - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // P - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // Q - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // R - HANDLER_TABLE_ENTRY(.Lstore_int_result) // S (short) - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // T - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // U - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // V (void) - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // W - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // X - HANDLER_TABLE_ENTRY(.Lcleanup_and_return) // Y - HANDLER_TABLE_ENTRY(.Lstore_boolean_result) // Z (boolean) - -END_FUNCTION art_quick_invoke_polymorphic - // TODO: implement these! UNIMPLEMENTED art_quick_memcmp16 diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index 5b3a314098..facd563428 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -2394,78 +2394,3 @@ DEFINE_FUNCTION art_quick_osr_stub rep movsb // while (rcx--) { *rdi++ = *rsi++ } jmp *%rdx END_FUNCTION art_quick_osr_stub - -DEFINE_FUNCTION art_quick_invoke_polymorphic - SETUP_SAVE_REFS_AND_ARGS_FRAME // save callee saves - movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread - movq %rsp, %rcx // pass SP - subq LITERAL(16), %rsp // make space for JValue result - CFI_ADJUST_CFA_OFFSET(16) - movq LITERAL(0), (%rsp) // initialize result - movq %rsp, %rdi // store pointer to JValue result - call SYMBOL(artInvokePolymorphic) // artInvokePolymorphic(result, receiver, Thread*, SP) - // save the code pointer - subq LITERAL('A'), %rax // Convert type descriptor character value to a zero based index. - cmpb LITERAL('Z' - 'A'), %al // Eliminate out of bounds options - ja .Lcleanup_and_return - movzbq %al, %rax - leaq .Lhandler_table(%rip), %rcx // Get the address of the handler table - movsbq (%rcx, %rax, 1), %rax // Lookup handler offset relative to table - addq %rcx, %rax // Add table address to yield handler address. - jmpq *%rax // Jump to handler. - -.align 4 -.Lhandler_table: // Table of type descriptor to handlers. -MACRO1(HANDLER_TABLE_OFFSET, handle_label) - .byte RAW_VAR(handle_label) - .Lhandler_table -END_MACRO - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // A - HANDLER_TABLE_OFFSET(.Lstore_long_result) // B (byte) - HANDLER_TABLE_OFFSET(.Lstore_char_result) // C (char) - HANDLER_TABLE_OFFSET(.Lstore_double_result) // D (double) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // E - HANDLER_TABLE_OFFSET(.Lstore_float_result) // F (float) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // G - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // H - HANDLER_TABLE_OFFSET(.Lstore_long_result) // I (int) - HANDLER_TABLE_OFFSET(.Lstore_long_result) // J (long) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // K - HANDLER_TABLE_OFFSET(.Lstore_long_result) // L (object) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // M - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // N - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // O - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // P - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // Q - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // R - HANDLER_TABLE_OFFSET(.Lstore_long_result) // S (short) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // T - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // U - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // V (void) - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // W - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // X - HANDLER_TABLE_OFFSET(.Lcleanup_and_return) // Y - HANDLER_TABLE_OFFSET(.Lstore_boolean_result) // Z (boolean) - -.Lstore_boolean_result: - movzbq (%rsp), %rax // Copy boolean result to the accumulator - jmp .Lcleanup_and_return -.Lstore_char_result: - movzwq (%rsp), %rax // Copy char result to the accumulator - jmp .Lcleanup_and_return -.Lstore_float_result: - movd (%rsp), %xmm0 // Copy float result to the context restored by - movd %xmm0, 32(%rsp) // RESTORE_SAVE_REFS_AND_ARGS_FRAME. - jmp .Lcleanup_and_return -.Lstore_double_result: - movsd (%rsp), %xmm0 // Copy double result to the context restored by - movsd %xmm0, 32(%rsp) // RESTORE_SAVE_REFS_AND_ARGS_FRAME. - jmp .Lcleanup_and_return -.Lstore_long_result: - movq (%rsp), %rax // Copy long result to the accumulator. - // Fall-through -.Lcleanup_and_return: - addq LITERAL(16), %rsp // Pop space for JValue result. - CFI_ADJUST_CFA_OFFSET(16) - RESTORE_SAVE_REFS_AND_ARGS_FRAME - RETURN_OR_DELIVER_PENDING_EXCEPTION -END_FUNCTION art_quick_invoke_polymorphic diff --git a/runtime/asm_support.h b/runtime/asm_support.h index e4972da13d..bfdddf7b03 100644 --- a/runtime/asm_support.h +++ b/runtime/asm_support.h @@ -98,7 +98,7 @@ ADD_TEST_EQ(THREAD_LOCAL_POS_OFFSET, ADD_TEST_EQ(THREAD_LOCAL_END_OFFSET, art::Thread::ThreadLocalEndOffset<POINTER_SIZE>().Int32Value()) // Offset of field Thread::tlsPtr_.thread_local_objects. -#define THREAD_LOCAL_OBJECTS_OFFSET (THREAD_LOCAL_END_OFFSET + 2 * __SIZEOF_POINTER__) +#define THREAD_LOCAL_OBJECTS_OFFSET (THREAD_LOCAL_END_OFFSET + __SIZEOF_POINTER__) ADD_TEST_EQ(THREAD_LOCAL_OBJECTS_OFFSET, art::Thread::ThreadLocalObjectsOffset<POINTER_SIZE>().Int32Value()) // Offset of field Thread::tlsPtr_.mterp_current_ibase. diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc index a44f79e193..c30272e114 100644 --- a/runtime/common_throws.cc +++ b/runtime/common_throws.cc @@ -428,8 +428,6 @@ static bool IsValidImplicitCheck(uintptr_t addr, ArtMethod* method, const Instru case Instruction::INVOKE_VIRTUAL_RANGE: case Instruction::INVOKE_INTERFACE: case Instruction::INVOKE_INTERFACE_RANGE: - case Instruction::INVOKE_POLYMORPHIC: - case Instruction::INVOKE_POLYMORPHIC_RANGE: case Instruction::INVOKE_VIRTUAL_QUICK: case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { // Without inlining, we could just check that the offset is the class offset. @@ -553,12 +551,6 @@ void ThrowNullPointerExceptionFromDexPC(bool check_address, uintptr_t addr) { case Instruction::INVOKE_INTERFACE_RANGE: ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kInterface); break; - case Instruction::INVOKE_POLYMORPHIC: - ThrowNullPointerExceptionForMethodAccess(instr->VRegB_45cc(), kVirtual); - break; - case Instruction::INVOKE_POLYMORPHIC_RANGE: - ThrowNullPointerExceptionForMethodAccess(instr->VRegB_4rcc(), kVirtual); - break; case Instruction::INVOKE_VIRTUAL_QUICK: case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { // Since we replaced the method index, we ask the verifier to tell us which diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc index 37f3ac92e9..7b8974fa5a 100644 --- a/runtime/dex_instruction.cc +++ b/runtime/dex_instruction.cc @@ -358,7 +358,7 @@ std::string Instruction::DumpString(const DexFile* file) const { } break; case k35c: { - uint32_t arg[kMaxVarArgRegs]; + uint32_t arg[5]; GetVarArgs(arg); switch (Opcode()) { case FILLED_NEW_ARRAY: @@ -443,50 +443,8 @@ std::string Instruction::DumpString(const DexFile* file) const { } break; } - case k45cc: { - uint32_t arg[kMaxVarArgRegs]; - GetVarArgs(arg); - uint32_t method_idx = VRegB_45cc(); - uint32_t proto_idx = VRegH_45cc(); - os << opcode << " {"; - for (int i = 0; i < VRegA_45cc(); ++i) { - if (i != 0) { - os << ", "; - } - os << "v" << arg[i]; - } - os << "}"; - if (file != nullptr) { - os << ", " << file->PrettyMethod(method_idx) << ", " << file->GetShorty(proto_idx) - << " // "; - } else { - os << ", "; - } - os << "method@" << method_idx << ", proto@" << proto_idx; - break; - } - case k4rcc: - switch (Opcode()) { - case INVOKE_POLYMORPHIC_RANGE: { - if (file != nullptr) { - uint32_t method_idx = VRegB_4rcc(); - uint32_t proto_idx = VRegH_4rcc(); - os << opcode << ", {v" << VRegC_4rcc() << " .. v" << (VRegC_4rcc() + VRegA_4rcc()) - << "}, " << file->PrettyMethod(method_idx) << ", " << file->GetShorty(proto_idx) - << " // method@" << method_idx << ", proto@" << proto_idx; - break; - } - } - FALLTHROUGH_INTENDED; - default: { - uint32_t method_idx = VRegB_4rcc(); - uint32_t proto_idx = VRegH_4rcc(); - os << opcode << ", {v" << VRegC_4rcc() << " .. v" << (VRegC_4rcc() + VRegA_4rcc()) - << "}, method@" << method_idx << ", proto@" << proto_idx; - } - } - break; case k51l: os << StringPrintf("%s v%d, #%+" PRId64, opcode, VRegA_51l(), VRegB_51l()); break; + default: os << " unknown format (" << DumpHex(5) << ")"; break; } return os.str(); } diff --git a/runtime/entrypoints/quick/quick_default_externs.h b/runtime/entrypoints/quick/quick_default_externs.h index 2d0932a0c4..64030f36bc 100644 --- a/runtime/entrypoints/quick/quick_default_externs.h +++ b/runtime/entrypoints/quick/quick_default_externs.h @@ -109,13 +109,8 @@ extern "C" void art_quick_invoke_direct_trampoline_with_access_check(uint32_t, v extern "C" void art_quick_invoke_interface_trampoline_with_access_check(uint32_t, void*); extern "C" void art_quick_invoke_static_trampoline_with_access_check(uint32_t, void*); extern "C" void art_quick_invoke_super_trampoline_with_access_check(uint32_t, void*); - extern "C" void art_quick_invoke_virtual_trampoline_with_access_check(uint32_t, void*); -// Invoke polymorphic entrypoint. Return type is dynamic and may be void, a primitive value, or -// reference return type. -extern "C" void art_quick_invoke_polymorphic(uint32_t, void*); - // Thread entrypoints. extern "C" void art_quick_test_suspend(); diff --git a/runtime/entrypoints/quick/quick_default_init_entrypoints.h b/runtime/entrypoints/quick/quick_default_init_entrypoints.h index 8ce61c1021..78dad94dfe 100644 --- a/runtime/entrypoints/quick/quick_default_init_entrypoints.h +++ b/runtime/entrypoints/quick/quick_default_init_entrypoints.h @@ -106,7 +106,6 @@ void DefaultInitEntryPoints(JniEntryPoints* jpoints, QuickEntryPoints* qpoints) art_quick_invoke_super_trampoline_with_access_check; qpoints->pInvokeVirtualTrampolineWithAccessCheck = art_quick_invoke_virtual_trampoline_with_access_check; - qpoints->pInvokePolymorphic = art_quick_invoke_polymorphic; // Thread qpoints->pTestSuspend = art_quick_test_suspend; diff --git a/runtime/entrypoints/quick/quick_entrypoints_list.h b/runtime/entrypoints/quick/quick_entrypoints_list.h index 4d5d6de41d..0911aeb0f4 100644 --- a/runtime/entrypoints/quick/quick_entrypoints_list.h +++ b/runtime/entrypoints/quick/quick_entrypoints_list.h @@ -133,7 +133,6 @@ V(InvokeStaticTrampolineWithAccessCheck, void, uint32_t, void*) \ V(InvokeSuperTrampolineWithAccessCheck, void, uint32_t, void*) \ V(InvokeVirtualTrampolineWithAccessCheck, void, uint32_t, void*) \ - V(InvokePolymorphic, void, uint32_t, void*) \ \ V(TestSuspend, void, void) \ \ diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index bbd4fbab93..bf1d4ea1a1 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -27,12 +27,10 @@ #include "imtable-inl.h" #include "interpreter/interpreter.h" #include "linear_alloc.h" -#include "method_handles.h" #include "method_reference.h" #include "mirror/class-inl.h" #include "mirror/dex_cache-inl.h" #include "mirror/method.h" -#include "mirror/method_handle_impl.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "oat_quick_method_header.h" @@ -41,7 +39,6 @@ #include "scoped_thread_state_change-inl.h" #include "stack.h" #include "debugger.h" -#include "well_known_classes.h" namespace art { @@ -2394,114 +2391,4 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t deadbeef ATTRIBUT reinterpret_cast<uintptr_t>(method)); } -// Returns shorty type so the caller can determine how to put |result| -// into expected registers. The shorty type is static so the compiler -// could call different flavors of this code path depending on the -// shorty type though this would require different entry points for -// each type. -extern "C" uintptr_t artInvokePolymorphic( - JValue* result, - mirror::Object* raw_method_handle, - Thread* self, - ArtMethod** sp) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - DCHECK_EQ(*sp, Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveRefsAndArgs)); - - // Start new JNI local reference state - JNIEnvExt* env = self->GetJniEnv(); - ScopedObjectAccessUnchecked soa(env); - ScopedJniEnvLocalRefState env_state(env); - const char* old_cause = self->StartAssertNoThreadSuspension("Making stack arguments safe."); - - // From the instruction, get the |callsite_shorty| and expose arguments on the stack to the GC. - ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp); - uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp); - const DexFile::CodeItem* code = caller_method->GetCodeItem(); - const Instruction* inst = Instruction::At(&code->insns_[dex_pc]); - DCHECK(inst->Opcode() == Instruction::INVOKE_POLYMORPHIC || - inst->Opcode() == Instruction::INVOKE_POLYMORPHIC_RANGE); - const DexFile* dex_file = caller_method->GetDexFile(); - const uint32_t proto_idx = inst->VRegH(); - const char* shorty = dex_file->GetShorty(proto_idx); - const size_t shorty_length = strlen(shorty); - static const bool kMethodIsStatic = false; // invoke() and invokeExact() are not static. - RememberForGcArgumentVisitor gc_visitor(sp, kMethodIsStatic, shorty, shorty_length, &soa); - gc_visitor.Visit(); - - // Wrap raw_method_handle in a Handle for safety. - StackHandleScope<5> hs(self); - Handle<mirror::MethodHandleImpl> method_handle( - hs.NewHandle(ObjPtr<mirror::MethodHandleImpl>::DownCast(MakeObjPtr(raw_method_handle)))); - raw_method_handle = nullptr; - self->EndAssertNoThreadSuspension(old_cause); - - // Resolve method - it's either MethodHandle.invoke() or MethodHandle.invokeExact(). - ClassLinker* linker = Runtime::Current()->GetClassLinker(); - ArtMethod* resolved_method = linker->ResolveMethod<ClassLinker::kForceICCECheck>(self, - inst->VRegB(), - caller_method, - kVirtual); - DCHECK((resolved_method == - jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_invokeExact)) || - (resolved_method == - jni::DecodeArtMethod(WellKnownClasses::java_lang_invoke_MethodHandle_invoke))); - if (UNLIKELY(method_handle.IsNull())) { - ThrowNullPointerExceptionForMethodAccess(resolved_method, InvokeType::kVirtual); - return static_cast<uintptr_t>('V'); - } - - Handle<mirror::Class> caller_class(hs.NewHandle(caller_method->GetDeclaringClass())); - Handle<mirror::MethodType> method_type(hs.NewHandle(linker->ResolveMethodType( - *dex_file, proto_idx, - hs.NewHandle<mirror::DexCache>(caller_class->GetDexCache()), - hs.NewHandle<mirror::ClassLoader>(caller_class->GetClassLoader())))); - // This implies we couldn't resolve one or more types in this method handle. - if (UNLIKELY(method_type.IsNull())) { - CHECK(self->IsExceptionPending()); - return static_cast<uintptr_t>('V'); - } - - DCHECK_EQ(ArtMethod::NumArgRegisters(shorty) + 1u, (uint32_t)inst->VRegA()); - DCHECK_EQ(resolved_method->IsStatic(), kMethodIsStatic); - - // Fix references before constructing the shadow frame. - gc_visitor.FixupReferences(); - - // Construct shadow frame placing arguments consecutively from |first_arg|. - const bool is_range = (inst->Opcode() == Instruction::INVOKE_POLYMORPHIC_RANGE); - const size_t num_vregs = is_range ? inst->VRegA_4rcc() : inst->VRegA_45cc(); - const size_t first_arg = 0; - ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = - CREATE_SHADOW_FRAME(num_vregs, /* link */ nullptr, resolved_method, dex_pc); - ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get(); - ScopedStackedShadowFramePusher - frame_pusher(self, shadow_frame, StackedShadowFrameType::kShadowFrameUnderConstruction); - BuildQuickShadowFrameVisitor shadow_frame_builder(sp, - kMethodIsStatic, - shorty, - strlen(shorty), - shadow_frame, - first_arg); - shadow_frame_builder.VisitArguments(); - - // Call DoInvokePolymorphic with |is_range| = true, as shadow frame has argument registers in - // consecutive order. - uint32_t unused_args[Instruction::kMaxVarArgRegs] = {}; - uint32_t first_callee_arg = first_arg + 1; - const bool do_assignability_check = false; - if (!DoInvokePolymorphic<true /* is_range */, do_assignability_check>(self, - resolved_method, - *shadow_frame, - method_handle, - method_type, - unused_args, - first_callee_arg, - result)) { - DCHECK(self->IsExceptionPending()); - } - - return static_cast<uintptr_t>(shorty[0]); -} - } // namespace art diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc index 96e17daa08..6866abb6ae 100644 --- a/runtime/entrypoints_order_test.cc +++ b/runtime/entrypoints_order_test.cc @@ -121,10 +121,10 @@ class EntrypointsOrderTest : public CommonRuntimeTest { sizeof(Thread::tls_ptr_sized_values::active_suspend_barriers)); // Skip across the entrypoints structures. - EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_pos, thread_local_end, sizeof(void*)); - EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_end, thread_local_start, sizeof(void*)); - EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_start, thread_local_objects, sizeof(void*)); + EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_start, thread_local_pos, sizeof(void*)); + EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_pos, thread_local_end, sizeof(void*)); + EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_end, thread_local_objects, sizeof(void*)); EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_objects, mterp_current_ibase, sizeof(size_t)); EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, mterp_current_ibase, mterp_default_ibase, sizeof(void*)); EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, mterp_default_ibase, mterp_alt_ibase, sizeof(void*)); @@ -286,8 +286,6 @@ class EntrypointsOrderTest : public CommonRuntimeTest { EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pInvokeSuperTrampolineWithAccessCheck, pInvokeVirtualTrampolineWithAccessCheck, sizeof(void*)); EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pInvokeVirtualTrampolineWithAccessCheck, - pInvokePolymorphic, sizeof(void*)); - EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pInvokePolymorphic, pTestSuspend, sizeof(void*)); EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pTestSuspend, pDeliverException, sizeof(void*)); diff --git a/runtime/oat.h b/runtime/oat.h index 685aa04313..dc103e2b52 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,7 +32,7 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' }; - static constexpr uint8_t kOatVersion[] = { '0', '9', '6', '\0' }; // invoke-polymorphic entry + static constexpr uint8_t kOatVersion[] = { '0', '9', '5', '\0' }; // alloc entrypoints change static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; diff --git a/runtime/thread.cc b/runtime/thread.cc index 9ce2e5ebb0..33c6a40320 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -2725,7 +2725,6 @@ void Thread::DumpThreadOffset(std::ostream& os, uint32_t offset) { QUICK_ENTRY_POINT_INFO(pInvokeStaticTrampolineWithAccessCheck) QUICK_ENTRY_POINT_INFO(pInvokeSuperTrampolineWithAccessCheck) QUICK_ENTRY_POINT_INFO(pInvokeVirtualTrampolineWithAccessCheck) - QUICK_ENTRY_POINT_INFO(pInvokePolymorphic) QUICK_ENTRY_POINT_INFO(pTestSuspend) QUICK_ENTRY_POINT_INFO(pDeliverException) QUICK_ENTRY_POINT_INFO(pThrowArrayBounds) diff --git a/runtime/thread.h b/runtime/thread.h index b8c5065852..6308851096 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -1416,7 +1416,7 @@ class Thread { stacked_shadow_frame_record(nullptr), deoptimization_context_stack(nullptr), frame_id_to_shadow_frame(nullptr), name(nullptr), pthread_self(0), last_no_thread_suspension_cause(nullptr), checkpoint_function(nullptr), - thread_local_pos(nullptr), thread_local_end(nullptr), thread_local_start(nullptr), + thread_local_start(nullptr), thread_local_pos(nullptr), thread_local_end(nullptr), thread_local_objects(0), mterp_current_ibase(nullptr), mterp_default_ibase(nullptr), mterp_alt_ibase(nullptr), thread_local_alloc_stack_top(nullptr), thread_local_alloc_stack_end(nullptr), nested_signal_state(nullptr), @@ -1540,14 +1540,13 @@ class Thread { JniEntryPoints jni_entrypoints; QuickEntryPoints quick_entrypoints; + // Thread-local allocation pointer. Moved here to force alignment for thread_local_pos on ARM. + uint8_t* thread_local_start; // thread_local_pos and thread_local_end must be consecutive for ldrd and are 8 byte aligned for // potentially better performance. uint8_t* thread_local_pos; uint8_t* thread_local_end; - // Thread-local allocation pointer. - uint8_t* thread_local_start; - size_t thread_local_objects; // Mterp jump table bases. diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 25a179bd32..715b237a6a 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -3106,16 +3106,19 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { break; } const uint32_t proto_idx = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc(); - const char* return_descriptor = + const char* descriptor = dex_file_->GetReturnTypeDescriptor(dex_file_->GetProtoId(proto_idx)); const RegType& return_type = - reg_types_.FromDescriptor(GetClassLoader(), return_descriptor, false); + reg_types_.FromDescriptor(GetClassLoader(), descriptor, false); if (!return_type.IsLowHalf()) { work_line_->SetResultRegisterType(this, return_type); } else { work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(®_types_)); } - just_set_result = true; + // TODO(oth): remove when compiler support is available. + Fail(VERIFY_ERROR_FORCE_INTERPRETER) + << "invoke-polymorphic is not supported by compiler"; + have_pending_experimental_failure_ = true; break; } case Instruction::NEG_INT: diff --git a/test/953-invoke-polymorphic-compiler/build b/test/953-invoke-polymorphic-compiler/build deleted file mode 100755 index a423ca6b4e..0000000000 --- a/test/953-invoke-polymorphic-compiler/build +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -# -# Copyright 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. - -# make us exit on a failure -set -e - -if [[ $@ != *"--jvm"* ]]; then - # Don't do anything with jvm. - export USE_JACK=true -fi - -./default-build "$@" --experimental method-handles diff --git a/test/953-invoke-polymorphic-compiler/expected.txt b/test/953-invoke-polymorphic-compiler/expected.txt deleted file mode 100644 index f47ee23fd8..0000000000 --- a/test/953-invoke-polymorphic-compiler/expected.txt +++ /dev/null @@ -1,25 +0,0 @@ -Running Main.Min2Print2([33, -4]) -Running Main.Min2Print2([-4, 33]) -Running Main.Min2Print3([33, -4, 17]) -Running Main.Min2Print3([-4, 17, 33]) -Running Main.Min2Print3([17, 33, -4]) -Running Main.Min2Print6([33, -4, 77, 88, 99, 111]) -Running Main.Min2Print6([-4, 77, 88, 99, 111, 33]) -Running Main.Min2Print6([77, 88, 99, 111, 33, -4]) -Running Main.Min2Print6([88, 99, 111, 33, -4, 77]) -Running Main.Min2Print6([99, 111, 33, -4, 77, 88]) -Running Main.Min2Print6([111, 33, -4, 77, 88, 99]) -Running Main.Min2Print26([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]) -Running Main.Min2Print26([25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]) -Running Main.Min2Print26([24, 25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]) -BasicTest done. -$opt$ReturnBooleanTest done. -$opt$ReturnCharTest done. -$opt$ReturnByteTest done. -$opt$ReturnShortTest done. -$opt$ReturnIntTest done. -$opt$ReturnLongTest done. -$opt$ReturnFloatTest done. -$opt$ReturnDoubleTest done. -$opt$ReturnStringTest done. -ReturnValuesTest done. diff --git a/test/953-invoke-polymorphic-compiler/info.txt b/test/953-invoke-polymorphic-compiler/info.txt deleted file mode 100644 index f1dbb61640..0000000000 --- a/test/953-invoke-polymorphic-compiler/info.txt +++ /dev/null @@ -1,3 +0,0 @@ -Tests for method handle invocations. - -NOTE: needs to run under ART or a Java 8 Language runtime and compiler. diff --git a/test/953-invoke-polymorphic-compiler/run b/test/953-invoke-polymorphic-compiler/run deleted file mode 100755 index a9f182288c..0000000000 --- a/test/953-invoke-polymorphic-compiler/run +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -# -# Copyright 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. - -# make us exit on a failure -set -e - -./default-run "$@" --experimental method-handles diff --git a/test/953-invoke-polymorphic-compiler/src/Main.java b/test/953-invoke-polymorphic-compiler/src/Main.java deleted file mode 100644 index 20a8fec112..0000000000 --- a/test/953-invoke-polymorphic-compiler/src/Main.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * 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. - */ - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodHandles.Lookup; -import java.lang.invoke.MethodType; -import java.lang.invoke.WrongMethodTypeException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class Main { - public static void assertTrue(boolean value) { - if (!value) { - throw new AssertionError("assertTrue value: " + value); - } - } - - public static void assertFalse(boolean value) { - if (value) { - throw new AssertionError("assertTrue value: " + value); - } - } - - public static void assertEquals(int i1, int i2) { - if (i1 == i2) { return; } - throw new AssertionError("assertEquals i1: " + i1 + ", i2: " + i2); - } - - public static void assertEquals(long i1, long i2) { - if (i1 == i2) { return; } - throw new AssertionError("assertEquals l1: " + i1 + ", l2: " + i2); - } - - public static void assertEquals(Object o, Object p) { - if (o == p) { return; } - if (o != null && p != null && o.equals(p)) { return; } - throw new AssertionError("assertEquals: o1: " + o + ", o2: " + p); - } - - public static void assertEquals(String s1, String s2) { - if (s1 == s2) { - return; - } - - if (s1 != null && s2 != null && s1.equals(s2)) { - return; - } - - throw new AssertionError("assertEquals s1: " + s1 + ", s2: " + s2); - } - - public static void fail() { - System.err.println("fail"); - Thread.dumpStack(); - } - - public static void fail(String message) { - System.err.println("fail: " + message); - Thread.dumpStack(); - } - - public static int Min2Print2(int a, int b) { - int[] values = new int[] { a, b }; - System.err.println("Running Main.Min2Print2(" + Arrays.toString(values) + ")"); - return a > b ? a : b; - } - - public static int Min2Print3(int a, int b, int c) { - int[] values = new int[] { a, b, c }; - System.err.println("Running Main.Min2Print3(" + Arrays.toString(values) + ")"); - return a > b ? a : b; - } - - public static int Min2Print6(int a, int b, int c, int d, int e, int f) { - int[] values = new int[] { a, b, c, d, e, f }; - System.err.println("Running Main.Min2Print6(" + Arrays.toString(values) + ")"); - return a > b ? a : b; - } - - public static int Min2Print26(int a, int b, int c, int d, - int e, int f, int g, int h, - int i, int j, int k, int l, - int m, int n, int o, int p, - int q, int r, int s, int t, - int u, int v, int w, int x, - int y, int z) { - int[] values = new int[] { a, b, c, d, e, f, g, h, i, j, k, l, m, - n, o, p, q, r, s, t, u, v, w, x, y, z }; - System.err.println("Running Main.Min2Print26(" + Arrays.toString(values) + ")"); - return a > b ? a : b; - } - - public static void $opt$BasicTest() throws Throwable { - MethodHandle mh; - mh = MethodHandles.lookup().findStatic( - Main.class, "Min2Print2", MethodType.methodType(int.class, int.class, int.class)); - assertEquals((int) mh.invokeExact(33, -4), 33); - assertEquals((int) mh.invokeExact(-4, 33), 33); - - mh = MethodHandles.lookup().findStatic( - Main.class, "Min2Print3", - MethodType.methodType(int.class, int.class, int.class, int.class)); - assertEquals((int) mh.invokeExact(33, -4, 17), 33); - assertEquals((int) mh.invokeExact(-4, 17, 33), 17); - assertEquals((int) mh.invokeExact(17, 33, -4), 33); - - mh = MethodHandles.lookup().findStatic( - Main.class, "Min2Print6", - MethodType.methodType( - int.class, int.class, int.class, int.class, int.class, int.class, int.class)); - assertEquals((int) mh.invokeExact(33, -4, 77, 88, 99, 111), 33); - try { - // Too few arguments - assertEquals((int) mh.invokeExact(33, -4, 77, 88), 33); - fail("No WMTE for too few arguments"); - } catch (WrongMethodTypeException e) {} - try { - // Too many arguments - assertEquals((int) mh.invokeExact(33, -4, 77, 88, 89, 90, 91), 33); - fail("No WMTE for too many arguments"); - } catch (WrongMethodTypeException e) {} - assertEquals((int) mh.invokeExact(-4, 77, 88, 99, 111, 33), 77); - assertEquals((int) mh.invokeExact(77, 88, 99, 111, 33, -4), 88); - assertEquals((int) mh.invokeExact(88, 99, 111, 33, -4, 77), 99); - assertEquals((int) mh.invokeExact(99, 111, 33, -4, 77, 88), 111); - assertEquals((int) mh.invokeExact(111, 33, -4, 77, 88, 99), 111); - - // A preposterous number of arguments. - mh = MethodHandles.lookup().findStatic( - Main.class, "Min2Print26", - MethodType.methodType( - // Return-type - int.class, - // Arguments - int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, - int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, - int.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, - int.class, int.class)); - assertEquals(1, (int) mh.invokeExact(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25)); - assertEquals(25, (int) mh.invokeExact(25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24)); - assertEquals(25, (int) mh.invokeExact(24, 25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23)); - - try { - // Wrong argument type - mh.invokeExact("a"); - fail("No WMTE for wrong arguments"); - } catch (WrongMethodTypeException wmte) {} - - try { - // Invoke on null handle. - MethodHandle mh0 = null; - mh0.invokeExact("bad"); - fail("No NPE for you"); - } catch (NullPointerException npe) {} - - System.err.println("BasicTest done."); - } - - private static boolean And(boolean lhs, boolean rhs) { - return lhs & rhs; - } - - private static boolean Xor(boolean lhs, boolean rhs) { - return lhs ^ rhs; - } - - private static String Multiply(String value, int n) { - String result = ""; - for (int i = 0; i < n; ++i) { - result = value + result; - } - return result; - } - - private static byte Multiply(byte value, byte n) { - return (byte)(value * n); - } - - private static short Multiply(short value, short n) { - return (short)(value * n); - } - - private static int Multiply(int value, int n) { - return value * n; - } - - private static long Multiply(long value, long n) { - return value * n; - } - - private static float Multiply(float value, float n) { - return value * n; - } - - private static double Multiply(double value, double n) { - return value * n; - } - - private static char Next(char c) { - return (char)(c + 1); - } - - public static void $opt$ReturnBooleanTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = - lookup.findStatic(Main.class, "And", - MethodType.methodType(boolean.class, boolean.class, boolean.class)); - assertEquals(true, (boolean) mh.invokeExact(true, true)); - assertEquals(false, (boolean) mh.invokeExact(true, false)); - assertEquals(false, (boolean) mh.invokeExact(false, true)); - assertEquals(false, (boolean) mh.invokeExact(false, false)); - assertEquals(true, (boolean) mh.invoke(true, true)); - assertEquals(false, (boolean) mh.invoke(true, false)); - assertEquals(false, (boolean) mh.invoke(false, true)); - assertEquals(false, (boolean) mh.invoke(false, false)); - - mh = lookup.findStatic(Main.class, "Xor", - MethodType.methodType(boolean.class, boolean.class, boolean.class)); - assertEquals(false, (boolean) mh.invokeExact(true, true)); - assertEquals(true, (boolean) mh.invokeExact(true, false)); - assertEquals(true, (boolean) mh.invokeExact(false, true)); - assertEquals(false, (boolean) mh.invokeExact(false, false)); - assertEquals(false, (boolean) mh.invoke(true, true)); - assertEquals(true, (boolean) mh.invoke(true, false)); - assertEquals(true, (boolean) mh.invoke(false, true)); - assertEquals(false, (boolean) mh.invoke(false, false)); - - System.err.println("$opt$ReturnBooleanTest done."); - } - - public static void $opt$ReturnCharTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Next", - MethodType.methodType(char.class, char.class)); - assertEquals('B', (char) mh.invokeExact('A')); - assertEquals((char) -55, (char) mh.invokeExact((char) -56)); - System.err.println("$opt$ReturnCharTest done."); - } - - public static void $opt$ReturnByteTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Multiply", - MethodType.methodType(byte.class, byte.class, byte.class)); - assertEquals((byte) 30, (byte) mh.invokeExact((byte) 10, (byte) 3)); - assertEquals((byte) -90, (byte) mh.invoke((byte) -10, (byte) 9)); - System.err.println("$opt$ReturnByteTest done."); - } - - public static void $opt$ReturnShortTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Multiply", - MethodType.methodType(short.class, short.class, short.class)); - assertEquals((short) 3000, (short) mh.invokeExact((short) 1000, (short) 3)); - assertEquals((short) -3000, (short) mh.invoke((short) -1000, (short) 3)); - System.err.println("$opt$ReturnShortTest done."); - } - - public static void $opt$ReturnIntTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Multiply", - MethodType.methodType(int.class, int.class, int.class)); - assertEquals(3_000_000, (int) mh.invokeExact(1_000_000, 3)); - assertEquals(-3_000_000, (int) mh.invoke(-1_000, 3_000)); - System.err.println("$opt$ReturnIntTest done."); - } - - public static void $opt$ReturnLongTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Multiply", - MethodType.methodType(long.class, long.class, long.class)); - assertEquals(4_294_967_295_000L, (long) mh.invokeExact(1000L, 4_294_967_295L)); - assertEquals(-4_294_967_295_000L, (long) mh.invoke(-1000L, 4_294_967_295L)); - System.err.println("$opt$ReturnLongTest done."); - } - - public static void $opt$ReturnFloatTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Multiply", - MethodType.methodType(float.class, float.class, float.class)); - assertEquals(3.0F, (float) mh.invokeExact(1000.0F, 3e-3F)); - assertEquals(-3.0F, (float) mh.invoke(-1000.0F, 3e-3F)); - System.err.println("$opt$ReturnFloatTest done."); - } - - public static void $opt$ReturnDoubleTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Multiply", - MethodType.methodType(double.class, double.class, double.class)); - assertEquals(3033000.0, (double) mh.invokeExact(1000.0, 3.033e3)); - assertEquals(-3033000.0, (double) mh.invoke(-1000.0, 3.033e3)); - System.err.println("$opt$ReturnDoubleTest done."); - } - - public static void $opt$ReturnStringTest() throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - MethodHandle mh = lookup.findStatic(Main.class, "Multiply", - MethodType.methodType(String.class, String.class, int.class)); - assertEquals("100010001000", (String) mh.invokeExact("1000", 3)); - assertEquals("100010001000", (String) mh.invoke("1000", 3)); - System.err.println("$opt$ReturnStringTest done."); - } - - public static void ReturnValuesTest() throws Throwable { - $opt$ReturnBooleanTest(); - $opt$ReturnCharTest(); - $opt$ReturnByteTest(); - $opt$ReturnShortTest(); - $opt$ReturnIntTest(); - $opt$ReturnLongTest(); - $opt$ReturnFloatTest(); - $opt$ReturnDoubleTest(); - $opt$ReturnStringTest(); - System.err.println("ReturnValuesTest done."); - } - - static class ValueHolder { - public boolean m_z; - public static boolean s_z; - } - - public static void $opt$AccessorsTest() throws Throwable { - ValueHolder valueHolder = new ValueHolder(); - MethodHandles.Lookup lookup = MethodHandles.lookup(); - - MethodHandle setMember = lookup.findSetter(ValueHolder.class, "m_z", boolean.class); - MethodHandle getMember = lookup.findGetter(ValueHolder.class, "m_z", boolean.class); - MethodHandle setStatic = lookup.findStaticSetter(ValueHolder.class, "s_z", boolean.class); - MethodHandle getStatic = lookup.findStaticGetter(ValueHolder.class, "s_z", boolean.class); - - boolean [] values = { false, true, false, true, false }; - for (boolean value : values) { - assertEquals((boolean) getStatic.invoke(), ValueHolder.s_z); - setStatic.invoke(value); - ValueHolder.s_z = value; - assertEquals(ValueHolder.s_z, value); - assertEquals((boolean) getStatic.invoke(), value); - - assertEquals((boolean) getMember.invoke(valueHolder), valueHolder.m_z); - setMember.invoke(valueHolder, value); - valueHolder.m_z = value; - assertEquals(valueHolder.m_z, value); - assertEquals((boolean) getMember.invoke(valueHolder), value); - } - } - - public static void main(String[] args) throws Throwable { - $opt$BasicTest(); - ReturnValuesTest(); - $opt$AccessorsTest(); - } -} diff --git a/test/957-methodhandle-transforms/src/Main.java b/test/957-methodhandle-transforms/src/Main.java index 9e79ff4c10..5806509fc3 100644 --- a/test/957-methodhandle-transforms/src/Main.java +++ b/test/957-methodhandle-transforms/src/Main.java @@ -40,17 +40,17 @@ public class Main { IllegalArgumentException.class); if (handle.type().returnType() != String.class) { - fail("Unexpected return type for handle: " + handle + + System.out.println("Unexpected return type for handle: " + handle + " [ " + handle.type() + "]"); } final IllegalArgumentException iae = new IllegalArgumentException("boo!"); try { handle.invoke(iae); - fail("Expected an exception of type: java.lang.IllegalArgumentException"); + System.out.println("Expected an exception of type: java.lang.IllegalArgumentException"); } catch (IllegalArgumentException expected) { if (expected != iae) { - fail("Wrong exception: expected " + iae + " but was " + expected); + System.out.println("Wrong exception: expected " + iae + " but was " + expected); } } } @@ -262,7 +262,7 @@ public class Main { array[0] = 42; int value = (int) getter.invoke(array, 0); if (value != 42) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } try { @@ -284,7 +284,7 @@ public class Main { array[0] = 42; long value = (long) getter.invoke(array, 0); if (value != 42l) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -294,7 +294,7 @@ public class Main { array[0] = 42; short value = (short) getter.invoke(array, 0); if (value != 42l) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -304,7 +304,7 @@ public class Main { array[0] = 42; char value = (char) getter.invoke(array, 0); if (value != 42l) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -314,7 +314,7 @@ public class Main { array[0] = (byte) 0x8; byte value = (byte) getter.invoke(array, 0); if (value != (byte) 0x8) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -324,7 +324,7 @@ public class Main { array[0] = true; boolean value = (boolean) getter.invoke(array, 0); if (!value) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -334,7 +334,7 @@ public class Main { array[0] = 42.0f; float value = (float) getter.invoke(array, 0); if (value != 42.0f) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -344,7 +344,7 @@ public class Main { array[0] = 42.0; double value = (double) getter.invoke(array, 0); if (value != 42.0) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -372,10 +372,10 @@ public class Main { setter.invoke(array, 1, 43); if (array[0] != 42) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } if (array[1] != 43) { - fail("Unexpected value: " + array[1]); + System.out.println("Unexpected value: " + array[1]); } try { @@ -396,7 +396,7 @@ public class Main { long[] array = new long[1]; setter.invoke(array, 0, 42l); if (array[0] != 42l) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } } @@ -405,7 +405,7 @@ public class Main { short[] array = new short[1]; setter.invoke(array, 0, (short) 42); if (array[0] != 42l) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } } @@ -414,7 +414,7 @@ public class Main { char[] array = new char[1]; setter.invoke(array, 0, (char) 42); if (array[0] != 42) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } } @@ -423,7 +423,7 @@ public class Main { byte[] array = new byte[1]; setter.invoke(array, 0, (byte) 0x8); if (array[0] != (byte) 0x8) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } } @@ -432,7 +432,7 @@ public class Main { boolean[] array = new boolean[1]; setter.invoke(array, 0, true); if (!array[0]) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } } @@ -441,7 +441,7 @@ public class Main { float[] array = new float[1]; setter.invoke(array, 0, 42.0f); if (array[0] != 42.0f) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } } @@ -450,7 +450,7 @@ public class Main { double[] array = new double[1]; setter.invoke(array, 0, 42.0); if (array[0] != 42.0) { - fail("Unexpected value: " + array[0]); + System.out.println("Unexpected value: " + array[0]); } } @@ -471,7 +471,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(boolean.class); boolean value = (boolean) identity.invoke(false); if (value) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -479,7 +479,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(byte.class); byte value = (byte) identity.invoke((byte) 0x8); if (value != (byte) 0x8) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -487,7 +487,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(char.class); char value = (char) identity.invoke((char) -56); if (value != (char) -56) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -495,7 +495,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(short.class); short value = (short) identity.invoke((short) -59); if (value != (short) -59) { - fail("Unexpected value: " + Short.toString(value)); + System.out.println("Unexpected value: " + value); } } @@ -503,7 +503,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(int.class); int value = (int) identity.invoke(52); if (value != 52) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -511,7 +511,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(long.class); long value = (long) identity.invoke(-76l); if (value != (long) -76) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -519,7 +519,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(float.class); float value = (float) identity.invoke(56.0f); if (value != (float) 56.0f) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -527,7 +527,7 @@ public class Main { MethodHandle identity = MethodHandles.identity(double.class); double value = (double) identity.invoke((double) 72.0); if (value != (double) 72.0) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -544,28 +544,28 @@ public class Main { MethodHandle constant = MethodHandles.constant(int.class, 56); int value = (int) constant.invoke(); if (value != 56) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } // short constant values are converted to int. constant = MethodHandles.constant(int.class, (short) 52); value = (int) constant.invoke(); if (value != 52) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } // char constant values are converted to int. constant = MethodHandles.constant(int.class, (char) 'b'); value = (int) constant.invoke(); if (value != (int) 'b') { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } // int constant values are converted to int. constant = MethodHandles.constant(int.class, (byte) 0x1); value = (int) constant.invoke(); if (value != 1) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } // boolean, float, double and long primitive constants are not convertible @@ -600,13 +600,13 @@ public class Main { MethodHandle constant = MethodHandles.constant(long.class, 56l); long value = (long) constant.invoke(); if (value != 56l) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } constant = MethodHandles.constant(long.class, (int) 56); value = (long) constant.invoke(); if (value != 56l) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -615,7 +615,7 @@ public class Main { MethodHandle constant = MethodHandles.constant(byte.class, (byte) 0x12); byte value = (byte) constant.invoke(); if (value != (byte) 0x12) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -624,7 +624,7 @@ public class Main { MethodHandle constant = MethodHandles.constant(boolean.class, true); boolean value = (boolean) constant.invoke(); if (!value) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -633,7 +633,7 @@ public class Main { MethodHandle constant = MethodHandles.constant(char.class, 'f'); char value = (char) constant.invoke(); if (value != 'f') { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -642,7 +642,7 @@ public class Main { MethodHandle constant = MethodHandles.constant(short.class, (short) 123); short value = (short) constant.invoke(); if (value != (short) 123) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -651,7 +651,7 @@ public class Main { MethodHandle constant = MethodHandles.constant(float.class, 56.0f); float value = (float) constant.invoke(); if (value != 56.0f) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -660,7 +660,7 @@ public class Main { MethodHandle constant = MethodHandles.constant(double.class, 256.0); double value = (double) constant.invoke(); if (value != 256.0) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -678,13 +678,13 @@ public class Main { char value = (char) stringCharAt.invoke("foo", 0); if (value != 'f') { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } MethodHandle bound = stringCharAt.bindTo("foo"); value = (char) bound.invoke(0); if (value != 'f') { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } try { @@ -706,7 +706,7 @@ public class Main { bound = integerParseInt.bindTo("78452"); int intValue = (int) bound.invoke(); if (intValue != 78452) { - fail("Unexpected value: " + intValue); + System.out.println("Unexpected value: " + intValue); } } @@ -745,11 +745,11 @@ public class Main { boolean value = (boolean) adapter.invoke((int) 42); if (!value) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } value = (boolean) adapter.invoke((int) 43); if (value) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -764,7 +764,7 @@ public class Main { int value = (int) adapter.invoke("56"); if (value != 57) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } @@ -779,7 +779,7 @@ public class Main { int value = (int) adapter.invoke(); if (value != 42) { - fail("Unexpected value: " + value); + System.out.println("Unexpected value: " + value); } } } @@ -791,7 +791,7 @@ public class Main { return; } - fail("Unexpected arguments: " + a + ", " + b + ", " + c + System.out.println("Unexpected arguments: " + a + ", " + b + ", " + c + ", " + d + ", " + e + ", " + f + ", " + g + ", " + h); } @@ -800,7 +800,7 @@ public class Main { return; } - fail("Unexpected arguments: " + a + ", " + b); + System.out.println("Unexpected arguments: " + a + ", " + b); } public static void testPermuteArguments() throws Throwable { @@ -893,11 +893,6 @@ public class Main { Thread.dumpStack(); } - public static void fail(String message) { - System.out.println("fail: " + message); - Thread.dumpStack(); - } - public static void assertEquals(String s1, String s2) { if (s1 == s2) { return; |