summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mythri Alle <mythria@google.com> 2023-04-26 12:56:36 +0000
committer Mythri Alle <mythria@google.com> 2023-04-27 10:32:29 +0000
commitd60aff547dedefc35265ce57707d406e8ccc4dc6 (patch)
tree8a88ce169a5871b2d29a61d89ecce225af7b6e14
parent89fae872b0aa0c7186ee11bdf1f5732de3f66030 (diff)
Reland "Don't enable intrinsic optimizations in debuggable runtime""
This reverts commit b5fcab944b3786f27ab6b698685109bfc7f785fd. Reason for revert: test/988 is a CTS test and we shouldn't modify the Main to do any real work other than calling run. Also there's no way to call ensureJitCompiled from atests, so restoring 988 to original and adding another test for testing JIT tracing Bug: 279547861 Test: test.py -t 988, 2263 Change-Id: I0908c29996a550b93ba6c38f99460ff0d51a2964
-rw-r--r--compiler/optimizing/critical_native_abi_fixup_arm.cc3
-rw-r--r--compiler/optimizing/inliner.cc6
-rw-r--r--compiler/optimizing/instruction_builder.cc35
-rw-r--r--compiler/optimizing/instruction_simplifier.cc2
-rw-r--r--compiler/optimizing/load_store_analysis_test.cc30
-rw-r--r--compiler/optimizing/nodes.cc4
-rw-r--r--compiler/optimizing/nodes.h40
-rw-r--r--compiler/optimizing/optimizing_unit_test.h3
-rw-r--r--test/2263-method-trace-jit/Android.bp40
l---------test/2263-method-trace-jit/expected-stderr.txt1
l---------test/2263-method-trace-jit/expected-stdout.txt1
-rw-r--r--test/2263-method-trace-jit/info.txt15
-rw-r--r--test/2263-method-trace-jit/run.py19
-rw-r--r--test/2263-method-trace-jit/src/Main.java26
l---------test/2263-method-trace-jit/src/art/Test988.java1
l---------test/2263-method-trace-jit/src/art/Test988Intrinsics.java1
l---------test/2263-method-trace-jit/src/art/Trace.java1
l---------test/2263-method-trace-jit/trace_fib.cc1
-rw-r--r--test/988-method-trace/src/art/Test988Intrinsics.java218
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();
+ }
}