Merge "Revert "ART: Compiler support for invoke-polymorphic.""
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 86d92ff..4180e0e 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -487,7 +487,7 @@
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 9ca7b19..f00648f 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -367,12 +367,6 @@
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 7e2dd48..6366b98 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -426,12 +426,12 @@
}
- // 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);
@@ -495,8 +495,6 @@
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 3bb97b6..541a1c5 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -2370,14 +2370,6 @@
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 227ad0f..9aaeadb 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -4080,14 +4080,6 @@
__ 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 fd51aab..c769dec 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -2445,14 +2445,6 @@
}
}
-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 ed0d997..bc62854 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -5154,14 +5154,6 @@
}
}
-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 0ea5bb0..1b9c6da 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -3256,14 +3256,6 @@
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 624cf81..a9b717d 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -2244,14 +2244,6 @@
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 152a9ed..2614735 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -2423,14 +2423,6 @@
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 f6fba88..09dcefa 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -464,11 +464,6 @@
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 d7da46b..c970e5c 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -308,10 +308,8 @@
}
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 3cfabdd..009d549 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 @@
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 @@
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 aef0b94..f29e522 100644
--- a/compiler/optimizing/instruction_builder.h
+++ b/compiler/optimizing/instruction_builder.h
@@ -175,17 +175,6 @@
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 4f30b11..2856c3e 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -943,10 +943,6 @@
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 064e119..ea9a94c 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1291,7 +1291,6 @@
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 @@
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 ab4f9e9..a3fce02 100644
--- a/compiler/utils/assembler_thumb_test_expected.cc.inc
+++ b/compiler/utils/assembler_thumb_test_expected.cc.inc
@@ -5610,7 +5610,7 @@
" 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 9e82f01..4d4ebdc 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_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 eba0c87..8b1e038 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_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 ea95bbc..62c29cf 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -468,7 +468,7 @@
* 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 @@
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 5b3a314..facd563 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 @@
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 e4972da..bfdddf7 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -98,7 +98,7 @@
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 a44f79e..c30272e 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -428,8 +428,6 @@
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 @@
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 37f3ac9..7b8974f 100644
--- a/runtime/dex_instruction.cc
+++ b/runtime/dex_instruction.cc
@@ -358,7 +358,7 @@
}
break;
case k35c: {
- uint32_t arg[kMaxVarArgRegs];
+ uint32_t arg[5];
GetVarArgs(arg);
switch (Opcode()) {
case FILLED_NEW_ARRAY:
@@ -443,50 +443,8 @@
}
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 2d0932a..64030f3 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_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 8ce61c1..78dad94 100644
--- a/runtime/entrypoints/quick/quick_default_init_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_default_init_entrypoints.h
@@ -106,7 +106,6 @@
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 4d5d6de..0911aeb 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 b22afc3..a3e5b55 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 @@
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 96e17da..6866abb 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -121,10 +121,10 @@
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 @@
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 685aa04..dc103e2 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
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 40b6d73..bdd4ca6 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2727,7 +2727,6 @@
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 d54a80d..a3ef9bc 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -1418,7 +1418,7 @@
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),
@@ -1542,14 +1542,13 @@
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 25a179b..715b237 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3106,16 +3106,19 @@
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 a423ca6..0000000
--- 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 f47ee23..0000000
--- 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 f1dbb61..0000000
--- 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 a9f1822..0000000
--- 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 20a8fec..0000000
--- 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 9e79ff4..5806509 100644
--- a/test/957-methodhandle-transforms/src/Main.java
+++ b/test/957-methodhandle-transforms/src/Main.java
@@ -40,17 +40,17 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
int value = (int) adapter.invoke("56");
if (value != 57) {
- fail("Unexpected value: " + value);
+ System.out.println("Unexpected value: " + value);
}
}
@@ -779,7 +779,7 @@
int value = (int) adapter.invoke();
if (value != 42) {
- fail("Unexpected value: " + value);
+ System.out.println("Unexpected value: " + value);
}
}
}
@@ -791,7 +791,7 @@
return;
}
- fail("Unexpected arguments: " + a + ", " + b + ", " + c
+ System.out.println("Unexpected arguments: " + a + ", " + b + ", " + c
+ ", " + d + ", " + e + ", " + f + ", " + g + ", " + h);
}
@@ -800,7 +800,7 @@
return;
}
- fail("Unexpected arguments: " + a + ", " + b);
+ System.out.println("Unexpected arguments: " + a + ", " + b);
}
public static void testPermuteArguments() throws Throwable {
@@ -893,11 +893,6 @@
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;