diff options
19 files changed, 299 insertions, 148 deletions
diff --git a/compiler/optimizing/critical_native_abi_fixup_arm.cc b/compiler/optimizing/critical_native_abi_fixup_arm.cc index 03fb26bf1e..77e156608b 100644 --- a/compiler/optimizing/critical_native_abi_fixup_arm.cc +++ b/compiler/optimizing/critical_native_abi_fixup_arm.cc @@ -74,7 +74,8 @@ static void FixUpArguments(HInvokeStaticOrDirect* invoke) { dispatch_info, kStatic, target_method, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !block->GetGraph()->IsDebuggable()); // The intrinsic has no side effects and does not need environment or dex cache on ARM. new_input->SetSideEffects(SideEffects::None()); IntrinsicOptimizations opt(new_input); diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index da498d4277..4bf62f3c26 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1321,7 +1321,8 @@ bool HInliner::TryDevirtualize(HInvoke* invoke_instruction, dispatch_info, kDirect, MethodReference(method->GetDexFile(), method->GetDexMethodIndex()), - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInputsRef inputs = invoke_instruction->GetInputs(); DCHECK_EQ(inputs.size(), invoke_instruction->GetNumberOfArguments()); for (size_t index = 0; index != inputs.size(); ++index) { @@ -1527,7 +1528,8 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction, invoke_instruction->GetMethodReference(), // Use existing invoke's method's reference. method, MethodReference(method->GetDexFile(), method->GetDexMethodIndex()), - method->GetMethodIndex()); + method->GetMethodIndex(), + !graph_->IsDebuggable()); DCHECK_NE(new_invoke->GetIntrinsic(), Intrinsics::kNone); HInputsRef inputs = invoke_instruction->GetInputs(); for (size_t index = 0; index != inputs.size(); ++index) { diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index e99b8a02d1..2576b02c9f 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -469,6 +469,9 @@ void HInstructionBuilder::BuildIntrinsic(ArtMethod* method) { current_block_ = graph_->GetEntryBlock(); InitializeBlockLocals(); InitializeParameters(); + if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) { + AppendInstruction(new (allocator_) HMethodEntryHook(0u)); + } AppendInstruction(new (allocator_) HGoto(0u)); // Fill the body. @@ -504,14 +507,21 @@ void HInstructionBuilder::BuildIntrinsic(ArtMethod* method) { dispatch_info, invoke_type, target_method, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false); } // Add the return instruction. if (return_type_ == DataType::Type::kVoid) { + if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) { + AppendInstruction(new (allocator_) HMethodExitHook(graph_->GetNullConstant(), kNoDexPc)); + } AppendInstruction(new (allocator_) HReturnVoid()); } else { + if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) { + AppendInstruction(new (allocator_) HMethodExitHook(latest_result_, kNoDexPc)); + } AppendInstruction(new (allocator_) HReturn(latest_result_)); } @@ -1050,7 +1060,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, dispatch_info, invoke_type, resolved_method_reference, - HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit); + HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit, + !graph_->IsDebuggable()); return HandleStringInit(invoke, operands, shorty); } @@ -1063,7 +1074,7 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, } // Try to build an HIR replacement for the intrinsic. - if (UNLIKELY(resolved_method->IsIntrinsic())) { + if (UNLIKELY(resolved_method->IsIntrinsic()) && !graph_->IsDebuggable()) { // All intrinsics are in the primary boot image, so their class can always be referenced // and we do not need to rely on the implicit class initialization check. The class should // be initialized but we do not require that here. @@ -1114,7 +1125,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, dispatch_info, invoke_type, resolved_method_reference, - clinit_check_requirement); + clinit_check_requirement, + !graph_->IsDebuggable()); if (clinit_check != nullptr) { // Add the class initialization check as last input of `invoke`. DCHECK_EQ(clinit_check_requirement, HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit); @@ -1130,7 +1142,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, method_reference, resolved_method, resolved_method_reference, - /*vtable_index=*/ imt_or_vtable_index); + /*vtable_index=*/ imt_or_vtable_index, + !graph_->IsDebuggable()); } else { DCHECK_EQ(invoke_type, kInterface); if (kIsDebugBuild) { @@ -1151,7 +1164,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, resolved_method, resolved_method_reference, /*imt_index=*/ imt_or_vtable_index, - load_kind); + load_kind, + !graph_->IsDebuggable()); } return HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false); } @@ -1350,12 +1364,14 @@ bool HInstructionBuilder::BuildInvokePolymorphic(uint32_t dex_pc, method_reference, resolved_method, resolved_method_reference, - proto_idx); + proto_idx, + !graph_->IsDebuggable()); if (!HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false)) { return false; } - if (invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvoke && + if (invoke->GetIntrinsic() != Intrinsics::kNone && + invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvoke && invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvokeExact && VarHandleAccessorNeedsReturnTypeCheck(invoke, return_type)) { // Type check is needed because VarHandle intrinsics do not type check the retrieved reference. @@ -1388,7 +1404,8 @@ bool HInstructionBuilder::BuildInvokeCustom(uint32_t dex_pc, call_site_idx, return_type, dex_pc, - method_reference); + method_reference, + !graph_->IsDebuggable()); return HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false); } diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index bf51b5dcf4..0c2fd5de56 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -2465,7 +2465,7 @@ void InstructionSimplifierVisitor::SimplifySystemArrayCopy(HInvoke* instruction) DCHECK(method != nullptr); DCHECK(method->IsStatic()); DCHECK(method->GetDeclaringClass() == system); - invoke->SetResolvedMethod(method); + invoke->SetResolvedMethod(method, !codegen_->GetGraph()->IsDebuggable()); // Sharpen the new invoke. Note that we do not update the dex method index of // the invoke, as we would need to look it up in the current dex file, and it // is unlikely that it exists. The most usual situation for such typed diff --git a/compiler/optimizing/load_store_analysis_test.cc b/compiler/optimizing/load_store_analysis_test.cc index 635f1b5fb2..8c6812f184 100644 --- a/compiler/optimizing/load_store_analysis_test.cc +++ b/compiler/optimizing/load_store_analysis_test.cc @@ -894,7 +894,8 @@ TEST_F(LoadStoreAnalysisTest, PartialEscape) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left = new (GetAllocator()) HGoto(); call_left->SetRawInputAt(0, new_inst); left->AddInstruction(call_left); @@ -1003,7 +1004,8 @@ TEST_F(LoadStoreAnalysisTest, PartialEscape2) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left = new (GetAllocator()) HGoto(); call_left->SetRawInputAt(0, new_inst); left->AddInstruction(call_left); @@ -1126,7 +1128,8 @@ TEST_F(LoadStoreAnalysisTest, PartialEscape3) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left = new (GetAllocator()) HGoto(); call_left->SetRawInputAt(0, new_inst); left->AddInstruction(call_left); @@ -1406,7 +1409,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscapeAdjacentNoPredicated) { {}, InvokeType::kStatic, {nullptr, 0}, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left = new (GetAllocator()) HGoto(); call_left->SetRawInputAt(0, new_inst); left->AddInstruction(call_left); @@ -1507,7 +1511,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscapeAdjacent) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left = new (GetAllocator()) HGoto(); call_left->SetRawInputAt(0, new_inst); left->AddInstruction(call_left); @@ -1618,7 +1623,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscape) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left = new (GetAllocator()) HGoto(); call_left->SetRawInputAt(0, new_inst); left->AddInstruction(call_left); @@ -1634,7 +1640,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscape) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst, c0, nullptr, @@ -1803,7 +1810,8 @@ TEST_F(LoadStoreAnalysisTest, DoubleDiamondEscape) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left = new (GetAllocator()) HGoto(); call_left->SetRawInputAt(0, new_inst); high_left->AddInstruction(call_left); @@ -1859,7 +1867,8 @@ TEST_F(LoadStoreAnalysisTest, DoubleDiamondEscape) { {}, InvokeType::kStatic, { nullptr, 0 }, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_low_left = new (GetAllocator()) HGoto(); call_low_left->SetRawInputAt(0, new_inst); low_left->AddInstruction(call_low_left); @@ -2016,7 +2025,8 @@ TEST_F(LoadStoreAnalysisTest, PartialPhiPropagation1) { {}, InvokeType::kStatic, {nullptr, 0}, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); HInstruction* goto_left_merge = new (GetAllocator()) HGoto(); left_phi->SetRawInputAt(0, obj_param); left_phi->SetRawInputAt(1, new_inst); diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 8d678cd33d..83b58763a4 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -3571,8 +3571,8 @@ static inline IntrinsicExceptions GetExceptionsIntrinsic(Intrinsics i) { return kCanThrow; } -void HInvoke::SetResolvedMethod(ArtMethod* method) { - if (method != nullptr && method->IsIntrinsic()) { +void HInvoke::SetResolvedMethod(ArtMethod* method, bool enable_intrinsic_opt) { + if (method != nullptr && method->IsIntrinsic() && enable_intrinsic_opt) { Intrinsics intrinsic = static_cast<Intrinsics>(method->GetIntrinsic()); SetIntrinsic(intrinsic, NeedsEnvironmentIntrinsic(intrinsic), diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 822ac9a0a1..5ca723a3c3 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -4757,7 +4757,7 @@ class HInvoke : public HVariableInputSizeInstruction { bool IsIntrinsic() const { return intrinsic_ != Intrinsics::kNone; } ArtMethod* GetResolvedMethod() const { return resolved_method_; } - void SetResolvedMethod(ArtMethod* method); + void SetResolvedMethod(ArtMethod* method, bool enable_intrinsic_opt); MethodReference GetMethodReference() const { return method_reference_; } @@ -4786,7 +4786,8 @@ class HInvoke : public HVariableInputSizeInstruction { MethodReference method_reference, ArtMethod* resolved_method, MethodReference resolved_method_reference, - InvokeType invoke_type) + InvokeType invoke_type, + bool enable_intrinsic_opt) : HVariableInputSizeInstruction( kind, return_type, @@ -4802,7 +4803,7 @@ class HInvoke : public HVariableInputSizeInstruction { intrinsic_optimizations_(0) { SetPackedField<InvokeTypeField>(invoke_type); SetPackedFlag<kFlagCanThrow>(true); - SetResolvedMethod(resolved_method); + SetResolvedMethod(resolved_method, enable_intrinsic_opt); } DEFAULT_COPY_CONSTRUCTOR(Invoke); @@ -4835,7 +4836,8 @@ class HInvokeUnresolved final : public HInvoke { method_reference, nullptr, MethodReference(nullptr, 0u), - invoke_type) { + invoke_type, + /* enable_intrinsic_opt= */ false) { } bool IsClonable() const override { return true; } @@ -4858,7 +4860,8 @@ class HInvokePolymorphic final : public HInvoke { // to pass intrinsic information to the HInvokePolymorphic node. ArtMethod* resolved_method, MethodReference resolved_method_reference, - dex::ProtoIndex proto_idx) + dex::ProtoIndex proto_idx, + bool enable_intrinsic_opt) : HInvoke(kInvokePolymorphic, allocator, number_of_arguments, @@ -4868,7 +4871,8 @@ class HInvokePolymorphic final : public HInvoke { method_reference, resolved_method, resolved_method_reference, - kPolymorphic), + kPolymorphic, + enable_intrinsic_opt), proto_idx_(proto_idx) { } @@ -4890,7 +4894,8 @@ class HInvokeCustom final : public HInvoke { uint32_t call_site_index, DataType::Type return_type, uint32_t dex_pc, - MethodReference method_reference) + MethodReference method_reference, + bool enable_intrinsic_opt) : HInvoke(kInvokeCustom, allocator, number_of_arguments, @@ -4900,7 +4905,8 @@ class HInvokeCustom final : public HInvoke { method_reference, /* resolved_method= */ nullptr, MethodReference(nullptr, 0u), - kStatic), + kStatic, + enable_intrinsic_opt), call_site_index_(call_site_index) { } @@ -4947,7 +4953,8 @@ class HInvokeStaticOrDirect final : public HInvoke { DispatchInfo dispatch_info, InvokeType invoke_type, MethodReference resolved_method_reference, - ClinitCheckRequirement clinit_check_requirement) + ClinitCheckRequirement clinit_check_requirement, + bool enable_intrinsic_opt) : HInvoke(kInvokeStaticOrDirect, allocator, number_of_arguments, @@ -4960,7 +4967,8 @@ class HInvokeStaticOrDirect final : public HInvoke { method_reference, resolved_method, resolved_method_reference, - invoke_type), + invoke_type, + enable_intrinsic_opt), dispatch_info_(dispatch_info) { SetPackedField<ClinitCheckRequirementField>(clinit_check_requirement); } @@ -5172,7 +5180,8 @@ class HInvokeVirtual final : public HInvoke { MethodReference method_reference, ArtMethod* resolved_method, MethodReference resolved_method_reference, - uint32_t vtable_index) + uint32_t vtable_index, + bool enable_intrinsic_opt) : HInvoke(kInvokeVirtual, allocator, number_of_arguments, @@ -5182,7 +5191,8 @@ class HInvokeVirtual final : public HInvoke { method_reference, resolved_method, resolved_method_reference, - kVirtual), + kVirtual, + enable_intrinsic_opt), vtable_index_(vtable_index) { } @@ -5234,7 +5244,8 @@ class HInvokeInterface final : public HInvoke { ArtMethod* resolved_method, MethodReference resolved_method_reference, uint32_t imt_index, - MethodLoadKind load_kind) + MethodLoadKind load_kind, + bool enable_intrinsic_opt) : HInvoke(kInvokeInterface, allocator, number_of_arguments + (NeedsCurrentMethod(load_kind) ? 1 : 0), @@ -5244,7 +5255,8 @@ class HInvokeInterface final : public HInvoke { method_reference, resolved_method, resolved_method_reference, - kInterface), + kInterface, + enable_intrinsic_opt), imt_index_(imt_index), hidden_argument_load_kind_(load_kind) { } diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index f18ffc7f83..2e05c41f01 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -461,7 +461,8 @@ class OptimizingUnitTestHelper { HInvokeStaticOrDirect::DispatchInfo{}, InvokeType::kStatic, /* resolved_method_reference= */ method_reference, - HInvokeStaticOrDirect::ClinitCheckRequirement::kNone); + HInvokeStaticOrDirect::ClinitCheckRequirement::kNone, + !graph_->IsDebuggable()); for (auto [ins, idx] : ZipCount(MakeIterationRange(args))) { res->SetRawInputAt(idx, ins); } diff --git a/test/2263-method-trace-jit/Android.bp b/test/2263-method-trace-jit/Android.bp new file mode 100644 index 0000000000..798d6dae02 --- /dev/null +++ b/test/2263-method-trace-jit/Android.bp @@ -0,0 +1,40 @@ +// Generated by `regen-test-files`. Do not edit manually. + +// Build rules for ART run-test `2263-method-trace-jit`. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "art_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["art_license"], +} + +// Test's Dex code. +java_test { + name: "art-run-test-2263-method-trace-jit", + defaults: ["art-run-test-defaults"], + test_config_template: ":art-run-test-target-no-test-suite-tag-template", + srcs: ["src/**/*.java"], + data: [ + ":art-run-test-2263-method-trace-jit-expected-stdout", + ":art-run-test-2263-method-trace-jit-expected-stderr", + ], +} + +// Test's expected standard output. +genrule { + name: "art-run-test-2263-method-trace-jit-expected-stdout", + out: ["art-run-test-2263-method-trace-jit-expected-stdout.txt"], + srcs: ["expected-stdout.txt"], + cmd: "cp -f $(in) $(out)", +} + +// Test's expected standard error. +genrule { + name: "art-run-test-2263-method-trace-jit-expected-stderr", + out: ["art-run-test-2263-method-trace-jit-expected-stderr.txt"], + srcs: ["expected-stderr.txt"], + cmd: "cp -f $(in) $(out)", +} diff --git a/test/2263-method-trace-jit/expected-stderr.txt b/test/2263-method-trace-jit/expected-stderr.txt new file mode 120000 index 0000000000..0abcd1b926 --- /dev/null +++ b/test/2263-method-trace-jit/expected-stderr.txt @@ -0,0 +1 @@ +../988-method-trace/expected-stderr.txt
\ No newline at end of file diff --git a/test/2263-method-trace-jit/expected-stdout.txt b/test/2263-method-trace-jit/expected-stdout.txt new file mode 120000 index 0000000000..e5311a05d1 --- /dev/null +++ b/test/2263-method-trace-jit/expected-stdout.txt @@ -0,0 +1 @@ +../988-method-trace/expected-stdout.txt
\ No newline at end of file diff --git a/test/2263-method-trace-jit/info.txt b/test/2263-method-trace-jit/info.txt new file mode 100644 index 0000000000..f0a200dc18 --- /dev/null +++ b/test/2263-method-trace-jit/info.txt @@ -0,0 +1,15 @@ +Tests method tracing in JVMTI + +This test is sensitive to the internal implementations of: + * java.lang.Error + * java.lang.Integer + * java.lang.Math + * java.lang.String + * java.lang.System + * java.util.ArrayList + * java.util.Arrays + * java.util.StringBuilder + * all super-classes and super-interfaces of the above types. + +Changes to the internal implementation of these classes might (or might not) +change the output of this test. diff --git a/test/2263-method-trace-jit/run.py b/test/2263-method-trace-jit/run.py new file mode 100644 index 0000000000..c02159d344 --- /dev/null +++ b/test/2263-method-trace-jit/run.py @@ -0,0 +1,19 @@ +# +# Copyright 2023 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. + + +def run(ctx, args): + # Ask for stack traces to be dumped to a file rather than to stdout. + ctx.default_run(args, jvmti=True) diff --git a/test/2263-method-trace-jit/src/Main.java b/test/2263-method-trace-jit/src/Main.java new file mode 100644 index 0000000000..470f8961b1 --- /dev/null +++ b/test/2263-method-trace-jit/src/Main.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 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. + */ + +public class Main { + public static void main(String[] args) throws Exception { + // Test calls to intrinsics from JITed code. + ensureJitCompiled(art.Test988Intrinsics.class, "test"); + ensureJitCompiled(art.Test988.class, "doFibTest"); + art.Test988.run(); + } + + public static native void ensureJitCompiled(Class<?> cls, String methodName); +} diff --git a/test/2263-method-trace-jit/src/art/Test988.java b/test/2263-method-trace-jit/src/art/Test988.java new file mode 120000 index 0000000000..24dcdeb16f --- /dev/null +++ b/test/2263-method-trace-jit/src/art/Test988.java @@ -0,0 +1 @@ +../../../988-method-trace/src/art/Test988.java
\ No newline at end of file diff --git a/test/2263-method-trace-jit/src/art/Test988Intrinsics.java b/test/2263-method-trace-jit/src/art/Test988Intrinsics.java new file mode 120000 index 0000000000..7fb019c17b --- /dev/null +++ b/test/2263-method-trace-jit/src/art/Test988Intrinsics.java @@ -0,0 +1 @@ +../../../988-method-trace/src/art/Test988Intrinsics.java
\ No newline at end of file diff --git a/test/2263-method-trace-jit/src/art/Trace.java b/test/2263-method-trace-jit/src/art/Trace.java new file mode 120000 index 0000000000..5d9b44b463 --- /dev/null +++ b/test/2263-method-trace-jit/src/art/Trace.java @@ -0,0 +1 @@ +../../../jvmti-common/Trace.java
\ No newline at end of file diff --git a/test/2263-method-trace-jit/trace_fib.cc b/test/2263-method-trace-jit/trace_fib.cc new file mode 120000 index 0000000000..d6167d4894 --- /dev/null +++ b/test/2263-method-trace-jit/trace_fib.cc @@ -0,0 +1 @@ +../988-method-trace/trace_fib.cc
\ No newline at end of file diff --git a/test/988-method-trace/src/art/Test988Intrinsics.java b/test/988-method-trace/src/art/Test988Intrinsics.java index 3069f1a2c3..fe68d3ed75 100644 --- a/test/988-method-trace/src/art/Test988Intrinsics.java +++ b/test/988-method-trace/src/art/Test988Intrinsics.java @@ -22,114 +22,116 @@ package art; -class Test988Intrinsics { - // Pre-initialize *all* instance variables used so that their constructors are not in the trace. - static java.lang.String instance_java_lang_String = "some large string"; - static java.lang.StringBuffer instance_java_lang_StringBuffer = new java.lang.StringBuffer("some large string buffer"); - static java.lang.StringBuilder instance_java_lang_StringBuilder = new java.lang.StringBuilder("some large string builder"); +public class Test988Intrinsics { + // Pre-initialize *all* instance variables used so that their constructors are not in the trace. + static java.lang.String instance_java_lang_String = "some large string"; + static java.lang.StringBuffer instance_java_lang_StringBuffer = + new java.lang.StringBuffer("some large string buffer"); + static java.lang.StringBuilder instance_java_lang_StringBuilder = + new java.lang.StringBuilder("some large string builder"); - static void initialize() { - // Ensure all static variables are initialized. - // In addition, pre-load classes here so that we don't see diverging class loading traces. - java.lang.Double.class.toString(); - java.lang.Float.class.toString(); - java.lang.Integer.class.toString(); - java.lang.Long.class.toString(); - java.lang.Short.class.toString(); - java.lang.Math.class.toString(); - java.lang.Thread.class.toString(); - java.lang.String.class.toString(); - java.lang.StringBuffer.class.toString(); - java.lang.StringBuilder.class.toString(); - } + static void initialize() { + // Ensure all static variables are initialized. + // In addition, pre-load classes here so that we don't see diverging class loading traces. + java.lang.Double.class.toString(); + java.lang.Float.class.toString(); + java.lang.Integer.class.toString(); + java.lang.Long.class.toString(); + java.lang.Short.class.toString(); + java.lang.Math.class.toString(); + java.lang.Thread.class.toString(); + java.lang.String.class.toString(); + java.lang.StringBuffer.class.toString(); + java.lang.StringBuilder.class.toString(); + } - static void test() { - // Call each intrinsic from art/runtime/intrinsics_list.h to make sure they are traced. - java.lang.Double.doubleToRawLongBits(0.0); - java.lang.Double.doubleToLongBits(0.0); - java.lang.Double.isInfinite(0.0); - java.lang.Double.isNaN(0.0); - java.lang.Double.longBitsToDouble(0L); - java.lang.Float.floatToRawIntBits(0.0f); - java.lang.Float.floatToIntBits(0.0f); - java.lang.Float.isInfinite(0.0f); - java.lang.Float.isNaN(0.0f); - java.lang.Float.intBitsToFloat(0); - java.lang.Integer.reverse(0); - java.lang.Integer.reverseBytes(0); - java.lang.Integer.bitCount(0); - java.lang.Integer.compare(0, 0); - java.lang.Integer.highestOneBit(0); - java.lang.Integer.lowestOneBit(0); - java.lang.Integer.numberOfLeadingZeros(0); - java.lang.Integer.numberOfTrailingZeros(0); - java.lang.Integer.rotateRight(0, 0); - java.lang.Integer.rotateLeft(0, 0); - java.lang.Integer.signum(0); - java.lang.Long.reverse(0L); - java.lang.Long.reverseBytes(0L); - java.lang.Long.bitCount(0L); - java.lang.Long.compare(0L, 0L); - java.lang.Long.highestOneBit(0L); - java.lang.Long.lowestOneBit(0L); - java.lang.Long.numberOfLeadingZeros(0L); - java.lang.Long.numberOfTrailingZeros(0L); - java.lang.Long.rotateRight(0L, 0); - java.lang.Long.rotateLeft(0L, 0); - java.lang.Long.signum(0L); - java.lang.Short.reverseBytes((short)0); - java.lang.Math.abs(0.0); - java.lang.Math.abs(0.0f); - java.lang.Math.abs(0L); - java.lang.Math.abs(0); - java.lang.Math.min(0.0, 0.0); - java.lang.Math.min(0.0f, 0.0f); - java.lang.Math.min(0L, 0L); - java.lang.Math.min(0, 0); - java.lang.Math.max(0.0, 0.0); - java.lang.Math.max(0.0f, 0.0f); - java.lang.Math.max(0L, 0L); - java.lang.Math.max(0, 0); - java.lang.Math.cos(0.0); - java.lang.Math.sin(0.0); - java.lang.Math.acos(0.0); - java.lang.Math.asin(0.0); - java.lang.Math.atan(0.0); - java.lang.Math.atan2(0.0, 0.0); - java.lang.Math.cbrt(0.0); - java.lang.Math.cosh(0.0); - java.lang.Math.exp(0.0); - java.lang.Math.expm1(0.0); - java.lang.Math.hypot(0.0, 0.0); - java.lang.Math.log(0.0); - java.lang.Math.log10(0.0); - java.lang.Math.nextAfter(0.0, 0.0); - java.lang.Math.sinh(0.0); - java.lang.Math.tan(0.0); - java.lang.Math.tanh(0.0); - java.lang.Math.sqrt(0.0); - java.lang.Math.ceil(0.0); - java.lang.Math.floor(0.0); - java.lang.Math.rint(0.0); - java.lang.Math.round(0.0); - java.lang.Math.round(0.0f); - java.lang.Thread.currentThread(); - instance_java_lang_String.charAt(0); - instance_java_lang_String.compareTo("hello"); - instance_java_lang_String.equals((java.lang.Object)null); - instance_java_lang_String.indexOf(0); - instance_java_lang_String.indexOf(0, 0); - instance_java_lang_String.indexOf("hello"); - instance_java_lang_String.indexOf("hello", 0); - instance_java_lang_String.isEmpty(); - instance_java_lang_String.length(); - instance_java_lang_StringBuffer.append("hello"); - instance_java_lang_StringBuffer.length(); - instance_java_lang_StringBuffer.toString(); - instance_java_lang_StringBuilder.append("hello"); - instance_java_lang_StringBuilder.length(); - instance_java_lang_StringBuilder.toString(); - java.lang.Integer.valueOf(0); - java.lang.Thread.interrupted(); - } + static void test() { + // Call each intrinsic from art/runtime/intrinsics_list.h to make sure they are traced. + java.lang.Double.doubleToRawLongBits(0.0); + java.lang.Double.doubleToLongBits(0.0); + java.lang.Double.isInfinite(0.0); + java.lang.Double.isNaN(0.0); + java.lang.Double.longBitsToDouble(0L); + java.lang.Float.floatToRawIntBits(0.0f); + java.lang.Float.floatToIntBits(0.0f); + java.lang.Float.isInfinite(0.0f); + java.lang.Float.isNaN(0.0f); + java.lang.Float.intBitsToFloat(0); + java.lang.Integer.reverse(0); + java.lang.Integer.reverseBytes(0); + java.lang.Integer.bitCount(0); + java.lang.Integer.compare(0, 0); + java.lang.Integer.highestOneBit(0); + java.lang.Integer.lowestOneBit(0); + java.lang.Integer.numberOfLeadingZeros(0); + java.lang.Integer.numberOfTrailingZeros(0); + java.lang.Integer.rotateRight(0, 0); + java.lang.Integer.rotateLeft(0, 0); + java.lang.Integer.signum(0); + java.lang.Long.reverse(0L); + java.lang.Long.reverseBytes(0L); + java.lang.Long.bitCount(0L); + java.lang.Long.compare(0L, 0L); + java.lang.Long.highestOneBit(0L); + java.lang.Long.lowestOneBit(0L); + java.lang.Long.numberOfLeadingZeros(0L); + java.lang.Long.numberOfTrailingZeros(0L); + java.lang.Long.rotateRight(0L, 0); + java.lang.Long.rotateLeft(0L, 0); + java.lang.Long.signum(0L); + java.lang.Short.reverseBytes((short) 0); + java.lang.Math.abs(0.0); + java.lang.Math.abs(0.0f); + java.lang.Math.abs(0L); + java.lang.Math.abs(0); + java.lang.Math.min(0.0, 0.0); + java.lang.Math.min(0.0f, 0.0f); + java.lang.Math.min(0L, 0L); + java.lang.Math.min(0, 0); + java.lang.Math.max(0.0, 0.0); + java.lang.Math.max(0.0f, 0.0f); + java.lang.Math.max(0L, 0L); + java.lang.Math.max(0, 0); + java.lang.Math.cos(0.0); + java.lang.Math.sin(0.0); + java.lang.Math.acos(0.0); + java.lang.Math.asin(0.0); + java.lang.Math.atan(0.0); + java.lang.Math.atan2(0.0, 0.0); + java.lang.Math.cbrt(0.0); + java.lang.Math.cosh(0.0); + java.lang.Math.exp(0.0); + java.lang.Math.expm1(0.0); + java.lang.Math.hypot(0.0, 0.0); + java.lang.Math.log(0.0); + java.lang.Math.log10(0.0); + java.lang.Math.nextAfter(0.0, 0.0); + java.lang.Math.sinh(0.0); + java.lang.Math.tan(0.0); + java.lang.Math.tanh(0.0); + java.lang.Math.sqrt(0.0); + java.lang.Math.ceil(0.0); + java.lang.Math.floor(0.0); + java.lang.Math.rint(0.0); + java.lang.Math.round(0.0); + java.lang.Math.round(0.0f); + java.lang.Thread.currentThread(); + instance_java_lang_String.charAt(0); + instance_java_lang_String.compareTo("hello"); + instance_java_lang_String.equals((java.lang.Object) null); + instance_java_lang_String.indexOf(0); + instance_java_lang_String.indexOf(0, 0); + instance_java_lang_String.indexOf("hello"); + instance_java_lang_String.indexOf("hello", 0); + instance_java_lang_String.isEmpty(); + instance_java_lang_String.length(); + instance_java_lang_StringBuffer.append("hello"); + instance_java_lang_StringBuffer.length(); + instance_java_lang_StringBuffer.toString(); + instance_java_lang_StringBuilder.append("hello"); + instance_java_lang_StringBuilder.length(); + instance_java_lang_StringBuilder.toString(); + java.lang.Integer.valueOf(0); + java.lang.Thread.interrupted(); + } } |