Merge "Don't pre-initialize Class.name fields in boot images"
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 34a6469..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,56 +0,0 @@
-// TODO: These should be handled with transitive static library dependencies
-art_static_dependencies = [
- // Note: the order is important because of static linking resolution.
- "libziparchive",
- "libnativehelper",
- "libnativebridge",
- "libnativeloader",
- "libsigchain_dummy",
- "liblog",
- "libz",
- "libbacktrace",
- "libcutils",
- "libunwindstack",
- "libutils",
- "libbase",
- "liblz4",
- "liblzma",
- "libmetricslogger_static",
-]
-
-subdirs = [
- "adbconnection",
- "benchmark",
- "build",
- "cmdline",
- "compiler",
- "dalvikvm",
- "dex2oat",
- "dexdump",
- "dexlayout",
- "dexlist",
- "dexoptanalyzer",
- "disassembler",
- "dt_fd_forward",
- "dt_fd_forward/export",
- "imgdiag",
- "libartbase",
- "libdexfile",
- "libprofile",
- "oatdump",
- "openjdkjvm",
- "openjdkjvmti",
- "patchoat",
- "profman",
- "runtime",
- "sigchainlib",
- "simulator",
- "test",
- "tools",
- "tools/breakpoint-logger",
- "tools/cpp-define-generator",
- "tools/dmtracedump",
- "tools/hiddenapi",
- "tools/titrace",
- "tools/wrapagentproperties",
-]
diff --git a/build/art.go b/build/art.go
index 61b1a4e..6c08486 100644
--- a/build/art.go
+++ b/build/art.go
@@ -283,6 +283,7 @@
android.RegisterModuleType("art_cc_test_library", artTestLibrary)
android.RegisterModuleType("art_cc_defaults", artDefaultsFactory)
android.RegisterModuleType("libart_cc_defaults", libartDefaultsFactory)
+ android.RegisterModuleType("libart_static_cc_defaults", libartStaticDefaultsFactory)
android.RegisterModuleType("art_global_defaults", artGlobalDefaultsFactory)
android.RegisterModuleType("art_debug_defaults", artDebugDefaultsFactory)
}
@@ -336,6 +337,33 @@
return module
}
+func libartStaticDefaultsFactory() android.Module {
+ c := &codegenProperties{}
+ module := cc.DefaultsFactory(c)
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ codegen(ctx, c, true)
+
+ type props struct {
+ Target struct {
+ Android struct {
+ Static_libs []string
+ }
+ }
+ }
+
+ p := &props{}
+ // TODO: express this in .bp instead b/79671158
+ if !envTrue(ctx, "ART_TARGET_LINUX") {
+ p.Target.Android.Static_libs = []string{
+ "libmetricslogger_static",
+ }
+ }
+ ctx.AppendProperties(p)
+ })
+
+ return module
+}
+
func artLibrary() android.Module {
m, _ := cc.NewLibrary(android.HostAndDeviceSupported)
module := m.Init()
diff --git a/cmdline/cmdline_parser_test.cc b/cmdline/cmdline_parser_test.cc
index 42c6a5f..97daafa 100644
--- a/cmdline/cmdline_parser_test.cc
+++ b/cmdline/cmdline_parser_test.cc
@@ -131,7 +131,7 @@
art::InitLogging(nullptr, art::Runtime::Abort); // argv = null
}
- virtual void SetUp() {
+ void SetUp() override {
parser_ = ParsedOptions::MakeParser(false); // do not ignore unrecognized options
}
diff --git a/compiler/Android.bp b/compiler/Android.bp
index c365537..c2f8e3c 100644
--- a/compiler/Android.bp
+++ b/compiler/Android.bp
@@ -191,6 +191,15 @@
export_include_dirs: ["."],
}
+cc_defaults {
+ name: "libart-compiler_static_base_defaults",
+ static_libs: [
+ "libbase",
+ "libcutils",
+ "liblzma",
+ ],
+}
+
gensrcs {
name: "art_compiler_operator_srcs",
cmd: "$(location generate_operator_out) art/compiler $(in) > $(out)",
@@ -260,6 +269,18 @@
},
}
+cc_defaults {
+ name: "libart-compiler_static_defaults",
+ defaults: [
+ "libart-compiler_static_base_defaults",
+ "libart_static_defaults",
+ "libartbase_static_defaults",
+ "libdexfile_static_defaults",
+ "libprofile_static_defaults",
+ ],
+ static_libs: ["libart-compiler"],
+}
+
art_cc_library {
name: "libartd-compiler",
defaults: [
@@ -302,6 +323,18 @@
],
}
+cc_defaults {
+ name: "libartd-compiler_static_defaults",
+ defaults: [
+ "libart-compiler_static_base_defaults",
+ "libartd_static_defaults",
+ "libartbased_static_defaults",
+ "libdexfiled_static_defaults",
+ "libprofiled_static_defaults",
+ ],
+ static_libs: ["libartd-compiler"],
+}
+
art_cc_library {
name: "libart-compiler-gtest",
defaults: ["libart-gtest-defaults"],
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index d603d96..586891a 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -108,7 +108,7 @@
int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
CHECK_EQ(result, 0);
- FlushInstructionCache(reinterpret_cast<char*>(base), reinterpret_cast<char*>(base + len));
+ FlushInstructionCache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
}
void CommonCompilerTest::MakeExecutable(ObjPtr<mirror::ClassLoader> class_loader,
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index f6afe2c..95d08b3 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -2564,8 +2564,8 @@
thread_pool);
auto compile = [&context, &compile_fn](size_t class_def_index) {
- ScopedTrace trace(__FUNCTION__);
const DexFile& dex_file = *context.GetDexFile();
+ SCOPED_TRACE << "compile " << dex_file.GetLocation() << "@" << class_def_index;
ClassLinker* class_linker = context.GetClassLinker();
jobject jclass_loader = context.GetClassLoader();
ClassReference ref(&dex_file, class_def_index);
diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc
index fd17364..80c0a68 100644
--- a/compiler/exception_test.cc
+++ b/compiler/exception_test.cc
@@ -50,7 +50,7 @@
// which always points to the first source statement.
static constexpr const uint32_t kDexPc = 0;
- virtual void SetUp() {
+ void SetUp() override {
CommonRuntimeTest::SetUp();
ScopedObjectAccess soa(Thread::Current());
diff --git a/compiler/optimizing/code_generator_vector_arm64.cc b/compiler/optimizing/code_generator_vector_arm64.cc
index 6d135a9..43169ba 100644
--- a/compiler/optimizing/code_generator_vector_arm64.cc
+++ b/compiler/optimizing/code_generator_vector_arm64.cc
@@ -1354,6 +1354,7 @@
Register scratch;
switch (instruction->GetPackedType()) {
+ case DataType::Type::kInt16: // (short) s.charAt(.) can yield HVecLoad/Int16/StringCharAt.
case DataType::Type::kUint16:
DCHECK_EQ(8u, instruction->GetVectorLength());
// Special handling of compressed/uncompressed string load.
@@ -1385,7 +1386,6 @@
case DataType::Type::kBool:
case DataType::Type::kUint8:
case DataType::Type::kInt8:
- case DataType::Type::kInt16:
case DataType::Type::kInt32:
case DataType::Type::kFloat32:
case DataType::Type::kInt64:
diff --git a/compiler/optimizing/code_generator_vector_x86.cc b/compiler/optimizing/code_generator_vector_x86.cc
index 086ae07..2502275 100644
--- a/compiler/optimizing/code_generator_vector_x86.cc
+++ b/compiler/optimizing/code_generator_vector_x86.cc
@@ -1205,6 +1205,7 @@
XmmRegister reg = locations->Out().AsFpuRegister<XmmRegister>();
bool is_aligned16 = instruction->GetAlignment().IsAlignedAt(16);
switch (instruction->GetPackedType()) {
+ case DataType::Type::kInt16: // (short) s.charAt(.) can yield HVecLoad/Int16/StringCharAt.
case DataType::Type::kUint16:
DCHECK_EQ(8u, instruction->GetVectorLength());
// Special handling of compressed/uncompressed string load.
@@ -1232,7 +1233,6 @@
case DataType::Type::kBool:
case DataType::Type::kUint8:
case DataType::Type::kInt8:
- case DataType::Type::kInt16:
case DataType::Type::kInt32:
case DataType::Type::kInt64:
DCHECK_LE(2u, instruction->GetVectorLength());
diff --git a/compiler/optimizing/code_generator_vector_x86_64.cc b/compiler/optimizing/code_generator_vector_x86_64.cc
index 4d31ab6..4a67daf 100644
--- a/compiler/optimizing/code_generator_vector_x86_64.cc
+++ b/compiler/optimizing/code_generator_vector_x86_64.cc
@@ -1178,6 +1178,7 @@
XmmRegister reg = locations->Out().AsFpuRegister<XmmRegister>();
bool is_aligned16 = instruction->GetAlignment().IsAlignedAt(16);
switch (instruction->GetPackedType()) {
+ case DataType::Type::kInt16: // (short) s.charAt(.) can yield HVecLoad/Int16/StringCharAt.
case DataType::Type::kUint16:
DCHECK_EQ(8u, instruction->GetVectorLength());
// Special handling of compressed/uncompressed string load.
@@ -1205,7 +1206,6 @@
case DataType::Type::kBool:
case DataType::Type::kUint8:
case DataType::Type::kInt8:
- case DataType::Type::kInt16:
case DataType::Type::kInt32:
case DataType::Type::kInt64:
DCHECK_LE(2u, instruction->GetVectorLength());
diff --git a/compiler/optimizing/constructor_fence_redundancy_elimination.cc b/compiler/optimizing/constructor_fence_redundancy_elimination.cc
index 3cb8bf2..3a1a9e0 100644
--- a/compiler/optimizing/constructor_fence_redundancy_elimination.cc
+++ b/compiler/optimizing/constructor_fence_redundancy_elimination.cc
@@ -78,7 +78,7 @@
VisitSetLocation(instruction, value);
}
- void VisitDeoptimize(HDeoptimize* instruction ATTRIBUTE_UNUSED) {
+ void VisitDeoptimize(HDeoptimize* instruction ATTRIBUTE_UNUSED) override {
// Pessimize: Merge all fences.
MergeCandidateFences();
}
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 2757f7b..bb96c21 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -2146,22 +2146,6 @@
ReferenceTypeInfo argument_rti = argument->GetReferenceTypeInfo();
if (argument_rti.IsValid() && argument_rti.IsStringClass()) {
optimizations.SetArgumentIsString();
- } else if (kUseReadBarrier) {
- DCHECK(instruction->GetResolvedMethod() != nullptr);
- DCHECK(instruction->GetResolvedMethod()->GetDeclaringClass()->IsStringClass() ||
- // Object.equals() can be devirtualized to String.equals().
- instruction->GetResolvedMethod()->GetDeclaringClass()->IsObjectClass());
- Runtime* runtime = Runtime::Current();
- // For AOT, we always assume that the boot image shall contain the String.class and
- // we do not need a read barrier for boot image classes as they are non-moveable.
- // For JIT, check if we actually have a boot image; if we do, the String.class
- // should also be non-moveable.
- if (runtime->IsAotCompiler() || runtime->GetHeap()->HasBootImageSpace()) {
- DCHECK(runtime->IsAotCompiler() ||
- !runtime->GetHeap()->IsMovableObject(
- instruction->GetResolvedMethod()->GetDeclaringClass()));
- optimizations.SetNoReadBarrierForStringClass();
- }
}
}
}
diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h
index 06e2fbb..2d93f23 100644
--- a/compiler/optimizing/intrinsics.h
+++ b/compiler/optimizing/intrinsics.h
@@ -219,7 +219,6 @@
INTRINSIC_OPTIMIZATION(ArgumentNotNull, 0);
INTRINSIC_OPTIMIZATION(ArgumentIsString, 1);
- INTRINSIC_OPTIMIZATION(NoReadBarrierForStringClass, 2);
private:
DISALLOW_COPY_AND_ASSIGN(StringEqualsOptimizations);
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index 1abfcb0..7684dc7 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -1398,13 +1398,6 @@
}
void IntrinsicLocationsBuilderARM64::VisitStringEquals(HInvoke* invoke) {
- if (kEmitCompilerReadBarrier &&
- !StringEqualsOptimizations(invoke).GetArgumentIsString() &&
- !StringEqualsOptimizations(invoke).GetNoReadBarrierForStringClass()) {
- // No support for this odd case (String class is moveable, not in the boot image).
- return;
- }
-
LocationSummary* locations =
new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
locations->SetInAt(0, Location::RequiresRegister());
diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc
index 1127fb8..bc59fcf 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -1458,13 +1458,6 @@
}
void IntrinsicLocationsBuilderARMVIXL::VisitStringEquals(HInvoke* invoke) {
- if (kEmitCompilerReadBarrier &&
- !StringEqualsOptimizations(invoke).GetArgumentIsString() &&
- !StringEqualsOptimizations(invoke).GetNoReadBarrierForStringClass()) {
- // No support for this odd case (String class is moveable, not in the boot image).
- return;
- }
-
LocationSummary* locations =
new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
InvokeRuntimeCallingConventionARMVIXL calling_convention;
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 771714b..6f7f5e4 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -1516,13 +1516,6 @@
// boolean java.lang.String.equals(Object anObject)
void IntrinsicLocationsBuilderMIPS::VisitStringEquals(HInvoke* invoke) {
- if (kEmitCompilerReadBarrier &&
- !StringEqualsOptimizations(invoke).GetArgumentIsString() &&
- !StringEqualsOptimizations(invoke).GetNoReadBarrierForStringClass()) {
- // No support for this odd case (String class is moveable, not in the boot image).
- return;
- }
-
LocationSummary* locations =
new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
locations->SetInAt(0, Location::RequiresRegister());
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc
index 4a1bd5b..2eb2529 100644
--- a/compiler/optimizing/intrinsics_mips64.cc
+++ b/compiler/optimizing/intrinsics_mips64.cc
@@ -1369,13 +1369,6 @@
// boolean java.lang.String.equals(Object anObject)
void IntrinsicLocationsBuilderMIPS64::VisitStringEquals(HInvoke* invoke) {
- if (kEmitCompilerReadBarrier &&
- !StringEqualsOptimizations(invoke).GetArgumentIsString() &&
- !StringEqualsOptimizations(invoke).GetNoReadBarrierForStringClass()) {
- // No support for this odd case (String class is moveable, not in the boot image).
- return;
- }
-
LocationSummary* locations =
new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
locations->SetInAt(0, Location::RequiresRegister());
diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc
index d33c0c3..3504d7a 100644
--- a/compiler/optimizing/intrinsics_x86.cc
+++ b/compiler/optimizing/intrinsics_x86.cc
@@ -922,13 +922,6 @@
}
void IntrinsicLocationsBuilderX86::VisitStringEquals(HInvoke* invoke) {
- if (kEmitCompilerReadBarrier &&
- !StringEqualsOptimizations(invoke).GetArgumentIsString() &&
- !StringEqualsOptimizations(invoke).GetNoReadBarrierForStringClass()) {
- // No support for this odd case (String class is moveable, not in the boot image).
- return;
- }
-
LocationSummary* locations =
new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
locations->SetInAt(0, Location::RequiresRegister());
diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc
index ae88974..96f6eaa 100644
--- a/compiler/optimizing/intrinsics_x86_64.cc
+++ b/compiler/optimizing/intrinsics_x86_64.cc
@@ -1230,13 +1230,6 @@
}
void IntrinsicLocationsBuilderX86_64::VisitStringEquals(HInvoke* invoke) {
- if (kEmitCompilerReadBarrier &&
- !StringEqualsOptimizations(invoke).GetArgumentIsString() &&
- !StringEqualsOptimizations(invoke).GetNoReadBarrierForStringClass()) {
- // No support for this odd case (String class is moveable, not in the boot image).
- return;
- }
-
LocationSummary* locations =
new (allocator_) LocationSummary(invoke, LocationSummary::kNoCall, kIntrinsified);
locations->SetInAt(0, Location::RequiresRegister());
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index 7f71745..b33d0f4 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -692,7 +692,7 @@
VisitSetLocation(instruction, idx, instruction->InputAt(2));
}
- void VisitDeoptimize(HDeoptimize* instruction) {
+ void VisitDeoptimize(HDeoptimize* instruction) override {
const ScopedArenaVector<HInstruction*>& heap_values =
heap_values_for_[instruction->GetBlock()->GetBlockId()];
for (HInstruction* heap_value : heap_values) {
diff --git a/compiler/optimizing/optimizing_cfi_test.cc b/compiler/optimizing/optimizing_cfi_test.cc
index be1f7ea..a52031c 100644
--- a/compiler/optimizing/optimizing_cfi_test.cc
+++ b/compiler/optimizing/optimizing_cfi_test.cc
@@ -128,7 +128,7 @@
public:
InternalCodeAllocator() {}
- virtual uint8_t* Allocate(size_t size) {
+ uint8_t* Allocate(size_t size) override {
memory_.resize(size);
return memory_.data();
}
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 0a74705..ff1207a 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -79,7 +79,7 @@
explicit CodeVectorAllocator(ArenaAllocator* allocator)
: memory_(allocator->Adapter(kArenaAllocCodeBuffer)) {}
- virtual uint8_t* Allocate(size_t size) {
+ uint8_t* Allocate(size_t size) override {
memory_.resize(size);
return &memory_[0];
}
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index a9d5902..9079658 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -114,9 +114,9 @@
void VisitCheckCast(HCheckCast* instr) override;
void VisitBoundType(HBoundType* instr) override;
void VisitNullCheck(HNullCheck* instr) override;
- void VisitPhi(HPhi* phi);
+ void VisitPhi(HPhi* phi) override;
- void VisitBasicBlock(HBasicBlock* block);
+ void VisitBasicBlock(HBasicBlock* block) override;
void ProcessWorklist();
private:
diff --git a/compiler/utils/mips/assembler_mips32r5_test.cc b/compiler/utils/mips/assembler_mips32r5_test.cc
index f9919f5..bd73c12 100644
--- a/compiler/utils/mips/assembler_mips32r5_test.cc
+++ b/compiler/utils/mips/assembler_mips32r5_test.cc
@@ -229,7 +229,7 @@
STLDeleteElements(&vec_registers_);
}
- std::vector<mips::MipsLabel> GetAddresses() {
+ std::vector<mips::MipsLabel> GetAddresses() override {
UNIMPLEMENTED(FATAL) << "Feature not implemented yet";
UNREACHABLE();
}
diff --git a/compiler/utils/mips/assembler_mips32r6_test.cc b/compiler/utils/mips/assembler_mips32r6_test.cc
index 1ec7a6a..9637c25 100644
--- a/compiler/utils/mips/assembler_mips32r6_test.cc
+++ b/compiler/utils/mips/assembler_mips32r6_test.cc
@@ -242,7 +242,7 @@
STLDeleteElements(&vec_registers_);
}
- std::vector<mips::MipsLabel> GetAddresses() {
+ std::vector<mips::MipsLabel> GetAddresses() override {
UNIMPLEMENTED(FATAL) << "Feature not implemented yet";
UNREACHABLE();
}
diff --git a/compiler/utils/mips/assembler_mips_test.cc b/compiler/utils/mips/assembler_mips_test.cc
index 9527fa6..f137c60 100644
--- a/compiler/utils/mips/assembler_mips_test.cc
+++ b/compiler/utils/mips/assembler_mips_test.cc
@@ -176,7 +176,7 @@
STLDeleteElements(&fp_registers_);
}
- std::vector<mips::MipsLabel> GetAddresses() {
+ std::vector<mips::MipsLabel> GetAddresses() override {
UNIMPLEMENTED(FATAL) << "Feature not implemented yet";
UNREACHABLE();
}
diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc
index 4ceb356..3218ae3 100644
--- a/compiler/utils/mips64/assembler_mips64_test.cc
+++ b/compiler/utils/mips64/assembler_mips64_test.cc
@@ -240,7 +240,7 @@
STLDeleteElements(&vec_registers_);
}
- std::vector<mips64::Mips64Label> GetAddresses() {
+ std::vector<mips64::Mips64Label> GetAddresses() override {
UNIMPLEMENTED(FATAL) << "Feature not implemented yet";
UNREACHABLE();
}
diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc
index e1de1f1..65711e0 100644
--- a/compiler/utils/x86_64/assembler_x86_64_test.cc
+++ b/compiler/utils/x86_64/assembler_x86_64_test.cc
@@ -297,7 +297,7 @@
STLDeleteElements(&fp_registers_);
}
- std::vector<x86_64::Address> GetAddresses() {
+ std::vector<x86_64::Address> GetAddresses() override {
return addresses_;
}
diff --git a/compiler/verifier_deps_test.cc b/compiler/verifier_deps_test.cc
index 81932a9..523c90b 100644
--- a/compiler/verifier_deps_test.cc
+++ b/compiler/verifier_deps_test.cc
@@ -52,7 +52,7 @@
bool IsRelocationPossible() override { return false; }
verifier::VerifierDeps* GetVerifierDeps() const override { return deps_; }
- void SetVerifierDeps(verifier::VerifierDeps* deps) { deps_ = deps; }
+ void SetVerifierDeps(verifier::VerifierDeps* deps) override { deps_ = deps; }
private:
verifier::VerifierDeps* deps_;
@@ -60,7 +60,7 @@
class VerifierDepsTest : public CommonCompilerTest {
public:
- void SetUpRuntimeOptions(RuntimeOptions* options) {
+ void SetUpRuntimeOptions(RuntimeOptions* options) override {
CommonCompilerTest::SetUpRuntimeOptions(options);
callbacks_.reset(new VerifierDepsCompilerCallbacks());
}
diff --git a/dex2oat/Android.bp b/dex2oat/Android.bp
index 88e69cd..666db42 100644
--- a/dex2oat/Android.bp
+++ b/dex2oat/Android.bp
@@ -89,6 +89,20 @@
},
}
+cc_defaults {
+ name: "libart-dex2oat_static_base_defaults",
+ target: {
+ android: {
+ static_libs: ["libcutils"],
+ },
+ },
+ static_libs: [
+ "libbase",
+ "liblz4",
+ "liblzma",
+ ],
+}
+
gensrcs {
name: "art_dex2oat_operator_srcs",
cmd: "$(location generate_operator_out) art/dex2oat $(in) > $(out)",
@@ -110,6 +124,20 @@
],
}
+cc_defaults {
+ name: "libart-dex2oat_static_defaults",
+ defaults: [
+ "libart-dex2oat_static_base_defaults",
+ "libart_static_defaults",
+ "libprofile_static_defaults",
+ ],
+ static_libs: [
+ "libart-compiler",
+ "libart-dexlayout",
+ "libart-dex2oat",
+ ],
+}
+
art_cc_static_library {
name: "libartd-dex2oat",
defaults: [
@@ -124,6 +152,20 @@
],
}
+cc_defaults {
+ name: "libartd-dex2oat_static_defaults",
+ defaults: [
+ "libart-dex2oat_static_base_defaults",
+ "libartd_static_defaults",
+ "libprofiled_static_defaults",
+ ],
+ static_libs: [
+ "libartd-compiler",
+ "libartd-dexlayout",
+ "libartd-dex2oat",
+ ],
+}
+
cc_library_headers {
name: "dex2oat_headers",
host_supported: true,
@@ -255,7 +297,9 @@
name: "dex2oats-defaults",
device_supported: false,
static_executable: true,
- defaults: ["dex2oat-defaults"],
+ defaults: [
+ "dex2oat-defaults",
+ ],
target: {
darwin: {
enabled: false,
@@ -269,22 +313,24 @@
// Try to get rid of it.
"-z muldefs",
],
- static_libs: art_static_dependencies,
+ static_libs: [
+ "libbase",
+ "liblz4",
+ "libsigchain_dummy",
+ ],
}
art_cc_binary {
name: "dex2oats",
- defaults: ["dex2oats-defaults"],
- static_libs: [
- "libart-dex2oat",
- "libart-compiler",
- "libart-dexlayout",
- "libart",
- "libartbase",
- "libdexfile",
- "libprofile",
- "libvixl-arm",
- "libvixl-arm64",
+ defaults: [
+ "dex2oats-defaults",
+ "libart_static_defaults",
+ "libart-compiler_static_defaults",
+ "libart-dexlayout_static_defaults",
+ "libartbase_static_defaults",
+ "libdexfile_static_defaults",
+ "libprofile_static_defaults",
+ "libart-dex2oat_static_defaults",
],
}
@@ -293,6 +339,13 @@
defaults: [
"art_debug_defaults",
"dex2oats-defaults",
+ "libartd_static_defaults",
+ "libartd-compiler_static_defaults",
+ "libartd-dexlayout_static_defaults",
+ "libartbased_static_defaults",
+ "libdexfiled_static_defaults",
+ "libprofiled_static_defaults",
+ "libartd-dex2oat_static_defaults",
],
target: {
linux_glibc_x86_64: {
@@ -301,17 +354,6 @@
},
// b/79417743, oatdump 32-bit tests failed with clang lld
use_clang_lld: false,
- static_libs: [
- "libartd-dex2oat",
- "libartd-compiler",
- "libartd-dexlayout",
- "libartd",
- "libartbased",
- "libprofiled",
- "libdexfiled",
- "libvixld-arm",
- "libvixld-arm64",
- ],
}
art_cc_test {
diff --git a/dex2oat/linker/elf_writer_quick.cc b/dex2oat/linker/elf_writer_quick.cc
index 852293b..9a7f93d 100644
--- a/dex2oat/linker/elf_writer_quick.cc
+++ b/dex2oat/linker/elf_writer_quick.cc
@@ -68,7 +68,7 @@
debug_info_(debug_info) {
}
- void Run(Thread*) {
+ void Run(Thread*) override {
result_ = debug::MakeMiniDebugInfo(isa_,
instruction_set_features_,
text_section_address_,
diff --git a/dex2oat/linker/elf_writer_test.cc b/dex2oat/linker/elf_writer_test.cc
index 40495f3..ef85fd1 100644
--- a/dex2oat/linker/elf_writer_test.cc
+++ b/dex2oat/linker/elf_writer_test.cc
@@ -34,7 +34,7 @@
class ElfWriterTest : public CommonCompilerTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
ReserveImageSpace();
CommonCompilerTest::SetUp();
}
diff --git a/dex2oat/linker/multi_oat_relative_patcher_test.cc b/dex2oat/linker/multi_oat_relative_patcher_test.cc
index a5831b6..2610561 100644
--- a/dex2oat/linker/multi_oat_relative_patcher_test.cc
+++ b/dex2oat/linker/multi_oat_relative_patcher_test.cc
@@ -96,12 +96,12 @@
void PatchBakerReadBarrierBranch(std::vector<uint8_t>* code ATTRIBUTE_UNUSED,
const LinkerPatch& patch ATTRIBUTE_UNUSED,
- uint32_t patch_offset ATTRIBUTE_UNUSED) {
+ uint32_t patch_offset ATTRIBUTE_UNUSED) override {
LOG(FATAL) << "UNIMPLEMENTED";
}
std::vector<debug::MethodDebugInfo> GenerateThunkDebugInfo(
- uint32_t executable_offset ATTRIBUTE_UNUSED) {
+ uint32_t executable_offset ATTRIBUTE_UNUSED) override {
LOG(FATAL) << "UNIMPLEMENTED";
UNREACHABLE();
}
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index f88d8d4..e2db11f 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -1671,7 +1671,7 @@
}
}
- virtual bool VisitComplete() {
+ bool VisitComplete() override {
offset_ = writer_->relative_patcher_->WriteThunks(out_, offset_);
if (UNLIKELY(offset_ == 0u)) {
PLOG(ERROR) << "Failed to write final relative call thunks";
diff --git a/dex2oat/linker/relative_patcher.cc b/dex2oat/linker/relative_patcher.cc
index 564cf30..45a4a22 100644
--- a/dex2oat/linker/relative_patcher.cc
+++ b/dex2oat/linker/relative_patcher.cc
@@ -79,7 +79,7 @@
void PatchBakerReadBarrierBranch(std::vector<uint8_t>* code ATTRIBUTE_UNUSED,
const LinkerPatch& patch ATTRIBUTE_UNUSED,
- uint32_t patch_offset ATTRIBUTE_UNUSED) {
+ uint32_t patch_offset ATTRIBUTE_UNUSED) override {
LOG(FATAL) << "Unexpected baker read barrier branch patch.";
}
diff --git a/dexdump/Android.bp b/dexdump/Android.bp
index ac9a9a2..3e576c8 100644
--- a/dexdump/Android.bp
+++ b/dexdump/Android.bp
@@ -38,13 +38,13 @@
art_cc_binary {
name: "dexdumps",
- defaults: ["dexdump_defaults"],
+ defaults: [
+ "dexdump_defaults",
+ "libartbase_static_defaults",
+ "libdexfile_static_defaults",
+ ],
host_supported: true,
device_supported: false,
- static_libs: [
- "libdexfile",
- "libartbase",
- ] + art_static_dependencies,
target: {
darwin: {
enabled: false,
diff --git a/dexdump/dexdump_test.cc b/dexdump/dexdump_test.cc
index 3a2d38d..bb6d4a4 100644
--- a/dexdump/dexdump_test.cc
+++ b/dexdump/dexdump_test.cc
@@ -31,7 +31,7 @@
class DexDumpTest : public CommonRuntimeTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
CommonRuntimeTest::SetUp();
// Dogfood our own lib core dex file.
dex_file_ = GetLibCoreDexFileNames()[0];
diff --git a/dexlayout/Android.bp b/dexlayout/Android.bp
index 147af0c..24ee5f8 100644
--- a/dexlayout/Android.bp
+++ b/dexlayout/Android.bp
@@ -32,6 +32,14 @@
static_libs: ["libz"],
}
+cc_defaults {
+ name: "libart-dexlayout_static_base_defaults",
+ static_libs: [
+ "libbase",
+ "libz",
+ ],
+}
+
art_cc_library {
name: "libart-dexlayout",
defaults: [
@@ -53,6 +61,17 @@
},
}
+cc_defaults {
+ name: "libart-dexlayout_static_defaults",
+ defaults: [
+ "libart-dexlayout_static_base_defaults",
+ "libartbase_static_defaults",
+ "libdexfile_static_defaults",
+ "libprofile_static_defaults",
+ ],
+ static_libs: ["libart-dexlayout"],
+}
+
art_cc_library {
name: "libartd-dexlayout",
defaults: [
@@ -67,6 +86,17 @@
}
cc_defaults {
+ name: "libartd-dexlayout_static_defaults",
+ defaults: [
+ "libart-dexlayout_static_base_defaults",
+ "libartbased_static_defaults",
+ "libdexfiled_static_defaults",
+ "libprofiled_static_defaults",
+ ],
+ static_libs: ["libartd-dexlayout"],
+}
+
+cc_defaults {
name: "dexlayout-defaults",
defaults: ["art_defaults"],
host_supported: true,
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index 178a4d4..598f7df 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -215,7 +215,7 @@
uint32_t GetOffset() const { return offset_; }
void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
- virtual uint32_t Size() const { return 0U; }
+ virtual uint32_t Size() const = 0;
private:
// Start out unassigned.
diff --git a/dexlayout/dex_ir_builder.cc b/dexlayout/dex_ir_builder.cc
index ca6ff9e..947d3d5 100644
--- a/dexlayout/dex_ir_builder.cc
+++ b/dexlayout/dex_ir_builder.cc
@@ -115,6 +115,8 @@
return it != collection_.end() ? it->second : nullptr;
}
+ uint32_t Size() const override { return size(); }
+
// Lower case for template interop with std::map.
uint32_t size() const { return collection_.size(); }
std::map<uint32_t, T*>& Collection() { return collection_; }
diff --git a/dexlayout/dexdiag_test.cc b/dexlayout/dexdiag_test.cc
index 60dd7e4..f936ff9 100644
--- a/dexlayout/dexdiag_test.cc
+++ b/dexlayout/dexdiag_test.cc
@@ -34,7 +34,7 @@
class DexDiagTest : public CommonRuntimeTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
CommonRuntimeTest::SetUp();
}
diff --git a/dexlist/dexlist_test.cc b/dexlist/dexlist_test.cc
index 68e6713..39e5f8c 100644
--- a/dexlist/dexlist_test.cc
+++ b/dexlist/dexlist_test.cc
@@ -33,7 +33,7 @@
class DexListTest : public CommonRuntimeTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
CommonRuntimeTest::SetUp();
// Dogfood our own lib core dex file.
dex_file_ = GetLibCoreDexFileNames()[0];
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index ebc18fc..51b3d75 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -26,6 +26,7 @@
#include <unordered_set>
#include <vector>
+#include <android-base/parseint.h>
#include "android-base/stringprintf.h"
#include "art_field-inl.h"
@@ -1682,14 +1683,14 @@
if (option.starts_with("--image-diff-pid=")) {
const char* image_diff_pid = option.substr(strlen("--image-diff-pid=")).data();
- if (!ParseInt(image_diff_pid, &image_diff_pid_)) {
+ if (!android::base::ParseInt(image_diff_pid, &image_diff_pid_)) {
*error_msg = "Image diff pid out of range";
return kParseError;
}
} else if (option.starts_with("--zygote-diff-pid=")) {
const char* zygote_diff_pid = option.substr(strlen("--zygote-diff-pid=")).data();
- if (!ParseInt(zygote_diff_pid, &zygote_diff_pid_)) {
+ if (!android::base::ParseInt(zygote_diff_pid, &zygote_diff_pid_)) {
*error_msg = "Zygote diff pid out of range";
return kParseError;
}
@@ -1730,7 +1731,7 @@
return kParseOk;
}
- virtual std::string GetUsage() const {
+ std::string GetUsage() const override {
std::string usage;
usage +=
@@ -1760,7 +1761,7 @@
};
struct ImgDiagMain : public CmdlineMain<ImgDiagArgs> {
- virtual bool ExecuteWithRuntime(Runtime* runtime) {
+ bool ExecuteWithRuntime(Runtime* runtime) override {
CHECK(args_ != nullptr);
return DumpImage(runtime,
diff --git a/imgdiag/imgdiag_test.cc b/imgdiag/imgdiag_test.cc
index cb40c7d..73df2a2 100644
--- a/imgdiag/imgdiag_test.cc
+++ b/imgdiag/imgdiag_test.cc
@@ -47,7 +47,7 @@
class ImgDiagTest : public CommonRuntimeTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
CommonRuntimeTest::SetUp();
// We loaded the runtime with an explicit image. Therefore the image space must exist.
diff --git a/libartbase/Android.bp b/libartbase/Android.bp
index 4ee48da..1b603b5 100644
--- a/libartbase/Android.bp
+++ b/libartbase/Android.bp
@@ -79,6 +79,30 @@
export_shared_lib_headers: ["libbase"],
}
+cc_defaults {
+ name: "libartbase_static_base_defaults",
+ static_libs: [
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "libz",
+ "libziparchive",
+ ],
+}
+
+cc_defaults {
+ name: "libartbase_static_defaults",
+ defaults: ["libartbase_static_base_defaults"],
+ static_libs: ["libartbase"],
+}
+
+cc_defaults {
+ name: "libartbased_static_defaults",
+ defaults: ["libartbase_static_base_defaults"],
+ static_libs: ["libartbased"],
+}
+
gensrcs {
name: "art_libartbase_operator_srcs",
cmd: "$(location generate_operator_out) art/libartbase $(in) > $(out)",
diff --git a/libartbase/base/allocator.cc b/libartbase/base/allocator.cc
index 1bcfe87..6393672 100644
--- a/libartbase/base/allocator.cc
+++ b/libartbase/base/allocator.cc
@@ -30,11 +30,11 @@
MallocAllocator() {}
~MallocAllocator() {}
- void* Alloc(size_t size) {
+ void* Alloc(size_t size) override {
return calloc(sizeof(uint8_t), size);
}
- void Free(void* p) {
+ void Free(void* p) override {
free(p);
}
@@ -49,12 +49,12 @@
NoopAllocator() {}
~NoopAllocator() {}
- void* Alloc(size_t size ATTRIBUTE_UNUSED) {
+ void* Alloc(size_t size ATTRIBUTE_UNUSED) override {
LOG(FATAL) << "NoopAllocator::Alloc should not be called";
UNREACHABLE();
}
- void Free(void* p ATTRIBUTE_UNUSED) {
+ void Free(void* p ATTRIBUTE_UNUSED) override {
// Noop.
}
diff --git a/libartbase/base/arena_bit_vector.cc b/libartbase/base/arena_bit_vector.cc
index c6d8993..138a5df 100644
--- a/libartbase/base/arena_bit_vector.cc
+++ b/libartbase/base/arena_bit_vector.cc
@@ -62,11 +62,11 @@
UNREACHABLE();
}
- virtual void* Alloc(size_t size) {
+ void* Alloc(size_t size) override {
return allocator_->Alloc(size, this->Kind());
}
- virtual void Free(void*) {} // Nop.
+ void Free(void*) override {} // Nop.
private:
ArenaBitVectorAllocator(ArenaAlloc* allocator, ArenaAllocKind kind)
diff --git a/libartbase/base/unix_file/fd_file_test.cc b/libartbase/base/unix_file/fd_file_test.cc
index 298b2d7..9c39bb5 100644
--- a/libartbase/base/unix_file/fd_file_test.cc
+++ b/libartbase/base/unix_file/fd_file_test.cc
@@ -23,7 +23,7 @@
class FdFileTest : public RandomAccessFileTest {
protected:
- virtual RandomAccessFile* MakeTestFile() {
+ RandomAccessFile* MakeTestFile() override {
FILE* tmp = tmpfile();
int fd = dup(fileno(tmp));
fclose(tmp);
diff --git a/libartbase/base/utils.cc b/libartbase/base/utils.cc
index 761c611..74cc5b9 100644
--- a/libartbase/base/utils.cc
+++ b/libartbase/base/utils.cc
@@ -38,6 +38,12 @@
#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
#endif
+#if defined(__BIONIC__)
+// membarrier(2) is only supported for target builds (b/111199492).
+#include <linux/membarrier.h>
+#include <sys/syscall.h>
+#endif
+
#if defined(__linux__)
#include <linux/unistd.h>
#endif
@@ -207,4 +213,42 @@
}
}
+bool FlushInstructionPipeline() {
+ // membarrier(2) is only supported for target builds (b/111199492).
+#if defined(__BIONIC__)
+ static constexpr int kSyncCoreMask =
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE |
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE;
+ static bool have_probed = false;
+ static bool have_sync_core = false;
+
+ if (UNLIKELY(!have_probed)) {
+ // Probe membarrier(2) commands supported by kernel.
+ int commands = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
+ if (commands >= 0) {
+ have_sync_core = (commands & kSyncCoreMask) == kSyncCoreMask;
+ if (have_sync_core) {
+ // Register with kernel that we'll be using the private expedited sync core command.
+ CheckedCall(syscall,
+ "membarrier register sync core",
+ __NR_membarrier,
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
+ 0);
+ }
+ }
+ have_probed = true;
+ }
+
+ if (have_sync_core) {
+ CheckedCall(syscall,
+ "membarrier sync core",
+ __NR_membarrier,
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE,
+ 0);
+ return true;
+ }
+#endif // defined(__BIONIC__)
+ return false;
+}
+
} // namespace art
diff --git a/libartbase/base/utils.h b/libartbase/base/utils.h
index ba61e1b..d85960d 100644
--- a/libartbase/base/utils.h
+++ b/libartbase/base/utils.h
@@ -24,6 +24,7 @@
#include <string>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
#include "casts.h"
#include "enums.h"
@@ -33,34 +34,6 @@
namespace art {
-template <typename T>
-bool ParseUint(const char *in, T* out) {
- char* end;
- unsigned long long int result = strtoull(in, &end, 0); // NOLINT(runtime/int)
- if (in == end || *end != '\0') {
- return false;
- }
- if (std::numeric_limits<T>::max() < result) {
- return false;
- }
- *out = static_cast<T>(result);
- return true;
-}
-
-template <typename T>
-bool ParseInt(const char* in, T* out) {
- char* end;
- long long int result = strtoll(in, &end, 0); // NOLINT(runtime/int)
- if (in == end || *end != '\0') {
- return false;
- }
- if (result < std::numeric_limits<T>::min() || std::numeric_limits<T>::max() < result) {
- return false;
- }
- *out = static_cast<T>(result);
- return true;
-}
-
static inline uint32_t PointerToLowMemUInt32(const void* p) {
uintptr_t intp = reinterpret_cast<uintptr_t>(p);
DCHECK_LE(intp, 0xFFFFFFFFU);
@@ -130,7 +103,7 @@
DCHECK(option.starts_with(option_prefix)) << option << " " << option_prefix;
const char* value_string = option.substr(option_prefix.size()).data();
int64_t parsed_integer_value = 0;
- if (!ParseInt(value_string, &parsed_integer_value)) {
+ if (!android::base::ParseInt(value_string, &parsed_integer_value)) {
usage("Failed to parse %s '%s' as an integer", option_name.c_str(), value_string);
}
*out = dchecked_integral_cast<T>(parsed_integer_value);
@@ -179,16 +152,19 @@
// Sleep forever and never come back.
NO_RETURN void SleepForever();
-inline void FlushInstructionCache(char* begin, char* end) {
- __builtin___clear_cache(begin, end);
+inline void FlushDataCache(void* begin, void* end) {
+ __builtin___clear_cache(reinterpret_cast<char*>(begin), reinterpret_cast<char*>(end));
}
-inline void FlushDataCache(char* begin, char* end) {
+inline void FlushInstructionCache(void* begin, void* end) {
// Same as FlushInstructionCache for lack of other builtin. __builtin___clear_cache
// flushes both caches.
- __builtin___clear_cache(begin, end);
+ __builtin___clear_cache(reinterpret_cast<char*>(begin), reinterpret_cast<char*>(end));
}
+// Flush instruction pipeline. Returns true on success, false if feature is unsupported.
+bool FlushInstructionPipeline();
+
template <typename T>
constexpr PointerSize ConvertToPointerSize(T any) {
if (any == 4 || any == 8) {
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index 06fd19e..49b1278 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -72,6 +72,36 @@
],
}
+cc_defaults {
+ name: "libdexfile_static_base_defaults",
+ static_libs: [
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "libz",
+ "libziparchive",
+ ],
+}
+
+cc_defaults {
+ name: "libdexfile_static_defaults",
+ defaults: [
+ "libartbase_static_defaults",
+ "libdexfile_static_base_defaults",
+ ],
+ static_libs: ["libdexfile"],
+}
+
+cc_defaults {
+ name: "libdexfiled_static_defaults",
+ defaults: [
+ "libartbased_static_defaults",
+ "libdexfile_static_base_defaults",
+ ],
+ static_libs: ["libdexfiled"],
+}
+
gensrcs {
name: "dexfile_operator_srcs",
cmd: "$(location generate_operator_out) art/libdexfile $(in) > $(out)",
diff --git a/libprofile/Android.bp b/libprofile/Android.bp
index b9883f6..edd9fa8 100644
--- a/libprofile/Android.bp
+++ b/libprofile/Android.bp
@@ -56,6 +56,37 @@
export_shared_lib_headers: ["libbase"],
}
+cc_defaults {
+ name: "libprofile_static_base_defaults",
+ static_libs: [
+ "libbase",
+ "libcutils",
+ "libutils",
+ "libz",
+ "libziparchive",
+ ],
+}
+
+cc_defaults {
+ name: "libprofile_static_defaults",
+ defaults: [
+ "libprofile_static_base_defaults",
+ "libartbase_static_defaults",
+ "libdexfile_static_defaults",
+ ],
+ static_libs: ["libprofile"],
+}
+
+cc_defaults {
+ name: "libprofiled_static_defaults",
+ defaults: [
+ "libprofile_static_base_defaults",
+ "libartbased_static_defaults",
+ "libdexfiled_static_defaults",
+ ],
+ static_libs: ["libprofiled"],
+}
+
art_cc_library {
name: "libprofile",
defaults: ["libprofile_defaults"],
diff --git a/oatdump/Android.bp b/oatdump/Android.bp
index 3cd8ae0..7d82ebf 100644
--- a/oatdump/Android.bp
+++ b/oatdump/Android.bp
@@ -66,7 +66,9 @@
name: "oatdumps-defaults",
device_supported: false,
static_executable: true,
- defaults: ["oatdump-defaults"],
+ defaults: [
+ "oatdump-defaults",
+ ],
target: {
darwin: {
enabled: false,
@@ -80,18 +82,20 @@
// Try to get rid of it.
"-z muldefs",
],
- static_libs: art_static_dependencies,
+ static_libs: ["libsigchain_dummy"],
}
art_cc_binary {
name: "oatdumps",
- defaults: ["oatdumps-defaults"],
+ defaults: [
+ "libart_static_defaults",
+ "libartbase_static_defaults",
+ "libdexfile_static_defaults",
+ "libprofile_static_defaults",
+ "libart-compiler_static_defaults",
+ "oatdumps-defaults",
+ ],
static_libs: [
- "libart",
- "libdexfile",
- "libprofile",
- "libartbase",
- "libart-compiler",
"libart-disassembler",
"libvixl-arm",
"libvixl-arm64",
@@ -102,6 +106,11 @@
name: "oatdumpds",
defaults: [
"art_debug_defaults",
+ "libartd_static_defaults",
+ "libartbased_static_defaults",
+ "libdexfiled_static_defaults",
+ "libprofiled_static_defaults",
+ "libartd-compiler_static_defaults",
"oatdumps-defaults",
],
target: {
@@ -110,15 +119,11 @@
},
},
static_libs: [
- "libartd",
- "libdexfiled",
- "libprofiled",
- "libartbased",
- "libartd-compiler",
"libartd-disassembler",
"libvixld-arm",
"libvixld-arm64",
],
+ group_static_libs: true,
}
art_cc_test {
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index fc7f5b7..51abaf4 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -28,6 +28,7 @@
#include <vector>
#include "android-base/logging.h"
+#include "android-base/parseint.h"
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
@@ -3380,7 +3381,7 @@
} else if (option.starts_with("--export-dex-to=")) {
export_dex_location_ = option.substr(strlen("--export-dex-to=")).data();
} else if (option.starts_with("--addr2instr=")) {
- if (!ParseUint(option.substr(strlen("--addr2instr=")).data(), &addr2instr_)) {
+ if (!android::base::ParseUint(option.substr(strlen("--addr2instr=")).data(), &addr2instr_)) {
*error_msg = "Address conversion failed";
return kParseError;
}
@@ -3423,7 +3424,7 @@
return kParseOk;
}
- virtual std::string GetUsage() const {
+ std::string GetUsage() const override {
std::string usage;
usage +=
@@ -3577,7 +3578,7 @@
}
}
- virtual bool ExecuteWithRuntime(Runtime* runtime) {
+ bool ExecuteWithRuntime(Runtime* runtime) override {
CHECK(args_ != nullptr);
if (!args_->imt_dump_.empty() || args_->imt_stat_dump_) {
diff --git a/openjdkjvmti/ti_class.cc b/openjdkjvmti/ti_class.cc
index f1d6fb0..1ed615b 100644
--- a/openjdkjvmti/ti_class.cc
+++ b/openjdkjvmti/ti_class.cc
@@ -267,7 +267,8 @@
}
}
- void ClassLoad(art::Handle<art::mirror::Class> klass) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ void ClassLoad(art::Handle<art::mirror::Class> klass) override
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassLoad)) {
art::Thread* thread = art::Thread::Current();
ScopedLocalRef<jclass> jklass(thread->GetJniEnv(),
@@ -289,7 +290,7 @@
void ClassPrepare(art::Handle<art::mirror::Class> temp_klass,
art::Handle<art::mirror::Class> klass)
- REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ override REQUIRES_SHARED(art::Locks::mutator_lock_) {
if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassPrepare)) {
art::Thread* thread = art::Thread::Current();
if (temp_klass.Get() != klass.Get()) {
diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc
index 1588df4..6764538 100644
--- a/openjdkjvmti/ti_method.cc
+++ b/openjdkjvmti/ti_method.cc
@@ -689,7 +689,7 @@
val_(val),
obj_val_(nullptr) {}
- virtual jvmtiError GetResult() REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ jvmtiError GetResult() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
if (result_ == OK && type_ == art::Primitive::kPrimNot) {
val_->l = obj_val_.IsNull()
? nullptr
diff --git a/openjdkjvmti/ti_monitor.cc b/openjdkjvmti/ti_monitor.cc
index 6d3a37e..df29098 100644
--- a/openjdkjvmti/ti_monitor.cc
+++ b/openjdkjvmti/ti_monitor.cc
@@ -370,7 +370,7 @@
public:
GetContendedMonitorClosure() : out_(nullptr) {}
- void Run(art::Thread* target_thread) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ void Run(art::Thread* target_thread) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
art::ScopedAssertNoThreadSuspension sants("GetContendedMonitorClosure::Run");
switch (target_thread->GetState()) {
// These three we are actually currently waiting on a monitor and have sent the appropriate
diff --git a/openjdkjvmti/ti_stack.cc b/openjdkjvmti/ti_stack.cc
index b6969af..e2b98b3 100644
--- a/openjdkjvmti/ti_stack.cc
+++ b/openjdkjvmti/ti_stack.cc
@@ -79,7 +79,7 @@
GetStackTraceVisitor(const GetStackTraceVisitor&) = default;
GetStackTraceVisitor(GetStackTraceVisitor&&) = default;
- bool VisitFrame() REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
art::ArtMethod* m = GetMethod();
if (m->IsRuntimeMethod()) {
return true;
@@ -662,7 +662,7 @@
: art::StackVisitor(thread, nullptr, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames),
count(0) {}
- bool VisitFrame() REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
art::ArtMethod* m = GetMethod();
const bool do_count = !(m == nullptr || m->IsRuntimeMethod());
if (do_count) {
@@ -734,7 +734,7 @@
caller(nullptr),
caller_dex_pc(0) {}
- bool VisitFrame() REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) {
art::ArtMethod* m = GetMethod();
const bool do_count = !(m == nullptr || m->IsRuntimeMethod());
if (do_count) {
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index e533094..41ef6c2 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -1110,7 +1110,7 @@
public:
explicit StopThreadClosure(art::Handle<art::mirror::Throwable> except) : exception_(except) { }
- void Run(art::Thread* me) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ void Run(art::Thread* me) override REQUIRES_SHARED(art::Locks::mutator_lock_) {
// Make sure the thread is prepared to notice the exception.
art::Runtime::Current()->GetInstrumentation()->InstrumentThreadStack(me);
me->SetAsyncException(exception_.Get());
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index aaa3e83..5d38e8b 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -26,6 +26,7 @@
#include <vector>
#include "android-base/file.h"
+#include <android-base/parseint.h>
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
@@ -630,7 +631,7 @@
std::string image_relocation_filename =
output_image_relocation_directory
+ (android::base::StartsWith(original_image_filename, "/") ? "" : "/")
- + original_image_filename.substr(original_image_filename.find_last_of("/"));
+ + original_image_filename.substr(original_image_filename.find_last_of('/'));
int64_t input_image_size = input_image->GetLength();
if (input_image_size < 0) {
LOG(ERROR) << "Error while getting input image size";
@@ -1272,7 +1273,7 @@
} else if (option.starts_with("--base-offset-delta=")) {
const char* base_delta_str = option.substr(strlen("--base-offset-delta=")).data();
base_delta_set = true;
- if (!ParseInt(base_delta_str, &base_delta)) {
+ if (!android::base::ParseInt(base_delta_str, &base_delta)) {
Usage("Failed to parse --base-offset-delta argument '%s' as an off_t", base_delta_str);
}
} else if (option == "--dump-timings") {
diff --git a/patchoat/patchoat_test.cc b/patchoat/patchoat_test.cc
index 08bf31c..6492b96 100644
--- a/patchoat/patchoat_test.cc
+++ b/patchoat/patchoat_test.cc
@@ -529,7 +529,7 @@
ASSERT_EQ(rel_shortened_basenames, relocated_image_shortened_basenames);
}
- virtual void TearDown() {
+ void TearDown() override {
if (!dex2oat_orig_dir_.empty()) {
ClearDirectory(dex2oat_orig_dir_.c_str(), /*recursive*/ true);
rmdir(dex2oat_orig_dir_.c_str());
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 6ec6265..1cebb06 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -408,6 +408,49 @@
export_shared_lib_headers: ["libbase"],
}
+libart_static_cc_defaults {
+ name: "libart_static_base_defaults",
+ target: {
+ android: {
+ static_libs: ["libtombstoned_client_static"],
+ },
+ },
+ static_libs: [
+ "libbacktrace",
+ "libbase",
+ "libcutils",
+ "liblog",
+ "liblz4",
+ "liblzma",
+ "libnativebridge",
+ "libnativeloader",
+ "libunwindstack",
+ "libz",
+ ],
+}
+
+cc_defaults {
+ name: "libart_static_defaults",
+ defaults: [
+ "libart_static_base_defaults",
+ "libartbase_static_defaults",
+ "libdexfile_static_defaults",
+ "libprofile_static_defaults",
+ ],
+ static_libs: ["libart"],
+}
+
+cc_defaults {
+ name: "libartd_static_defaults",
+ defaults: [
+ "libart_static_base_defaults",
+ "libartbased_static_defaults",
+ "libdexfiled_static_defaults",
+ "libprofiled_static_defaults",
+ ],
+ static_libs: ["libartd"],
+}
+
gensrcs {
name: "art_operator_srcs",
cmd: "$(location generate_operator_out) art/runtime $(in) > $(out)",
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index f693524..9b69166 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -417,7 +417,6 @@
case Intrinsics::kMemoryPokeIntNative:
case Intrinsics::kMemoryPokeLongNative:
case Intrinsics::kMemoryPokeShortNative:
- return HiddenApiAccessFlags::kDarkGreylist;
case Intrinsics::kVarHandleFullFence:
case Intrinsics::kVarHandleAcquireFence:
case Intrinsics::kVarHandleReleaseFence:
diff --git a/runtime/barrier_test.cc b/runtime/barrier_test.cc
index 88075ba..5ec24bc 100644
--- a/runtime/barrier_test.cc
+++ b/runtime/barrier_test.cc
@@ -32,7 +32,7 @@
count1_(count1),
count2_(count2) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
LOG(INFO) << "Before barrier" << *self;
++*count1_;
barrier_->Wait(self);
@@ -40,7 +40,7 @@
LOG(INFO) << "After barrier" << *self;
}
- virtual void Finalize() {
+ void Finalize() override {
delete this;
}
@@ -91,7 +91,7 @@
count_(count),
subtasks_(subtasks) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
for (size_t i = 0; i < subtasks_; ++i) {
++*count_;
// Pass through to next subtask.
@@ -99,7 +99,7 @@
}
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
private:
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index e19dedc..f355f5b 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -431,6 +431,8 @@
heap->IncrementDisableMovingGC(self);
StackHandleScope<64> hs(self); // 64 is picked arbitrarily.
auto class_class_size = mirror::Class::ClassClassSize(image_pointer_size_);
+ // Allocate the object as non-movable so that there are no cases where Object::IsClass returns
+ // the incorrect result when comparing to-space vs from-space.
Handle<mirror::Class> java_lang_Class(hs.NewHandle(ObjPtr<mirror::Class>::DownCast(MakeObjPtr(
heap->AllocNonMovableObject<true>(self, nullptr, class_class_size, VoidFunctor())))));
CHECK(java_lang_Class != nullptr);
@@ -483,9 +485,17 @@
mirror::ObjectArray<mirror::Object>::ClassSize(image_pointer_size_))));
object_array_class->SetComponentType(java_lang_Object.Get());
- // Setup String.
+ // Setup java.lang.String.
+ //
+ // We make this class non-movable for the unlikely case where it were to be
+ // moved by a sticky-bit (minor) collection when using the Generational
+ // Concurrent Copying (CC) collector, potentially creating a stale reference
+ // in the `klass_` field of one of its instances allocated in the Large-Object
+ // Space (LOS) -- see the comment about the dirty card scanning logic in
+ // art::gc::collector::ConcurrentCopying::MarkingPhase.
Handle<mirror::Class> java_lang_String(hs.NewHandle(
- AllocClass(self, java_lang_Class.Get(), mirror::String::ClassSize(image_pointer_size_))));
+ AllocClass</* kMovable */ false>(
+ self, java_lang_Class.Get(), mirror::String::ClassSize(image_pointer_size_))));
java_lang_String->SetStringClass();
mirror::Class::SetStatus(java_lang_String, ClassStatus::kResolved, self);
@@ -528,13 +538,13 @@
// Create int array type for native pointer arrays (for example vtables) on 32-bit archs.
Handle<mirror::Class> int_array_class(hs.NewHandle(
- AllocClass(self, java_lang_Class.Get(), mirror::Array::ClassSize(image_pointer_size_))));
+ AllocPrimitiveArrayClass(self, java_lang_Class.Get())));
int_array_class->SetComponentType(GetClassRoot(ClassRoot::kPrimitiveInt, this));
SetClassRoot(ClassRoot::kIntArrayClass, int_array_class.Get());
// Create long array type for native pointer arrays (for example vtables) on 64-bit archs.
Handle<mirror::Class> long_array_class(hs.NewHandle(
- AllocClass(self, java_lang_Class.Get(), mirror::Array::ClassSize(image_pointer_size_))));
+ AllocPrimitiveArrayClass(self, java_lang_Class.Get())));
long_array_class->SetComponentType(GetClassRoot(ClassRoot::kPrimitiveLong, this));
SetClassRoot(ClassRoot::kLongArrayClass, long_array_class.Get());
@@ -610,20 +620,29 @@
CHECK_EQ(dalvik_system_ClassExt->GetObjectSize(), mirror::ClassExt::InstanceSize());
// Setup the primitive array type classes - can't be done until Object has a vtable.
- SetClassRoot(ClassRoot::kBooleanArrayClass, FindSystemClass(self, "[Z"));
+ AllocAndSetPrimitiveArrayClassRoot(self,
+ java_lang_Class.Get(),
+ ClassRoot::kBooleanArrayClass,
+ ClassRoot::kPrimitiveBoolean,
+ "[Z");
- SetClassRoot(ClassRoot::kByteArrayClass, FindSystemClass(self, "[B"));
+ AllocAndSetPrimitiveArrayClassRoot(
+ self, java_lang_Class.Get(), ClassRoot::kByteArrayClass, ClassRoot::kPrimitiveByte, "[B");
- SetClassRoot(ClassRoot::kCharArrayClass, FindSystemClass(self, "[C"));
+ AllocAndSetPrimitiveArrayClassRoot(
+ self, java_lang_Class.Get(), ClassRoot::kCharArrayClass, ClassRoot::kPrimitiveChar, "[C");
- SetClassRoot(ClassRoot::kShortArrayClass, FindSystemClass(self, "[S"));
+ AllocAndSetPrimitiveArrayClassRoot(
+ self, java_lang_Class.Get(), ClassRoot::kShortArrayClass, ClassRoot::kPrimitiveShort, "[S");
CheckSystemClass(self, int_array_class, "[I");
CheckSystemClass(self, long_array_class, "[J");
- SetClassRoot(ClassRoot::kFloatArrayClass, FindSystemClass(self, "[F"));
+ AllocAndSetPrimitiveArrayClassRoot(
+ self, java_lang_Class.Get(), ClassRoot::kFloatArrayClass, ClassRoot::kPrimitiveFloat, "[F");
- SetClassRoot(ClassRoot::kDoubleArrayClass, FindSystemClass(self, "[D"));
+ AllocAndSetPrimitiveArrayClassRoot(
+ self, java_lang_Class.Get(), ClassRoot::kDoubleArrayClass, ClassRoot::kPrimitiveDouble, "[D");
// Run Class through FindSystemClass. This initializes the dex_cache_ fields and register it
// in class_table_.
@@ -1140,7 +1159,7 @@
VerifyDeclaringClassVisitor() REQUIRES_SHARED(Locks::mutator_lock_, Locks::heap_bitmap_lock_)
: live_bitmap_(Runtime::Current()->GetHeap()->GetLiveBitmap()) {}
- virtual void Visit(ArtMethod* method)
+ void Visit(ArtMethod* method) override
REQUIRES_SHARED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
ObjPtr<mirror::Class> klass = method->GetDeclaringClassUnchecked();
if (klass != nullptr) {
@@ -1540,7 +1559,7 @@
public:
explicit VerifyClassInTableArtMethodVisitor(ClassTable* table) : table_(table) {}
- virtual void Visit(ArtMethod* method)
+ void Visit(ArtMethod* method) override
REQUIRES_SHARED(Locks::mutator_lock_, Locks::classlinker_classes_lock_) {
ObjPtr<mirror::Class> klass = method->GetDeclaringClass();
if (klass != nullptr && !Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass)) {
@@ -2165,13 +2184,14 @@
return dex_cache;
}
+template <bool kMovable>
ObjPtr<mirror::Class> ClassLinker::AllocClass(Thread* self,
ObjPtr<mirror::Class> java_lang_Class,
uint32_t class_size) {
DCHECK_GE(class_size, sizeof(mirror::Class));
gc::Heap* heap = Runtime::Current()->GetHeap();
mirror::Class::InitializeClassVisitor visitor(class_size);
- ObjPtr<mirror::Object> k = kMovingClasses ?
+ ObjPtr<mirror::Object> k = (kMovingClasses && kMovable) ?
heap->AllocObject<true>(self, java_lang_Class, class_size, visitor) :
heap->AllocNonMovableObject<true>(self, java_lang_Class, class_size, visitor);
if (UNLIKELY(k == nullptr)) {
@@ -2185,6 +2205,18 @@
return AllocClass(self, GetClassRoot<mirror::Class>(this), class_size);
}
+ObjPtr<mirror::Class> ClassLinker::AllocPrimitiveArrayClass(Thread* self,
+ ObjPtr<mirror::Class> java_lang_Class) {
+ // We make this class non-movable for the unlikely case where it were to be
+ // moved by a sticky-bit (minor) collection when using the Generational
+ // Concurrent Copying (CC) collector, potentially creating a stale reference
+ // in the `klass_` field of one of its instances allocated in the Large-Object
+ // Space (LOS) -- see the comment about the dirty card scanning logic in
+ // art::gc::collector::ConcurrentCopying::MarkingPhase.
+ return AllocClass</* kMovable */ false>(
+ self, java_lang_Class, mirror::Array::ClassSize(image_pointer_size_));
+}
+
ObjPtr<mirror::ObjectArray<mirror::StackTraceElement>> ClassLinker::AllocStackTraceElementArray(
Thread* self,
size_t length) {
@@ -3648,10 +3680,22 @@
new_class.Assign(GetClassRoot<mirror::ObjectArray<mirror::Object>>(this));
} else if (strcmp(descriptor, "[Ljava/lang/String;") == 0) {
new_class.Assign(GetClassRoot<mirror::ObjectArray<mirror::String>>(this));
+ } else if (strcmp(descriptor, "[Z") == 0) {
+ new_class.Assign(GetClassRoot<mirror::BooleanArray>(this));
+ } else if (strcmp(descriptor, "[B") == 0) {
+ new_class.Assign(GetClassRoot<mirror::ByteArray>(this));
+ } else if (strcmp(descriptor, "[C") == 0) {
+ new_class.Assign(GetClassRoot<mirror::CharArray>(this));
+ } else if (strcmp(descriptor, "[S") == 0) {
+ new_class.Assign(GetClassRoot<mirror::ShortArray>(this));
} else if (strcmp(descriptor, "[I") == 0) {
new_class.Assign(GetClassRoot<mirror::IntArray>(this));
} else if (strcmp(descriptor, "[J") == 0) {
new_class.Assign(GetClassRoot<mirror::LongArray>(this));
+ } else if (strcmp(descriptor, "[F") == 0) {
+ new_class.Assign(GetClassRoot<mirror::FloatArray>(this));
+ } else if (strcmp(descriptor, "[D") == 0) {
+ new_class.Assign(GetClassRoot<mirror::DoubleArray>(this));
}
}
if (new_class == nullptr) {
@@ -8607,6 +8651,19 @@
class_roots->Set<false>(index, klass);
}
+void ClassLinker::AllocAndSetPrimitiveArrayClassRoot(Thread* self,
+ ObjPtr<mirror::Class> java_lang_Class,
+ ClassRoot primitive_array_class_root,
+ ClassRoot primitive_class_root,
+ const char* descriptor) {
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Class> primitive_array_class(hs.NewHandle(
+ AllocPrimitiveArrayClass(self, java_lang_Class)));
+ primitive_array_class->SetComponentType(GetClassRoot(primitive_class_root, this));
+ SetClassRoot(primitive_array_class_root, primitive_array_class.Get());
+ CheckSystemClass(self, primitive_array_class, descriptor);
+}
+
jobject ClassLinker::CreateWellKnownClassLoader(Thread* self,
const std::vector<const DexFile*>& dex_files,
jclass loader_class,
@@ -8941,7 +8998,7 @@
ifcount * mirror::IfTable::kMax)));
}
-// Instantiate ResolveMethod.
+// Instantiate ClassLinker::ResolveMethod.
template ArtMethod* ClassLinker::ResolveMethod<ClassLinker::ResolveMode::kCheckICCEAndIAE>(
uint32_t method_idx,
Handle<mirror::DexCache> dex_cache,
@@ -8955,4 +9012,14 @@
ArtMethod* referrer,
InvokeType type);
+// Instantiate ClassLinker::AllocClass.
+template ObjPtr<mirror::Class> ClassLinker::AllocClass</* kMovable */ true>(
+ Thread* self,
+ ObjPtr<mirror::Class> java_lang_Class,
+ uint32_t class_size);
+template ObjPtr<mirror::Class> ClassLinker::AllocClass</* kMovable */ false>(
+ Thread* self,
+ ObjPtr<mirror::Class> java_lang_Class,
+ uint32_t class_size);
+
} // namespace art
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index e4d9c96..efe29d3 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -775,7 +775,11 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_, !Roles::uninterruptible_);
- // For early bootstrapping by Init
+ // For early bootstrapping by Init.
+ // If we do not allow moving classes (`art::kMovingClass` is false) or if
+ // parameter `kMovable` is false (or both), the class object is allocated in
+ // the non-moving space.
+ template <bool kMovable = true>
ObjPtr<mirror::Class> AllocClass(Thread* self,
ObjPtr<mirror::Class> java_lang_Class,
uint32_t class_size)
@@ -789,6 +793,12 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
+ // Allocate a primitive array class.
+ ObjPtr<mirror::Class> AllocPrimitiveArrayClass(Thread* self,
+ ObjPtr<mirror::Class> java_lang_Class)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(!Roles::uninterruptible_);
+
ObjPtr<mirror::DexCache> AllocDexCache(/*out*/ ObjPtr<mirror::String>* out_location,
Thread* self,
const DexFile& dex_file)
@@ -1206,6 +1216,20 @@
void SetClassRoot(ClassRoot class_root, ObjPtr<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_);
+ // Allocate primitive array class for primitive with class root
+ // `primitive_class_root`, and associate it to class root
+ // `primitive_array_class_root`.
+ //
+ // Also check this class returned when searching system classes for
+ // `descriptor` matches the allocated class.
+ void AllocAndSetPrimitiveArrayClassRoot(Thread* self,
+ ObjPtr<mirror::Class> java_lang_Class,
+ ClassRoot primitive_array_class_root,
+ ClassRoot primitive_class_root,
+ const char* descriptor)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(!Roles::uninterruptible_);
+
// Return the quick generic JNI stub for testing.
const void* GetRuntimeQuickGenericJniStub() const;
diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc
index 2bd5411..f6b764d 100644
--- a/runtime/class_loader_context.cc
+++ b/runtime/class_loader_context.cc
@@ -16,6 +16,8 @@
#include "class_loader_context.h"
+#include <android-base/parseint.h>
+
#include "art_field-inl.h"
#include "base/dchecked_vector.h"
#include "base/stl_util.h"
@@ -120,7 +122,7 @@
return false;
}
uint32_t checksum = 0;
- if (!ParseInt(dex_file_with_checksum[1].c_str(), &checksum)) {
+ if (!android::base::ParseInt(dex_file_with_checksum[1].c_str(), &checksum)) {
return false;
}
class_loader_chain_.back().classpath.push_back(dex_file_with_checksum[0]);
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 366b5ec..7103214 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -897,7 +897,7 @@
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
- bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
+ bool VisitFrame() override NO_THREAD_SAFETY_ANALYSIS {
if (!GetMethod()->IsRuntimeMethod()) {
Monitor::VisitLocks(this, AppendOwnedMonitors, this);
++current_stack_depth;
@@ -2406,7 +2406,7 @@
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
- bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
+ bool VisitFrame() override NO_THREAD_SAFETY_ANALYSIS {
if (!GetMethod()->IsRuntimeMethod()) {
++depth;
}
@@ -2576,7 +2576,7 @@
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
- virtual bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
+ bool VisitFrame() override NO_THREAD_SAFETY_ANALYSIS {
if (frame_id != GetFrameId()) {
return true; // continue
} else {
@@ -2618,7 +2618,7 @@
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
- bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
+ bool VisitFrame() override NO_THREAD_SAFETY_ANALYSIS {
if (GetFrameId() != frame_id_) {
return true; // Not our frame, carry on.
}
@@ -3831,7 +3831,7 @@
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
- bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
+ bool VisitFrame() override NO_THREAD_SAFETY_ANALYSIS {
ArtMethod* m = GetMethod();
if (!m->IsRuntimeMethod()) {
++stack_depth;
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index e6f3d0b..1045d2a 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -317,20 +317,9 @@
ArtMethod* referrer,
Thread* self,
size_t expected_size) {
- bool is_primitive;
- bool is_set;
- bool is_static;
- switch (type) {
- case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break;
- case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break;
- case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break;
- case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break;
- case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break;
- case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break;
- case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break;
- case StaticPrimitiveWrite: // Keep GCC happy by having a default handler, fall-through.
- default: is_primitive = true; is_set = true; is_static = true; break;
- }
+ constexpr bool is_primitive = (type & FindFieldFlags::PrimitiveBit) != 0;
+ constexpr bool is_set = (type & FindFieldFlags::WriteBit) != 0;
+ constexpr bool is_static = (type & FindFieldFlags::StaticBit) != 0;
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
ArtField* resolved_field;
@@ -611,22 +600,9 @@
return nullptr;
}
// Check for incompatible class change.
- bool is_primitive;
- bool is_set;
- bool is_static;
- switch (type) {
- case InstanceObjectRead: is_primitive = false; is_set = false; is_static = false; break;
- case InstanceObjectWrite: is_primitive = false; is_set = true; is_static = false; break;
- case InstancePrimitiveRead: is_primitive = true; is_set = false; is_static = false; break;
- case InstancePrimitiveWrite: is_primitive = true; is_set = true; is_static = false; break;
- case StaticObjectRead: is_primitive = false; is_set = false; is_static = true; break;
- case StaticObjectWrite: is_primitive = false; is_set = true; is_static = true; break;
- case StaticPrimitiveRead: is_primitive = true; is_set = false; is_static = true; break;
- case StaticPrimitiveWrite: is_primitive = true; is_set = true; is_static = true; break;
- default:
- LOG(FATAL) << "UNREACHABLE";
- UNREACHABLE();
- }
+ const bool is_primitive = (type & FindFieldFlags::PrimitiveBit) != 0;
+ const bool is_set = (type & FindFieldFlags::WriteBit) != 0;
+ const bool is_static = (type & FindFieldFlags::StaticBit) != 0;
if (UNLIKELY(resolved_field->IsStatic() != is_static)) {
// Incompatible class change.
return nullptr;
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 9d70b03..c8bf6d0 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -103,16 +103,25 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
+enum FindFieldFlags {
+ InstanceBit = 1 << 0,
+ StaticBit = 1 << 1,
+ ObjectBit = 1 << 2,
+ PrimitiveBit = 1 << 3,
+ ReadBit = 1 << 4,
+ WriteBit = 1 << 5,
+};
+
// Type of find field operation for fast and slow case.
enum FindFieldType {
- InstanceObjectRead,
- InstanceObjectWrite,
- InstancePrimitiveRead,
- InstancePrimitiveWrite,
- StaticObjectRead,
- StaticObjectWrite,
- StaticPrimitiveRead,
- StaticPrimitiveWrite,
+ InstanceObjectRead = InstanceBit | ObjectBit | ReadBit,
+ InstanceObjectWrite = InstanceBit | ObjectBit | WriteBit,
+ InstancePrimitiveRead = InstanceBit | PrimitiveBit | ReadBit,
+ InstancePrimitiveWrite = InstanceBit | PrimitiveBit | WriteBit,
+ StaticObjectRead = StaticBit | ObjectBit | ReadBit,
+ StaticObjectWrite = StaticBit | ObjectBit | WriteBit,
+ StaticPrimitiveRead = StaticBit | PrimitiveBit | ReadBit,
+ StaticPrimitiveWrite = StaticBit | PrimitiveBit | WriteBit,
};
template<FindFieldType type, bool access_check>
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 62cc9de..d38e3ed 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -28,13 +28,6 @@
namespace art {
-inline constexpr bool FindFieldTypeIsRead(FindFieldType type) {
- return type == InstanceObjectRead ||
- type == InstancePrimitiveRead ||
- type == StaticObjectRead ||
- type == StaticPrimitiveRead;
-}
-
// Helper function to do a null check after trying to resolve the field. Not for statics since obj
// does not exist there. There is a suspend check, object is a double pointer to update the value
// in the caller in case it moves.
@@ -50,7 +43,7 @@
HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(obj));
ArtField* field = FindFieldFromCode<type, kAccessCheck>(field_idx, referrer, self, size);
if (LIKELY(field != nullptr) && UNLIKELY(h == nullptr)) {
- ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/FindFieldTypeIsRead(type));
+ ThrowNullPointerExceptionForFieldAccess(field, (type & FindFieldFlags::ReadBit) != 0);
return nullptr;
}
return field;
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 3a80008..d91cc24 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -423,7 +423,7 @@
void VisitRoots(mirror::Object*** roots,
size_t count,
- const RootInfo& info ATTRIBUTE_UNUSED)
+ const RootInfo& info ATTRIBUTE_UNUSED) override
REQUIRES_SHARED(Locks::mutator_lock_) {
Thread* self = Thread::Current();
for (size_t i = 0; i < count; ++i) {
@@ -440,7 +440,7 @@
void VisitRoots(mirror::CompressedReference<mirror::Object>** roots,
size_t count,
- const RootInfo& info ATTRIBUTE_UNUSED)
+ const RootInfo& info ATTRIBUTE_UNUSED) override
REQUIRES_SHARED(Locks::mutator_lock_) {
Thread* self = Thread::Current();
for (size_t i = 0; i < count; ++i) {
@@ -905,13 +905,8 @@
// during a minor (young-generation) collection:
// - In the case where we run with a boot image, these classes are part of the image space,
// which is an immune space.
- // - In the case where we run without a boot image, these classes are allocated in the region
- // space (main space), but they are not expected to move during a minor collection (this
- // would only happen if those classes were allocated between a major and a minor
- // collections, which is unlikely -- we don't expect any GC to happen before these
- // fundamental classes are initialized). Note that these classes could move during a major
- // collection though, but this is fine: in that case, the whole heap is traced and the card
- // table logic below is not used.
+ // - In the case where we run without a boot image, these classes are allocated in the
+ // non-moving space (see art::ClassLinker::InitWithoutImage).
Runtime::Current()->GetHeap()->GetCardTable()->Scan<false>(
space->GetMarkBitmap(),
space->Begin(),
@@ -2331,6 +2326,7 @@
CHECK(!region_space_->HasAddress(ref)) << "obj=" << obj << " ref=" << ref;
// In a non-moving space. Check that the ref is marked.
if (immune_spaces_.ContainsObject(ref)) {
+ // Immune space case.
if (kUseBakerReadBarrier) {
// Immune object may not be gray if called from the GC.
if (Thread::Current() == thread_running_gc_ && !gc_grays_immune_objects_) {
@@ -2344,28 +2340,68 @@
<< " updated_all_immune_objects=" << updated_all_immune_objects;
}
} else {
+ // Non-moving space and large-object space (LOS) cases.
accounting::ContinuousSpaceBitmap* mark_bitmap =
heap_mark_bitmap_->GetContinuousSpaceBitmap(ref);
accounting::LargeObjectBitmap* los_bitmap =
heap_mark_bitmap_->GetLargeObjectBitmap(ref);
- bool is_los = mark_bitmap == nullptr;
- if ((!is_los && mark_bitmap->Test(ref)) ||
- (is_los && los_bitmap->Test(ref))) {
- // OK.
- } else {
- // If `ref` is on the allocation stack, then it may not be
- // marked live, but considered marked/alive (but not
- // necessarily on the live stack).
- CHECK(IsOnAllocStack(ref))
- << "Unmarked ref that's not on the allocation stack."
- << " obj=" << obj
- << " ref=" << ref
- << " rb_state=" << ref->GetReadBarrierState()
- << " is_los=" << std::boolalpha << is_los << std::noboolalpha
- << " is_marking=" << std::boolalpha << is_marking_ << std::noboolalpha
- << " young_gen=" << std::boolalpha << young_gen_ << std::noboolalpha
- << " self=" << Thread::Current();
- }
+ bool is_los = (mark_bitmap == nullptr);
+
+ bool marked_in_non_moving_space_or_los =
+ (kUseBakerReadBarrier
+ && kEnableGenerationalConcurrentCopyingCollection
+ && young_gen_
+ && !done_scanning_.load(std::memory_order_acquire))
+ // Don't use the mark bitmap to ensure `ref` is marked: check that the
+ // read barrier state is gray instead. This is to take into account a
+ // potential race between two read barriers on the same reference when the
+ // young-generation collector is still scanning the dirty cards.
+ //
+ // For instance consider two concurrent read barriers on the same GC root
+ // reference during the dirty-card-scanning step of a young-generation
+ // collection. Both threads would call ReadBarrier::BarrierForRoot, which
+ // would:
+ // a. mark the reference (leading to a call to
+ // ConcurrentCopying::MarkNonMoving); then
+ // b. check the to-space invariant (leading to a call this
+ // ConcurrentCopying::AssertToSpaceInvariantInNonMovingSpace -- this
+ // method).
+ //
+ // In this situation, the following race could happen:
+ // 1. Thread A successfully changes `ref`'s read barrier state from
+ // non-gray (white) to gray (with AtomicSetReadBarrierState) in
+ // ConcurrentCopying::MarkNonMoving, then gets preempted.
+ // 2. Thread B also tries to change `ref`'s read barrier state with
+ // AtomicSetReadBarrierState from non-gray to gray in
+ // ConcurrentCopying::MarkNonMoving, but fails, as Thread A already
+ // changed it.
+ // 3. Because Thread B failed the previous CAS, it does *not* set the
+ // bit in the mark bitmap for `ref`.
+ // 4. Thread B checks the to-space invariant and calls
+ // ConcurrentCopying::AssertToSpaceInvariantInNonMovingSpace: the bit
+ // is not set in the mark bitmap for `ref`; checking that this bit is
+ // set to check the to-space invariant is therefore not a reliable
+ // test.
+ // 5. (Note that eventually, Thread A will resume its execution and set
+ // the bit for `ref` in the mark bitmap.)
+ ? (ref->GetReadBarrierState() == ReadBarrier::GrayState())
+ // It is safe to use the heap mark bitmap otherwise.
+ : (!is_los && mark_bitmap->Test(ref)) || (is_los && los_bitmap->Test(ref));
+
+ // If `ref` is on the allocation stack, then it may not be
+ // marked live, but considered marked/alive (but not
+ // necessarily on the live stack).
+ CHECK(marked_in_non_moving_space_or_los || IsOnAllocStack(ref))
+ << "Unmarked ref that's not on the allocation stack."
+ << " obj=" << obj
+ << " ref=" << ref
+ << " rb_state=" << ref->GetReadBarrierState()
+ << " is_los=" << std::boolalpha << is_los << std::noboolalpha
+ << " is_marking=" << std::boolalpha << is_marking_ << std::noboolalpha
+ << " young_gen=" << std::boolalpha << young_gen_ << std::noboolalpha
+ << " done_scanning="
+ << std::boolalpha << done_scanning_.load(std::memory_order_acquire) << std::noboolalpha
+ << " self=" << Thread::Current();
}
}
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index 23b2719..5f44a72 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -789,12 +789,12 @@
mark_stack_[mark_stack_pos_++].Assign(obj);
}
- virtual void Finalize() {
+ void Finalize() override {
delete this;
}
// Scans all of the objects
- virtual void Run(Thread* self ATTRIBUTE_UNUSED)
+ void Run(Thread* self ATTRIBUTE_UNUSED) override
REQUIRES(Locks::heap_bitmap_lock_)
REQUIRES_SHARED(Locks::mutator_lock_) {
ScanObjectParallelVisitor visitor(this);
@@ -852,11 +852,11 @@
const uint8_t minimum_age_;
const bool clear_card_;
- virtual void Finalize() {
+ void Finalize() override {
delete this;
}
- virtual void Run(Thread* self) NO_THREAD_SAFETY_ANALYSIS {
+ void Run(Thread* self) override NO_THREAD_SAFETY_ANALYSIS {
ScanObjectParallelVisitor visitor(this);
accounting::CardTable* card_table = mark_sweep_->GetHeap()->GetCardTable();
size_t cards_scanned = clear_card_
@@ -1009,12 +1009,12 @@
const uintptr_t begin_;
const uintptr_t end_;
- virtual void Finalize() {
+ void Finalize() override {
delete this;
}
// Scans all of the objects
- virtual void Run(Thread* self) NO_THREAD_SAFETY_ANALYSIS {
+ void Run(Thread* self) override NO_THREAD_SAFETY_ANALYSIS {
ScanObjectParallelVisitor visitor(this);
bitmap_->VisitMarkedRange(begin_, end_, visitor);
// Finish by emptying our local mark stack.
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 589e9a4..b6610b7 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -450,6 +450,7 @@
// Non moving space is always dlmalloc since we currently don't have support for multiple
// active rosalloc spaces.
const size_t size = non_moving_space_mem_map.Size();
+ const void* non_moving_space_mem_map_begin = non_moving_space_mem_map.Begin();
non_moving_space_ = space::DlMallocSpace::CreateFromMemMap(std::move(non_moving_space_mem_map),
"zygote / non moving space",
kDefaultStartingSize,
@@ -457,9 +458,9 @@
size,
size,
/* can_move_objects */ false);
- non_moving_space_->SetFootprintLimit(non_moving_space_->Capacity());
CHECK(non_moving_space_ != nullptr) << "Failed creating non moving space "
- << non_moving_space_mem_map.Begin();
+ << non_moving_space_mem_map_begin;
+ non_moving_space_->SetFootprintLimit(non_moving_space_->Capacity());
AddSpace(non_moving_space_);
}
// Create other spaces based on whether or not we have a moving GC.
@@ -2279,13 +2280,13 @@
}
}
- virtual bool ShouldSweepSpace(space::ContinuousSpace* space ATTRIBUTE_UNUSED) const {
+ bool ShouldSweepSpace(space::ContinuousSpace* space ATTRIBUTE_UNUSED) const override {
// Don't sweep any spaces since we probably blasted the internal accounting of the free list
// allocator.
return false;
}
- virtual mirror::Object* MarkNonForwardedObject(mirror::Object* obj)
+ mirror::Object* MarkNonForwardedObject(mirror::Object* obj) override
REQUIRES(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
size_t obj_size = obj->SizeOf<kDefaultVerifyFlags>();
size_t alloc_size = RoundUp(obj_size, kObjectAlignment);
diff --git a/runtime/gc/heap_test.cc b/runtime/gc/heap_test.cc
index 7cbad3b..05a04f2 100644
--- a/runtime/gc/heap_test.cc
+++ b/runtime/gc/heap_test.cc
@@ -96,7 +96,7 @@
}
class ZygoteHeapTest : public CommonRuntimeTest {
- void SetUpRuntimeOptions(RuntimeOptions* options) {
+ void SetUpRuntimeOptions(RuntimeOptions* options) override {
CommonRuntimeTest::SetUpRuntimeOptions(options);
options->push_back(std::make_pair("-Xzygote", nullptr));
}
diff --git a/runtime/gc/heap_verification_test.cc b/runtime/gc/heap_verification_test.cc
index 6caca84..3754129 100644
--- a/runtime/gc/heap_verification_test.cc
+++ b/runtime/gc/heap_verification_test.cc
@@ -83,7 +83,12 @@
}
TEST_F(VerificationTest, IsValidClassInHeap) {
- TEST_DISABLED_FOR_MEMORY_TOOL_WITH_HEAP_POISONING();
+ // Now that the String class is allocated in the non-moving space when the
+ // runtime is running without a boot image (which is the case in this gtest),
+ // and we run with AddressSanizer, it is possible that the (presumably
+ // invalid) memory location `uint_klass - kObjectAlignment` tested below is
+ // poisoned when running with AddressSanizer. Disable this test in that case.
+ TEST_DISABLED_FOR_MEMORY_TOOL();
ScopedObjectAccess soa(Thread::Current());
VariableSizedHandleScope hs(soa.Self());
Handle<mirror::String> string(
@@ -106,7 +111,13 @@
}
TEST_F(VerificationTest, DumpValidObjectInfo) {
- TEST_DISABLED_FOR_MEMORY_TOOL_WITH_HEAP_POISONING();
+ // Now that the String class is allocated in the non-moving space when the
+ // runtime is running without a boot image (which is the case in this gtest),
+ // and we run with AddressSanizer, it is possible that the calls to
+ // Verification::DumpObjectInfo below involving the String class object
+ // (`string->GetClass()`, `uint_klass`, etc.) access poisoned memory when they
+ // call Verification::DumpRAMAroundAddress. Disable this test in that case.
+ TEST_DISABLED_FOR_MEMORY_TOOL();
ScopedLogSeverity sls(LogSeverity::INFO);
ScopedObjectAccess soa(Thread::Current());
Runtime* const runtime = Runtime::Current();
@@ -126,7 +137,13 @@
}
TEST_F(VerificationTest, LogHeapCorruption) {
- TEST_DISABLED_FOR_MEMORY_TOOL_WITH_HEAP_POISONING();
+ // Now that the String class is allocated in the non-moving space when the
+ // runtime is running without a boot image (which is the case in this gtest),
+ // and we run with AddressSanizer, it is possible that the call to
+ // Verification::LogHeapCorruption below involving the String class object
+ // (`string->GetClass()`) accesses poisoned memory when it calls
+ // Verification::DumpRAMAroundAddress. Disable this test in that case.
+ TEST_DISABLED_FOR_MEMORY_TOOL();
ScopedLogSeverity sls(LogSeverity::INFO);
ScopedObjectAccess soa(Thread::Current());
Runtime* const runtime = Runtime::Current();
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc
index fe4124d..c212bad 100644
--- a/runtime/gc/reference_processor.cc
+++ b/runtime/gc/reference_processor.cc
@@ -276,7 +276,7 @@
explicit ClearedReferenceTask(jobject cleared_references)
: HeapTask(NanoTime()), cleared_references_(cleared_references) {
}
- virtual void Run(Thread* thread) {
+ void Run(Thread* thread) override {
ScopedObjectAccess soa(thread);
jvalue args[1];
args[0].l = cleared_references_;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 3999e27..316bfe1 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1008,7 +1008,7 @@
}
if (obj->IsClass()) {
- mirror::Class* klass = obj->AsClass<kVerifyNone, kWithoutReadBarrier>();
+ mirror::Class* klass = obj->AsClass<kVerifyNone>();
// Fixup super class before visiting instance fields which require
// information from their super class to calculate offsets.
mirror::Class* super_class = klass->GetSuperClass<kVerifyNone, kWithoutReadBarrier>();
@@ -1026,8 +1026,8 @@
*this);
// Note that this code relies on no circular dependencies.
// We want to use our own class loader and not the one in the image.
- if (obj->IsClass<kVerifyNone, kWithoutReadBarrier>()) {
- mirror::Class* as_klass = obj->AsClass<kVerifyNone, kWithoutReadBarrier>();
+ if (obj->IsClass<kVerifyNone>()) {
+ mirror::Class* as_klass = obj->AsClass<kVerifyNone>();
FixupObjectAdapter visitor(boot_image_, boot_oat_, app_image_, app_oat_);
as_klass->FixupNativePointers<kVerifyNone, kWithoutReadBarrier>(as_klass,
pointer_size_,
@@ -1099,7 +1099,7 @@
fixup_heap_objects_(fixup_heap_objects),
pointer_size_(pointer_size) {}
- virtual void Visit(ArtMethod* method) NO_THREAD_SAFETY_ANALYSIS {
+ void Visit(ArtMethod* method) override NO_THREAD_SAFETY_ANALYSIS {
// TODO: Separate visitor for runtime vs normal methods.
if (UNLIKELY(method->IsRuntimeMethod())) {
ImtConflictTable* table = method->GetImtConflictTable(pointer_size_);
@@ -1132,7 +1132,7 @@
template<typename... Args>
explicit FixupArtFieldVisitor(Args... args) : FixupVisitor(args...) {}
- virtual void Visit(ArtField* field) NO_THREAD_SAFETY_ANALYSIS {
+ void Visit(ArtField* field) override NO_THREAD_SAFETY_ANALYSIS {
field->UpdateObjects(ForwardObjectAdapter(this));
}
};
diff --git a/runtime/gc/space/large_object_space_test.cc b/runtime/gc/space/large_object_space_test.cc
index 9baa016..d55ccd6 100644
--- a/runtime/gc/space/large_object_space_test.cc
+++ b/runtime/gc/space/large_object_space_test.cc
@@ -128,7 +128,7 @@
AllocRaceTask(size_t id, size_t iterations, size_t size, LargeObjectSpace* los) :
id_(id), iterations_(iterations), size_(size), los_(los) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
for (size_t i = 0; i < iterations_ ; ++i) {
size_t alloc_size, bytes_tl_bulk_allocated;
mirror::Object* ptr = los_->Alloc(self, size_, &alloc_size, nullptr,
@@ -140,7 +140,7 @@
}
}
- virtual void Finalize() {
+ void Finalize() override {
delete this;
}
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index b42433c..03fd964 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -1385,7 +1385,7 @@
: StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
shorty('V') {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
if (m != nullptr && !m->IsRuntimeMethod()) {
// The first Java method.
diff --git a/runtime/interpreter/mterp/arm/field.S b/runtime/interpreter/mterp/arm/field.S
new file mode 100644
index 0000000..c468788
--- /dev/null
+++ b/runtime/interpreter/mterp/arm/field.S
@@ -0,0 +1,16 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl $helper
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
diff --git a/runtime/interpreter/mterp/arm/op_iget.S b/runtime/interpreter/mterp/arm/op_iget.S
index 1684a76..1fa32fa 100644
--- a/runtime/interpreter/mterp/arm/op_iget.S
+++ b/runtime/interpreter/mterp/arm/op_iget.S
@@ -1,26 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
- bl $helper
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if $is_object
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_iget_wide.S b/runtime/interpreter/mterp/arm/op_iget_wide.S
index 46e9ec8..ede21eb 100644
--- a/runtime/interpreter/mterp/arm/op_iget_wide.S
+++ b/runtime/interpreter/mterp/arm/op_iget_wide.S
@@ -1,23 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
- bl MterpIGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpException @ bail out
- CLEAR_SHADOW_PAIR r2, ip, lr @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r3, r2 @ r3<- &fp[A]
- stmia r3, {r0-r1} @ fp[A]<- r0/r1
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/arm/op_iput.S b/runtime/interpreter/mterp/arm/op_iput.S
index a16795d..6201d80 100644
--- a/runtime/interpreter/mterp/arm/op_iput.S
+++ b/runtime/interpreter/mterp/arm/op_iput.S
@@ -1,22 +1,2 @@
%default { "is_object":"0", "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
- bl $helper
- cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_iput_object.S b/runtime/interpreter/mterp/arm/op_iput_object.S
index 4f401eb..1003d10 100644
--- a/runtime/interpreter/mterp/arm/op_iput_object.S
+++ b/runtime/interpreter/mterp/arm/op_iput_object.S
@@ -1,11 +1 @@
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpIPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/arm/op_iput_wide.S b/runtime/interpreter/mterp/arm/op_iput_wide.S
index 6a41473..f2845ad 100644
--- a/runtime/interpreter/mterp/arm/op_iput_wide.S
+++ b/runtime/interpreter/mterp/arm/op_iput_wide.S
@@ -1,16 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU64
- cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/arm/op_sget.S b/runtime/interpreter/mterp/arm/op_sget.S
index 575a8c0..b382de4 100644
--- a/runtime/interpreter/mterp/arm/op_sget.S
+++ b/runtime/interpreter/mterp/arm/op_sget.S
@@ -1,27 +1,2 @@
%default { "is_object":"0", "helper":"MterpSGetU32" }
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
-
- .extern $helper
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl $helper
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if $is_object
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
- ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_sget_wide.S b/runtime/interpreter/mterp/arm/op_sget_wide.S
index 5981ec4..d6905df 100644
--- a/runtime/interpreter/mterp/arm/op_sget_wide.S
+++ b/runtime/interpreter/mterp/arm/op_sget_wide.S
@@ -1,22 +1 @@
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field@BBBB */
-
- .extern MterpSGetU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r9, rINST, lsr #8 @ r9<- AA
- VREG_INDEX_TO_ADDR lr, r9 @ r9<- &fp[AA]
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r9, r2, ip @ Zero out the shadow regs
- stmia lr, {r0-r1} @ vAA/vAA+1<- r0/r1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/arm/op_sput.S b/runtime/interpreter/mterp/arm/op_sput.S
index c4a8978..171f024 100644
--- a/runtime/interpreter/mterp/arm/op_sput.S
+++ b/runtime/interpreter/mterp/arm/op_sput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpSPutU32"}
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl $helper
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "arm/field.S" { }
diff --git a/runtime/interpreter/mterp/arm/op_sput_object.S b/runtime/interpreter/mterp/arm/op_sput_object.S
index c58918f..8fcd52e 100644
--- a/runtime/interpreter/mterp/arm/op_sput_object.S
+++ b/runtime/interpreter/mterp/arm/op_sput_object.S
@@ -1,11 +1 @@
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpSPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/arm/op_sput_wide.S b/runtime/interpreter/mterp/arm/op_sput_wide.S
index 0ed4017..c254f78 100644
--- a/runtime/interpreter/mterp/arm/op_sput_wide.S
+++ b/runtime/interpreter/mterp/arm/op_sput_wide.S
@@ -1,19 +1 @@
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r1, rINST, lsr #8 @ r1<- AA
- VREG_INDEX_TO_ADDR r1, r1
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU64
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+%include "arm/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/arm64/field.S b/runtime/interpreter/mterp/arm64/field.S
new file mode 100644
index 0000000..631c8d1
--- /dev/null
+++ b/runtime/interpreter/mterp/arm64/field.S
@@ -0,0 +1,15 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl $helper
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
diff --git a/runtime/interpreter/mterp/arm64/op_iget.S b/runtime/interpreter/mterp/arm64/op_iget.S
index cb453ac..48b9cad 100644
--- a/runtime/interpreter/mterp/arm64/op_iget.S
+++ b/runtime/interpreter/mterp/arm64/op_iget.S
@@ -1,26 +1,2 @@
-%default { "extend":"", "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
- bl $helper
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- $extend
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if $is_object
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%default { "is_object":"0", "helper":"MterpIGetU32"}
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_boolean.S b/runtime/interpreter/mterp/arm64/op_iget_boolean.S
index 3b17144..9a83b2a 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_boolean.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_boolean.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetU8", "extend":"uxtb w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetU8" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_byte.S b/runtime/interpreter/mterp/arm64/op_iget_byte.S
index d5ef1d3..f73e634 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_byte.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_byte.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetI8", "extend":"sxtb w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetI8" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_char.S b/runtime/interpreter/mterp/arm64/op_iget_char.S
index 68e1435..a5efd9e 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_char.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_char.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetU16", "extend":"uxth w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetU16" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_short.S b/runtime/interpreter/mterp/arm64/op_iget_short.S
index 714f4b9..bb81c17 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_short.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_short.S
@@ -1 +1 @@
-%include "arm64/op_iget.S" { "helper":"MterpIGetI16", "extend":"sxth w0, w0" }
+%include "arm64/op_iget.S" { "helper":"MterpIGetI16" }
diff --git a/runtime/interpreter/mterp/arm64/op_iget_wide.S b/runtime/interpreter/mterp/arm64/op_iget_wide.S
index 4fc735c..70061d6 100644
--- a/runtime/interpreter/mterp/arm64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_iget_wide.S
@@ -1,21 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
- bl MterpIGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cmp w3, #0
- cbnz w3, MterpException // bail out
- SET_VREG_WIDE x0, w2
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/arm64/op_iput.S b/runtime/interpreter/mterp/arm64/op_iput.S
index 5e21d5c..2bc3db9 100644
--- a/runtime/interpreter/mterp/arm64/op_iput.S
+++ b/runtime/interpreter/mterp/arm64/op_iput.S
@@ -1,21 +1,2 @@
%default { "is_object":"0", "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern $helper
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
- bl $helper
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_iput_object.S b/runtime/interpreter/mterp/arm64/op_iput_object.S
index 0c0441a..e9bb93f 100644
--- a/runtime/interpreter/mterp/arm64/op_iput_object.S
+++ b/runtime/interpreter/mterp/arm64/op_iput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov w2, wINST
- mov x3, xSELF
- bl MterpIPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/arm64/op_iput_wide.S b/runtime/interpreter/mterp/arm64/op_iput_wide.S
index be6aeb0..e1fafad 100644
--- a/runtime/interpreter/mterp/arm64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_iput_wide.S
@@ -1,15 +1 @@
- /* iput-wide vA, vB, field//CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- VREG_INDEX_TO_ADDR x2, x2 // w2<- &fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU64
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/arm64/op_sget.S b/runtime/interpreter/mterp/arm64/op_sget.S
index 00b07fa..78e95b2 100644
--- a/runtime/interpreter/mterp/arm64/op_sget.S
+++ b/runtime/interpreter/mterp/arm64/op_sget.S
@@ -1,27 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "extend":"" }
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
-
- .extern $helper
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl $helper
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- $extend
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if $is_object
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
- ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_sget_boolean.S b/runtime/interpreter/mterp/arm64/op_sget_boolean.S
index 73f3a10..0cf9f09 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_boolean.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_boolean.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetU8", "extend":"uxtb w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetU8"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_byte.S b/runtime/interpreter/mterp/arm64/op_sget_byte.S
index 38c0da6..7c88a81 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_byte.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_byte.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetI8", "extend":"sxtb w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetI8"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_char.S b/runtime/interpreter/mterp/arm64/op_sget_char.S
index c0801bf..883e944 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_char.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_char.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetU16", "extend":"uxth w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetU16"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_short.S b/runtime/interpreter/mterp/arm64/op_sget_short.S
index 81e0434..6cb9184 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_short.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_short.S
@@ -1 +1 @@
-%include "arm64/op_sget.S" {"helper":"MterpSGetI16", "extend":"sxth w0, w0"}
+%include "arm64/op_sget.S" {"helper":"MterpSGetI16"}
diff --git a/runtime/interpreter/mterp/arm64/op_sget_wide.S b/runtime/interpreter/mterp/arm64/op_sget_wide.S
index 546ab94..f5d182e 100644
--- a/runtime/interpreter/mterp/arm64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_sget_wide.S
@@ -1,19 +1 @@
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field//BBBB */
-
- .extern MterpSGetU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w4, wINST, #8 // w4<- AA
- cbnz x3, MterpException // bail out
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- SET_VREG_WIDE x0, w4
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/arm64/op_sput.S b/runtime/interpreter/mterp/arm64/op_sput.S
index 7a0dc30..d229d0d 100644
--- a/runtime/interpreter/mterp/arm64/op_sput.S
+++ b/runtime/interpreter/mterp/arm64/op_sput.S
@@ -1,19 +1,2 @@
-%default { "helper":"MterpSPutU32"}
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl $helper
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "arm64/field.S" { }
diff --git a/runtime/interpreter/mterp/arm64/op_sput_object.S b/runtime/interpreter/mterp/arm64/op_sput_object.S
index a649656..536f1b1 100644
--- a/runtime/interpreter/mterp/arm64/op_sput_object.S
+++ b/runtime/interpreter/mterp/arm64/op_sput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov x2, xINST
- mov x3, xSELF
- bl MterpSPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/arm64/op_sput_wide.S b/runtime/interpreter/mterp/arm64/op_sput_wide.S
index 58b3c42..b4be6b2 100644
--- a/runtime/interpreter/mterp/arm64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/arm64/op_sput_wide.S
@@ -1,18 +1 @@
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field//BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- lsr w1, wINST, #8 // w1<- AA
- VREG_INDEX_TO_ADDR x1, w1
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU64
- cbnz w0, MterpException // 0 on success, -1 on failure
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+%include "arm64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mips/field.S b/runtime/interpreter/mterp/mips/field.S
new file mode 100644
index 0000000..1333ed7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips/field.S
@@ -0,0 +1 @@
+TODO
diff --git a/runtime/interpreter/mterp/mips/op_iget.S b/runtime/interpreter/mterp/mips/op_iget.S
index 33717de..e218272 100644
--- a/runtime/interpreter/mterp/mips/op_iget.S
+++ b/runtime/interpreter/mterp/mips/op_iget.S
@@ -1,25 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL($helper)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if $is_object
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_iget_wide.S b/runtime/interpreter/mterp/mips/op_iget_wide.S
index 858a889..885372a 100644
--- a/runtime/interpreter/mterp/mips/op_iget_wide.S
+++ b/runtime/interpreter/mterp/mips/op_iget_wide.S
@@ -1,20 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field byte offset
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a2, t0) # fp[A] <- v0/v1
+%include "mips/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/mips/op_iput.S b/runtime/interpreter/mterp/mips/op_iput.S
index 4dd4075..efbdfba 100644
--- a/runtime/interpreter/mterp/mips/op_iput.S
+++ b/runtime/interpreter/mterp/mips/op_iput.S
@@ -1,21 +1,2 @@
-%default { "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL($helper)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_iput_object.S b/runtime/interpreter/mterp/mips/op_iput_object.S
index c96a4d4..6f7e7b7 100644
--- a/runtime/interpreter/mterp/mips/op_iput_object.S
+++ b/runtime/interpreter/mterp/mips/op_iput_object.S
@@ -1,16 +1 @@
- /*
- * 32-bit instance field put.
- *
- * for: iput-object, iput-object-volatile
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpIPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/mips/op_iput_wide.S b/runtime/interpreter/mterp/mips/op_iput_wide.S
index dccb6b7..fc862e4 100644
--- a/runtime/interpreter/mterp/mips/op_iput_wide.S
+++ b/runtime/interpreter/mterp/mips/op_iput_wide.S
@@ -1,15 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- EAS2(a2, rFP, a2) # a2 <- &fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU64)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/mips/op_sget.S b/runtime/interpreter/mterp/mips/op_sget.S
index 8750a17..92d6673 100644
--- a/runtime/interpreter/mterp/mips/op_sget.S
+++ b/runtime/interpreter/mterp/mips/op_sget.S
@@ -1,24 +1,2 @@
%default { "is_object":"0", "helper":"MterpSGetU32" }
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL($helper)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if $is_object
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_sget_wide.S b/runtime/interpreter/mterp/mips/op_sget_wide.S
index 76f78cb..be4ae02 100644
--- a/runtime/interpreter/mterp/mips/op_sget_wide.S
+++ b/runtime/interpreter/mterp/mips/op_sget_wide.S
@@ -1,16 +1 @@
- /*
- * 64-bit SGET handler.
- */
- /* sget-wide vAA, field@BBBB */
- .extern MterpSGetU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- bnez a3, MterpException
- GET_OPA(a1) # a1 <- AA
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a1, t0) # vAA/vAA+1 <- v0/v1
+%include "mips/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/mips/op_sput.S b/runtime/interpreter/mterp/mips/op_sput.S
index 547de39..c858679 100644
--- a/runtime/interpreter/mterp/mips/op_sput.S
+++ b/runtime/interpreter/mterp/mips/op_sput.S
@@ -1,19 +1,2 @@
-%default { "helper":"MterpSPutU32"}
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL($helper)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "mips/field.S" { }
diff --git a/runtime/interpreter/mterp/mips/op_sput_object.S b/runtime/interpreter/mterp/mips/op_sput_object.S
index 55c88a6..683b767 100644
--- a/runtime/interpreter/mterp/mips/op_sput_object.S
+++ b/runtime/interpreter/mterp/mips/op_sput_object.S
@@ -1,16 +1 @@
- /*
- * General 32-bit SPUT handler.
- *
- * for: sput-object,
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpSPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/mips/op_sput_wide.S b/runtime/interpreter/mterp/mips/op_sput_wide.S
index cfaaaee..1d2ed19 100644
--- a/runtime/interpreter/mterp/mips/op_sput_wide.S
+++ b/runtime/interpreter/mterp/mips/op_sput_wide.S
@@ -1,17 +1 @@
- /*
- * 64-bit SPUT handler.
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPA(a1) # a1 <- AA
- EAS2(a1, rFP, a1) # a1 <- &fp[AA]
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU64)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+%include "mips/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mips64/field.S b/runtime/interpreter/mterp/mips64/field.S
new file mode 100644
index 0000000..1333ed7
--- /dev/null
+++ b/runtime/interpreter/mterp/mips64/field.S
@@ -0,0 +1 @@
+TODO
diff --git a/runtime/interpreter/mterp/mips64/op_iget.S b/runtime/interpreter/mterp/mips64/op_iget.S
index a8ce94c..e91f099 100644
--- a/runtime/interpreter/mterp/mips64/op_iget.S
+++ b/runtime/interpreter/mterp/mips64/op_iget.S
@@ -1,26 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal $helper
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if $is_object
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_iget_wide.S b/runtime/interpreter/mterp/mips64/op_iget_wide.S
index 08bf544..40f3645 100644
--- a/runtime/interpreter/mterp/mips64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_iget_wide.S
@@ -1,21 +1 @@
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- .extern MterpIGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- SET_VREG_WIDE v0, a2 # fp[A] <- v0
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/mips64/op_iput.S b/runtime/interpreter/mterp/mips64/op_iput.S
index 9a789e6..81ab911 100644
--- a/runtime/interpreter/mterp/mips64/op_iput.S
+++ b/runtime/interpreter/mterp/mips64/op_iput.S
@@ -1,21 +1,2 @@
-%default { "helper":"MterpIPutU32" }
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal $helper
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_iput_object.S b/runtime/interpreter/mterp/mips64/op_iput_object.S
index dd1938e..d3316dd 100644
--- a/runtime/interpreter/mterp/mips64/op_iput_object.S
+++ b/runtime/interpreter/mterp/mips64/op_iput_object.S
@@ -1,11 +1 @@
- .extern MterpIPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpIPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/mips64/op_iput_wide.S b/runtime/interpreter/mterp/mips64/op_iput_wide.S
index 6272690..05194b3 100644
--- a/runtime/interpreter/mterp/mips64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_iput_wide.S
@@ -1,15 +1 @@
- /* iput-wide vA, vB, field//CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- dlsa a2, a2, rFP, 2 # a2 <- &fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU64
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/mips64/op_sget.S b/runtime/interpreter/mterp/mips64/op_sget.S
index b7b0382..200da35 100644
--- a/runtime/interpreter/mterp/mips64/op_sget.S
+++ b/runtime/interpreter/mterp/mips64/op_sget.S
@@ -1,26 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "extend":"" }
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal $helper
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- $extend
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if $is_object
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_sget_boolean.S b/runtime/interpreter/mterp/mips64/op_sget_boolean.S
index fe2deb1..8abb396 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_boolean.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_boolean.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetU8", "extend":"and v0, v0, 0xff"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetU8"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_byte.S b/runtime/interpreter/mterp/mips64/op_sget_byte.S
index a7e2bef..68623f6 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_byte.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_byte.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetI8", "extend":"seb v0, v0"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetI8"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_char.S b/runtime/interpreter/mterp/mips64/op_sget_char.S
index ed86f32..3c7b962 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_char.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_char.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetU16", "extend":"and v0, v0, 0xffff"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetU16"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_short.S b/runtime/interpreter/mterp/mips64/op_sget_short.S
index f708a20..9a8579b 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_short.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_short.S
@@ -1 +1 @@
-%include "mips64/op_sget.S" {"helper":"MterpSGetI16", "extend":"seh v0, v0"}
+%include "mips64/op_sget.S" {"helper":"MterpSGetI16"}
diff --git a/runtime/interpreter/mterp/mips64/op_sget_wide.S b/runtime/interpreter/mterp/mips64/op_sget_wide.S
index 7c31252..14f232c 100644
--- a/runtime/interpreter/mterp/mips64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_sget_wide.S
@@ -1,18 +1 @@
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field//BBBB */
- .extern MterpSGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a4, rINST, 8 # a4 <- AA
- bnez a3, MterpException # bail out
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- SET_VREG_WIDE v0, a4
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/mips64/op_sput.S b/runtime/interpreter/mterp/mips64/op_sput.S
index 28b8c3e..0bd6837 100644
--- a/runtime/interpreter/mterp/mips64/op_sput.S
+++ b/runtime/interpreter/mterp/mips64/op_sput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpSPutU32" }
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern $helper
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal $helper
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "mips64/field.S" { }
diff --git a/runtime/interpreter/mterp/mips64/op_sput_object.S b/runtime/interpreter/mterp/mips64/op_sput_object.S
index ff43967..09bd0fb 100644
--- a/runtime/interpreter/mterp/mips64/op_sput_object.S
+++ b/runtime/interpreter/mterp/mips64/op_sput_object.S
@@ -1,11 +1 @@
- .extern MterpSPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpSPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/mips64/op_sput_wide.S b/runtime/interpreter/mterp/mips64/op_sput_wide.S
index bfb6983..070d17f 100644
--- a/runtime/interpreter/mterp/mips64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/mips64/op_sput_wide.S
@@ -1,18 +1 @@
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field//BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a1, rINST, 8 # a2 <- AA
- dlsa a1, a1, rFP, 2
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU64
- bnezc v0, MterpException # 0 on success, -1 on failure
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+%include "mips64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index 7b37c9a..65c1aa8 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -490,24 +490,6 @@
return true;
}
-extern "C" size_t MterpSPutObj(ShadowFrame* shadow_frame, uint16_t* dex_pc_ptr,
- uint32_t inst_data, Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- const Instruction* inst = Instruction::At(dex_pc_ptr);
- return DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, false, false>
- (self, *shadow_frame, inst, inst_data);
-}
-
-extern "C" size_t MterpIPutObj(ShadowFrame* shadow_frame,
- uint16_t* dex_pc_ptr,
- uint32_t inst_data,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- const Instruction* inst = Instruction::At(dex_pc_ptr);
- return DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, false, false>
- (self, *shadow_frame, inst, inst_data);
-}
-
extern "C" size_t MterpIputObjectQuick(ShadowFrame* shadow_frame,
uint16_t* dex_pc_ptr,
uint32_t inst_data)
@@ -681,352 +663,159 @@
return MterpShouldSwitchInterpreters();
}
-template<typename PrimType, typename RetType, typename Getter, FindFieldType kType>
-NO_INLINE RetType artGetInstanceFromMterp(uint32_t field_idx,
- mirror::Object* obj,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- StackHandleScope<1> hs(self);
- HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&obj)); // GC might move the object.
- ArtField* field = FindFieldFromCode<kType, /* access_checks */ false>(
- field_idx, referrer, self, sizeof(PrimType));
- if (UNLIKELY(field == nullptr)) {
- return 0; // Will throw exception by checking with Thread::Current.
+// Execute single field access instruction (get/put, static/instance).
+// The template arguments reduce this to fairly small amount of code.
+// It requires the target object and field to be already resolved.
+template<typename PrimType, FindFieldType kAccessType>
+ALWAYS_INLINE void MterpFieldAccess(Instruction* inst,
+ uint16_t inst_data,
+ ShadowFrame* shadow_frame,
+ ObjPtr<mirror::Object> obj,
+ MemberOffset offset,
+ bool is_volatile)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ static_assert(std::is_integral<PrimType>::value, "Unexpected primitive type");
+ constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
+ constexpr bool kIsPrimitive = (kAccessType & FindFieldFlags::PrimitiveBit) != 0;
+ constexpr bool kIsRead = (kAccessType & FindFieldFlags::ReadBit) != 0;
+
+ uint16_t vRegA = kIsStatic ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
+ if (kIsPrimitive) {
+ if (kIsRead) {
+ PrimType value = UNLIKELY(is_volatile)
+ ? obj->GetFieldPrimitive<PrimType, /*kIsVolatile*/ true>(offset)
+ : obj->GetFieldPrimitive<PrimType, /*kIsVolatile*/ false>(offset);
+ if (sizeof(PrimType) == sizeof(uint64_t)) {
+ shadow_frame->SetVRegLong(vRegA, value); // Set two consecutive registers.
+ } else {
+ shadow_frame->SetVReg(vRegA, static_cast<int32_t>(value)); // Sign/zero extend.
+ }
+ } else { // Write.
+ uint64_t value = (sizeof(PrimType) == sizeof(uint64_t))
+ ? shadow_frame->GetVRegLong(vRegA)
+ : shadow_frame->GetVReg(vRegA);
+ if (UNLIKELY(is_volatile)) {
+ obj->SetFieldPrimitive<PrimType, /*kIsVolatile*/ true>(offset, value);
+ } else {
+ obj->SetFieldPrimitive<PrimType, /*kIsVolatile*/ false>(offset, value);
+ }
+ }
+ } else { // Object.
+ if (kIsRead) {
+ ObjPtr<mirror::Object> value = UNLIKELY(is_volatile)
+ ? obj->GetFieldObjectVolatile<mirror::Object>(offset)
+ : obj->GetFieldObject<mirror::Object>(offset);
+ shadow_frame->SetVRegReference(vRegA, value);
+ } else { // Write.
+ ObjPtr<mirror::Object> value = shadow_frame->GetVRegReference(vRegA);
+ if (UNLIKELY(is_volatile)) {
+ obj->SetFieldObjectVolatile</*kTransactionActive*/ false>(offset, value);
+ } else {
+ obj->SetFieldObject</*kTransactionActive*/ false>(offset, value);
+ }
+ }
}
- if (UNLIKELY(h == nullptr)) {
- ThrowNullPointerExceptionForFieldAccess(field, /*is_read*/ true);
- return 0; // Will throw exception by checking with Thread::Current.
- }
- return Getter::Get(obj, field);
}
-template<typename PrimType, typename RetType, typename Getter>
-ALWAYS_INLINE RetType artGetInstanceFromMterpFast(uint32_t field_idx,
- mirror::Object* obj,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- constexpr bool kIsObject = std::is_same<RetType, mirror::Object*>::value;
- constexpr FindFieldType kType = kIsObject ? InstanceObjectRead : InstancePrimitiveRead;
+template<typename PrimType, FindFieldType kAccessType>
+NO_INLINE bool MterpFieldAccessSlow(Instruction* inst,
+ uint16_t inst_data,
+ ShadowFrame* shadow_frame,
+ Thread* self)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
+ constexpr bool kIsRead = (kAccessType & FindFieldFlags::ReadBit) != 0;
+
+ // Update the dex pc in shadow frame, just in case anything throws.
+ shadow_frame->SetDexPCPtr(reinterpret_cast<uint16_t*>(inst));
+ ArtMethod* referrer = shadow_frame->GetMethod();
+ uint32_t field_idx = kIsStatic ? inst->VRegB_21c() : inst->VRegC_22c();
+ ArtField* field = FindFieldFromCode<kAccessType, /* access_checks */ false>(
+ field_idx, referrer, self, sizeof(PrimType));
+ if (UNLIKELY(field == nullptr)) {
+ DCHECK(self->IsExceptionPending());
+ return false;
+ }
+ ObjPtr<mirror::Object> obj = kIsStatic
+ ? field->GetDeclaringClass().Ptr()
+ : shadow_frame->GetVRegReference(inst->VRegB_22c(inst_data));
+ if (UNLIKELY(obj == nullptr)) {
+ ThrowNullPointerExceptionForFieldAccess(field, kIsRead);
+ return false;
+ }
+ MterpFieldAccess<PrimType, kAccessType>(
+ inst, inst_data, shadow_frame, obj, field->GetOffset(), field->IsVolatile());
+ return true;
+}
+
+template<typename PrimType, FindFieldType kAccessType>
+ALWAYS_INLINE bool MterpFieldAccessFast(Instruction* inst,
+ uint16_t inst_data,
+ ShadowFrame* shadow_frame,
+ Thread* self)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ constexpr bool kIsStatic = (kAccessType & FindFieldFlags::StaticBit) != 0;
// This effectively inlines the fast path from ArtMethod::GetDexCache.
// It avoids non-inlined call which in turn allows elimination of the prologue and epilogue.
+ ArtMethod* referrer = shadow_frame->GetMethod();
if (LIKELY(!referrer->IsObsolete())) {
// Avoid read barriers, since we need only the pointer to the native (non-movable)
// DexCache field array which we can get even through from-space objects.
ObjPtr<mirror::Class> klass = referrer->GetDeclaringClass<kWithoutReadBarrier>();
mirror::DexCache* dex_cache = klass->GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>();
+
// Try to find the desired field in DexCache.
+ uint32_t field_idx = kIsStatic ? inst->VRegB_21c() : inst->VRegC_22c();
ArtField* field = dex_cache->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr & obj != nullptr)) {
- if (kIsDebugBuild) {
- // Compare the fast path and slow path.
- StackHandleScope<1> hs(self);
- HandleWrapper<mirror::Object> h(hs.NewHandleWrapper(&obj)); // GC might move the object.
- DCHECK_EQ(field, (FindFieldFromCode<kType, /* access_checks */ false>(
+ if (LIKELY(field != nullptr)) {
+ bool initialized = !kIsStatic || field->GetDeclaringClass()->IsInitialized();
+ if (LIKELY(initialized)) {
+ DCHECK_EQ(field, (FindFieldFromCode<kAccessType, /* access_checks */ false>(
field_idx, referrer, self, sizeof(PrimType))));
+ ObjPtr<mirror::Object> obj = kIsStatic
+ ? field->GetDeclaringClass().Ptr()
+ : shadow_frame->GetVRegReference(inst->VRegB_22c(inst_data));
+ if (LIKELY(kIsStatic || obj != nullptr)) {
+ MterpFieldAccess<PrimType, kAccessType>(
+ inst, inst_data, shadow_frame, obj, field->GetOffset(), field->IsVolatile());
+ return true;
+ }
}
- return Getter::Get(obj, field);
}
}
+
// Slow path. Last and with identical arguments so that it becomes single instruction tail call.
- return artGetInstanceFromMterp<PrimType, RetType, Getter, kType>(field_idx, obj, referrer, self);
+ return MterpFieldAccessSlow<PrimType, kAccessType>(inst, inst_data, shadow_frame, self);
}
-#define ART_GET_FIELD_FROM_MTERP(Suffix, Kind, PrimType, RetType, Ptr) \
-extern "C" RetType MterpIGet ## Suffix(uint32_t field_idx, \
- mirror::Object* obj, \
- ArtMethod* referrer, \
- Thread* self) \
- REQUIRES_SHARED(Locks::mutator_lock_) { \
- struct Getter { /* Specialize the field load depending on the field type */ \
- static RetType Get(mirror::Object* o, ArtField* f) REQUIRES_SHARED(Locks::mutator_lock_) { \
- return f->Get##Kind(o)Ptr; \
- } \
- }; \
- return artGetInstanceFromMterpFast<PrimType, RetType, Getter>(field_idx, obj, referrer, self); \
-} \
-
-ART_GET_FIELD_FROM_MTERP(I8, Byte, int8_t, ssize_t, )
-ART_GET_FIELD_FROM_MTERP(U8, Boolean, uint8_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(I16, Short, int16_t, ssize_t, )
-ART_GET_FIELD_FROM_MTERP(U16, Char, uint16_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(U32, 32, uint32_t, size_t, )
-ART_GET_FIELD_FROM_MTERP(U64, 64, uint64_t, uint64_t, )
-ART_GET_FIELD_FROM_MTERP(Obj, Obj, mirror::HeapReference<mirror::Object>, mirror::Object*, .Ptr())
-
-#undef ART_GET_FIELD_FROM_MTERP
-
-extern "C" ssize_t MterpIPutU8(uint32_t field_idx,
- mirror::Object* obj,
- uint8_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetBoolean<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
+#define MTERP_FIELD_ACCESSOR(Name, PrimType, AccessType) \
+extern "C" bool Name(Instruction* inst, uint16_t inst_data, ShadowFrame* sf, Thread* self) \
+ REQUIRES_SHARED(Locks::mutator_lock_) { \
+ return MterpFieldAccessFast<PrimType, AccessType>(inst, inst_data, sf, self); \
}
-extern "C" ssize_t MterpIPutI8(uint32_t field_idx,
- mirror::Object* obj,
- uint8_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetByte<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
+#define MTERP_FIELD_ACCESSORS_FOR_TYPE(Sufix, PrimType, Kind) \
+ MTERP_FIELD_ACCESSOR(MterpIGet##Sufix, PrimType, Instance##Kind##Read) \
+ MTERP_FIELD_ACCESSOR(MterpIPut##Sufix, PrimType, Instance##Kind##Write) \
+ MTERP_FIELD_ACCESSOR(MterpSGet##Sufix, PrimType, Static##Kind##Read) \
+ MTERP_FIELD_ACCESSOR(MterpSPut##Sufix, PrimType, Static##Kind##Write)
-extern "C" ssize_t MterpIPutU16(uint32_t field_idx,
- mirror::Object* obj,
- uint16_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetChar<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
+MTERP_FIELD_ACCESSORS_FOR_TYPE(I8, int8_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U8, uint8_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(I16, int16_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U16, uint16_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U32, uint32_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(U64, uint64_t, Primitive)
+MTERP_FIELD_ACCESSORS_FOR_TYPE(Obj, uint32_t, Object)
-extern "C" ssize_t MterpIPutI16(uint32_t field_idx,
- mirror::Object* obj,
- uint16_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetShort<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
+// Check that the primitive type for Obj variant above is correct.
+// It really must be primitive type for the templates to compile.
+// In the case of objects, it is only used to get the field size.
+static_assert(kHeapReferenceSize == sizeof(uint32_t), "Unexpected kHeapReferenceSize");
-extern "C" ssize_t MterpIPutU32(uint32_t field_idx,
- mirror::Object* obj,
- uint32_t new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->Set32<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
-
-extern "C" ssize_t MterpIPutU64(uint32_t field_idx,
- mirror::Object* obj,
- uint64_t* new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->Set64<false>(obj, *new_value);
- return 0; // success
- }
- return -1; // failure
-}
-
-extern "C" ssize_t artSetObjInstanceFromMterp(uint32_t field_idx,
- mirror::Object* obj,
- mirror::Object* new_value,
- ArtMethod* referrer)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtField* field = referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
- if (LIKELY(field != nullptr && obj != nullptr)) {
- field->SetObj<false>(obj, new_value);
- return 0; // success
- }
- return -1; // failure
-}
-
-template <typename return_type, Primitive::Type primitive_type>
-ALWAYS_INLINE return_type MterpGetStatic(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self,
- return_type (ArtField::*func)(ObjPtr<mirror::Object>))
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return_type res = 0; // On exception, the result will be ignored.
- ArtField* f =
- FindFieldFromCode<StaticPrimitiveRead, false>(field_idx,
- referrer,
- self,
- primitive_type);
- if (LIKELY(f != nullptr)) {
- ObjPtr<mirror::Object> obj = f->GetDeclaringClass();
- res = (f->*func)(obj);
- }
- return res;
-}
-
-extern "C" int32_t MterpSGetU8(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<uint8_t, Primitive::kPrimBoolean>(field_idx,
- referrer,
- self,
- &ArtField::GetBoolean);
-}
-
-extern "C" int32_t MterpSGetI8(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int8_t, Primitive::kPrimByte>(field_idx,
- referrer,
- self,
- &ArtField::GetByte);
-}
-
-extern "C" uint32_t MterpSGetU16(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<uint16_t, Primitive::kPrimChar>(field_idx,
- referrer,
- self,
- &ArtField::GetChar);
-}
-
-extern "C" int32_t MterpSGetI16(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int16_t, Primitive::kPrimShort>(field_idx,
- referrer,
- self,
- &ArtField::GetShort);
-}
-
-extern "C" mirror::Object* MterpSGetObj(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<ObjPtr<mirror::Object>, Primitive::kPrimNot>(field_idx,
- referrer,
- self,
- &ArtField::GetObject).Ptr();
-}
-
-extern "C" int32_t MterpSGetU32(uint32_t field_idx,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int32_t, Primitive::kPrimInt>(field_idx,
- referrer,
- self,
- &ArtField::GetInt);
-}
-
-extern "C" int64_t MterpSGetU64(uint32_t field_idx, ArtMethod* referrer, Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpGetStatic<int64_t, Primitive::kPrimLong>(field_idx,
- referrer,
- self,
- &ArtField::GetLong);
-}
-
-
-template <typename field_type, Primitive::Type primitive_type>
-int MterpSetStatic(uint32_t field_idx,
- field_type new_value,
- ArtMethod* referrer,
- Thread* self,
- void (ArtField::*func)(ObjPtr<mirror::Object>, field_type val))
- REQUIRES_SHARED(Locks::mutator_lock_) {
- int res = 0; // Assume success (following quick_field_entrypoints conventions)
- ArtField* f =
- FindFieldFromCode<StaticPrimitiveWrite, false>(field_idx, referrer, self, primitive_type);
- if (LIKELY(f != nullptr)) {
- ObjPtr<mirror::Object> obj = f->GetDeclaringClass();
- (f->*func)(obj, new_value);
- } else {
- res = -1; // Failure
- }
- return res;
-}
-
-extern "C" int MterpSPutU8(uint32_t field_idx,
- uint8_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<uint8_t, Primitive::kPrimBoolean>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetBoolean<false>);
-}
-
-extern "C" int MterpSPutI8(uint32_t field_idx,
- int8_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int8_t, Primitive::kPrimByte>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetByte<false>);
-}
-
-extern "C" int MterpSPutU16(uint32_t field_idx,
- uint16_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<uint16_t, Primitive::kPrimChar>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetChar<false>);
-}
-
-extern "C" int MterpSPutI16(uint32_t field_idx,
- int16_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int16_t, Primitive::kPrimShort>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetShort<false>);
-}
-
-extern "C" int MterpSPutU32(uint32_t field_idx,
- int32_t new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int32_t, Primitive::kPrimInt>(field_idx,
- new_value,
- referrer,
- self,
- &ArtField::SetInt<false>);
-}
-
-extern "C" int MterpSPutU64(uint32_t field_idx,
- int64_t* new_value,
- ArtMethod* referrer,
- Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- return MterpSetStatic<int64_t, Primitive::kPrimLong>(field_idx,
- *new_value,
- referrer,
- self,
- &ArtField::SetLong<false>);
-}
+#undef MTERP_FIELD_ACCESSORS_FOR_TYPE
+#undef MTERP_FIELD_ACCESSOR
extern "C" mirror::Object* artAGetObjectFromMterp(mirror::Object* arr,
int32_t index)
diff --git a/runtime/interpreter/mterp/out/mterp_arm.S b/runtime/interpreter/mterp/out/mterp_arm.S
index 394a849..25512ae 100644
--- a/runtime/interpreter/mterp/out/mterp_arm.S
+++ b/runtime/interpreter/mterp/out/mterp_arm.S
@@ -2246,215 +2246,185 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU32
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU32
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: arm/op_iget_wide.S */
+/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * 64-bit instance field get.
- *
- * for: iget-wide
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU64
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpException @ bail out
- CLEAR_SHADOW_PAIR r2, ip, lr @ Zero out the shadow regs
- VREG_INDEX_TO_ADDR r3, r2 @ r3<- &fp[A]
- stmia r3, {r0-r1} @ fp[A]<- r0/r1
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: arm/op_iget_object.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetObj
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetObj
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 1
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: arm/op_iget_boolean.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: arm/op_iget_byte.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetI8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetI8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: arm/op_iget_char.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetU16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetU16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: arm/op_iget_short.S */
/* File: arm/op_iget.S */
+/* File: arm/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ldr r2, [rFP, #OFF_FP_METHOD] @ r2<- referrer
- mov r3, rSELF @ r3<- self
+ .extern MterpIGetI16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIGetI16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx r2, rINST, #8, #4 @ r2<- A
- PREFETCH_INST 2
- cmp r3, #0
- bne MterpPossibleException @ bail out
- .if 0
- SET_VREG_OBJECT r0, r2 @ fp[A]<- r0
- .else
- SET_VREG r0, r2 @ fp[A]<- r0
- .endif
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
+
+/* ------------------------------ */
+ .balign 128
+.L_op_iput: /* 0x59 */
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutU32
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpIPutU32
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip @ extract opcode from rINST
GOTO_OPCODE ip @ jump to next instruction
@@ -2462,93 +2432,74 @@
/* ------------------------------ */
.balign 128
-.L_op_iput: /* 0x59 */
-/* File: arm/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU32
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU32
- cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
-
-/* ------------------------------ */
- .balign 128
.L_op_iput_wide: /* 0x5a */
/* File: arm/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- VREG_INDEX_TO_ADDR r2, r2 @ r2<- &fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutU64
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: arm/op_iput_object.S */
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpIPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+/* File: arm/op_iput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpIPutObj
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: arm/op_iput_boolean.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutU8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutU8
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2556,27 +2507,23 @@
.L_op_iput_byte: /* 0x5d */
/* File: arm/op_iput_byte.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutI8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutI8
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2584,27 +2531,23 @@
.L_op_iput_char: /* 0x5e */
/* File: arm/op_iput_char.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutU16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutU16
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2612,118 +2555,93 @@
.L_op_iput_short: /* 0x5f */
/* File: arm/op_iput_short.S */
/* File: arm/op_iput.S */
+/* File: arm/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field@CCCC */
.extern MterpIPutI16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref CCCC
- mov r1, rINST, lsr #12 @ r1<- B
- GET_VREG r1, r1 @ r1<- fp[B], the object pointer
- ubfx r2, rINST, #8, #4 @ r2<- A
- GET_VREG r2, r2 @ r2<- fp[A]
- ldr r3, [rFP, #OFF_FP_METHOD] @ r3<- referrer
- PREFETCH_INST 2
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
bl MterpIPutI16
cmp r0, #0
- bne MterpPossibleException
- ADVANCE 2 @ advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetU32
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU32
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU32
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: arm/op_sget_wide.S */
+/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * SGET_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sget-wide vAA, field@BBBB */
-
.extern MterpSGetU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU64
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r9, rINST, lsr #8 @ r9<- AA
- VREG_INDEX_TO_ADDR lr, r9 @ r9<- &fp[AA]
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- CLEAR_SHADOW_PAIR r9, r2, ip @ Zero out the shadow regs
- stmia lr, {r0-r1} @ vAA/vAA+1<- r0/r1
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU64
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: arm/op_sget_object.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetObj
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetObj
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 1
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetObj
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2731,32 +2649,23 @@
.L_op_sget_boolean: /* 0x63 */
/* File: arm/op_sget_boolean.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetU8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU8
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2764,32 +2673,23 @@
.L_op_sget_byte: /* 0x64 */
/* File: arm/op_sget_byte.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetI8
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetI8
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetI8
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2797,32 +2697,23 @@
.L_op_sget_char: /* 0x65 */
/* File: arm/op_sget_char.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetU16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetU16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetU16
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2830,122 +2721,117 @@
.L_op_sget_short: /* 0x66 */
/* File: arm/op_sget_short.S */
/* File: arm/op_sget.S */
+/* File: arm/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
-
.extern MterpSGetI16
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- ldr r1, [rFP, #OFF_FP_METHOD]
- mov r2, rSELF
- bl MterpSGetI16
- ldr r3, [rSELF, #THREAD_EXCEPTION_OFFSET]
- mov r2, rINST, lsr #8 @ r2<- AA
- PREFETCH_INST 2
- cmp r3, #0 @ Fail to resolve?
- bne MterpException @ bail out
-.if 0
- SET_VREG_OBJECT r0, r2 @ fp[AA]<- r0
-.else
- SET_VREG r0, r2 @ fp[AA]<- r0
-.endif
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSGetI16
+ cmp r0, #0
+ beq MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU32
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutU32
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU32
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: arm/op_sput_wide.S */
+/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * SPUT_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sput-wide vAA, field@BBBB */
.extern MterpSPutU64
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r1, rINST, lsr #8 @ r1<- AA
- VREG_INDEX_TO_ADDR r1, r1
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU64
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU64
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: arm/op_sput_object.S */
- EXPORT_PC
- add r0, rFP, #OFF_FP_SHADOWFRAME
- mov r1, rPC
- mov r2, rINST
- mov r3, rSELF
- bl MterpSPutObj
- cmp r0, #0
- beq MterpException
- FETCH_ADVANCE_INST 2 @ advance rPC, load rINST
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+/* File: arm/op_sput.S */
+/* File: arm/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutObj
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: arm/op_sput_boolean.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU8
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutU8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU8
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2953,25 +2839,23 @@
.L_op_sput_byte: /* 0x6b */
/* File: arm/op_sput_byte.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutI8
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutI8
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutI8
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -2979,25 +2863,23 @@
.L_op_sput_char: /* 0x6c */
/* File: arm/op_sput_char.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutU16
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutU16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutU16
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
@@ -3005,25 +2887,23 @@
.L_op_sput_short: /* 0x6d */
/* File: arm/op_sput_short.S */
/* File: arm/op_sput.S */
+/* File: arm/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field@BBBB */
- EXPORT_PC
- FETCH r0, 1 @ r0<- field ref BBBB
- mov r3, rINST, lsr #8 @ r3<- AA
- GET_VREG r1, r3 @ r1<= fp[AA]
- ldr r2, [rFP, #OFF_FP_METHOD]
- mov r3, rSELF
- PREFETCH_INST 2 @ Get next inst, but don't advance rPC
- bl MterpSPutI16
- cmp r0, #0 @ 0 on success, -1 on failure
- bne MterpException
- ADVANCE 2 @ Past exception point - now advance rPC
- GET_INST_OPCODE ip @ extract opcode from rINST
- GOTO_OPCODE ip @ jump to next instruction
+ .extern MterpSPutI16
+ mov r0, rPC @ arg0: Instruction* inst
+ mov r1, rINST @ arg1: uint16_t inst_data
+ add r2, rFP, #OFF_FP_SHADOWFRAME @ arg2: ShadowFrame* sf
+ mov r3, rSELF @ arg3: Thread* self
+ PREFETCH_INST 2 @ prefetch next opcode
+ bl MterpSPutI16
+ cmp r0, #0
+ beq MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip @ extract opcode from rINST
+ GOTO_OPCODE ip @ jump to next instruction
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_arm64.S b/runtime/interpreter/mterp/out/mterp_arm64.S
index 5f4aa4f..fd60c95 100644
--- a/runtime/interpreter/mterp/out/mterp_arm64.S
+++ b/runtime/interpreter/mterp/out/mterp_arm64.S
@@ -2183,213 +2183,177 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU32
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU32
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: arm64/op_iget_wide.S */
+/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * 64-bit instance field get.
- *
- * for: iget-wide
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU64
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cmp w3, #0
- cbnz w3, MterpException // bail out
- SET_VREG_WIDE x0, w2
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from wINST
+ GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: arm64/op_iget_object.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetObj
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetObj
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
-
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 1
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: arm64/op_iget_boolean.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- uxtb w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: arm64/op_iget_byte.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetI8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetI8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- sxtb w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: arm64/op_iget_char.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetU16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetU16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- uxth w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: arm64/op_iget_short.S */
/* File: arm64/op_iget.S */
+/* File: arm64/field.S */
/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ldr x2, [xFP, #OFF_FP_METHOD] // w2<- referrer
- mov x3, xSELF // w3<- self
+ .extern MterpIGetI16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIGetI16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- sxth w0, w0
- ubfx w2, wINST, #8, #4 // w2<- A
- PREFETCH_INST 2
- cbnz x3, MterpPossibleException // bail out
- .if 0
- SET_VREG_OBJECT w0, w2 // fp[A]<- w0
- .else
- SET_VREG w0, w2 // fp[A]<- w0
- .endif
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
+
+/* ------------------------------ */
+ .balign 128
+.L_op_iput: /* 0x59 */
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutU32
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpIPutU32
+ cbz x0, MterpPossibleException
ADVANCE 2
GET_INST_OPCODE ip // extract opcode from rINST
GOTO_OPCODE ip // jump to next instruction
@@ -2397,89 +2361,71 @@
/* ------------------------------ */
.balign 128
-.L_op_iput: /* 0x59 */
-/* File: arm64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU32
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
- bl MterpIPutU32
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
-
-/* ------------------------------ */
- .balign 128
.L_op_iput_wide: /* 0x5a */
/* File: arm64/op_iput_wide.S */
- /* iput-wide vA, vB, field//CCCC */
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- VREG_INDEX_TO_ADDR x2, x2 // w2<- &fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutU64
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: arm64/op_iput_object.S */
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov w2, wINST
- mov x3, xSELF
- bl MterpIPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpIPutObj
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: arm64/op_iput_boolean.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutU8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutU8
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2487,26 +2433,22 @@
.L_op_iput_byte: /* 0x5d */
/* File: arm64/op_iput_byte.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutI8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutI8
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2514,26 +2456,22 @@
.L_op_iput_char: /* 0x5e */
/* File: arm64/op_iput_char.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutU16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutU16
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2541,114 +2479,89 @@
.L_op_iput_short: /* 0x5f */
/* File: arm64/op_iput_short.S */
/* File: arm64/op_iput.S */
+/* File: arm64/field.S */
/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vA, vB, field//CCCC */
.extern MterpIPutI16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref CCCC
- lsr w1, wINST, #12 // w1<- B
- GET_VREG w1, w1 // w1<- fp[B], the object pointer
- ubfx w2, wINST, #8, #4 // w2<- A
- GET_VREG w2, w2 // w2<- fp[A]
- ldr x3, [xFP, #OFF_FP_METHOD] // w3<- referrer
- PREFETCH_INST 2
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
bl MterpIPutI16
- cbnz w0, MterpPossibleException
- ADVANCE 2 // advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetU32
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU32
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
-
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU32
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: arm64/op_sget_wide.S */
+/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * SGET_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sget-wide vAA, field//BBBB */
+ .extern MterpSGetU64
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU64
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
- .extern MterpGet64StaticFromCode
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU64
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w4, wINST, #8 // w4<- AA
- cbnz x3, MterpException // bail out
- FETCH_ADVANCE_INST 2 // advance rPC, load wINST
- SET_VREG_WIDE x0, w4
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: arm64/op_sget_object.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetObj
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetObj
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
-
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 1
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetObj
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2656,32 +2569,22 @@
.L_op_sget_boolean: /* 0x63 */
/* File: arm64/op_sget_boolean.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetU8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- uxtb w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU8
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2689,32 +2592,22 @@
.L_op_sget_byte: /* 0x64 */
/* File: arm64/op_sget_byte.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetI8
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetI8
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- sxtb w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetI8
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2722,32 +2615,22 @@
.L_op_sget_char: /* 0x65 */
/* File: arm64/op_sget_char.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetU16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetU16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- uxth w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetU16
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2755,118 +2638,112 @@
.L_op_sget_short: /* 0x66 */
/* File: arm64/op_sget_short.S */
/* File: arm64/op_sget.S */
+/* File: arm64/field.S */
/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
-
.extern MterpSGetI16
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- ldr x1, [xFP, #OFF_FP_METHOD]
- mov x2, xSELF
- bl MterpSGetI16
- ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
- lsr w2, wINST, #8 // w2<- AA
- sxth w0, w0
- PREFETCH_INST 2
- cbnz x3, MterpException // bail out
-.if 0
- SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
-.else
- SET_VREG w0, w2 // fp[AA]<- w0
-.endif
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSGetI16
+ cbz x0, MterpPossibleException
ADVANCE 2
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU32
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutU32
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU32
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: arm64/op_sput_wide.S */
+/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * SPUT_WIDE handler wrapper.
- *
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* sput-wide vAA, field//BBBB */
.extern MterpSPutU64
- EXPORT_PC
- FETCH w0, 1 // w0<- field ref BBBB
- lsr w1, wINST, #8 // w1<- AA
- VREG_INDEX_TO_ADDR x1, w1
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU64
- cbnz w0, MterpException // 0 on success, -1 on failure
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from wINST
- GOTO_OPCODE ip // jump to next instruction
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU64
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: arm64/op_sput_object.S */
- EXPORT_PC
- add x0, xFP, #OFF_FP_SHADOWFRAME
- mov x1, xPC
- mov x2, xINST
- mov x3, xSELF
- bl MterpSPutObj
- cbz w0, MterpException
- FETCH_ADVANCE_INST 2 // advance rPC, load rINST
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutObj
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: arm64/op_sput_boolean.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU8
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutU8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU8
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2874,24 +2751,22 @@
.L_op_sput_byte: /* 0x6b */
/* File: arm64/op_sput_byte.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutI8
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutI8
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutI8
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2899,24 +2774,22 @@
.L_op_sput_char: /* 0x6c */
/* File: arm64/op_sput_char.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutU16
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutU16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutU16
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
@@ -2924,24 +2797,22 @@
.L_op_sput_short: /* 0x6d */
/* File: arm64/op_sput_short.S */
/* File: arm64/op_sput.S */
+/* File: arm64/field.S */
/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
+ * General field read / write (iget-* iput-* sget-* sput-*).
*/
- /* op vAA, field//BBBB */
- EXPORT_PC
- FETCH w0, 1 // r0<- field ref BBBB
- lsr w3, wINST, #8 // r3<- AA
- GET_VREG w1, w3 // r1<= fp[AA]
- ldr x2, [xFP, #OFF_FP_METHOD]
- mov x3, xSELF
- PREFETCH_INST 2 // Get next inst, but don't advance rPC
- bl MterpSPutI16
- cbnz w0, MterpException // 0 on success
- ADVANCE 2 // Past exception point - now advance rPC
- GET_INST_OPCODE ip // extract opcode from rINST
- GOTO_OPCODE ip // jump to next instruction
+ .extern MterpSPutI16
+ mov x0, xPC // arg0: Instruction* inst
+ mov x1, xINST // arg1: uint16_t inst_data
+ add x2, xFP, #OFF_FP_SHADOWFRAME // arg2: ShadowFrame* sf
+ mov x3, xSELF // arg3: Thread* self
+ PREFETCH_INST 2 // prefetch next opcode
+ bl MterpSPutI16
+ cbz x0, MterpPossibleException
+ ADVANCE 2
+ GET_INST_OPCODE ip // extract opcode from rINST
+ GOTO_OPCODE ip // jump to next instruction
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_mips.S b/runtime/interpreter/mterp/out/mterp_mips.S
index fb7d52e..1f5bea0 100644
--- a/runtime/interpreter/mterp/out/mterp_mips.S
+++ b/runtime/interpreter/mterp/out/mterp_mips.S
@@ -2665,85 +2665,28 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU32)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: mips/op_iget_wide.S */
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field byte offset
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a2, t0) # fp[A] <- v0/v1
+/* File: mips/op_iget.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: mips/op_iget_object.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetObj)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 1
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2751,30 +2694,9 @@
.L_op_iget_boolean: /* 0x55 */
/* File: mips/op_iget_boolean.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2782,30 +2704,9 @@
.L_op_iget_byte: /* 0x56 */
/* File: mips/op_iget_byte.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetI8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2813,30 +2714,9 @@
.L_op_iget_char: /* 0x57 */
/* File: mips/op_iget_char.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetU16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2844,123 +2724,47 @@
.L_op_iget_short: /* 0x58 */
/* File: mips/op_iget_short.S */
/* File: mips/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- JAL(MterpIGetI16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA4(a2) # a2<- A+
- PREFETCH_INST(2) # load rINST
- bnez a3, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- .if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[A] <- v0
- .else
- SET_VREG_GOTO(v0, a2, t0) # fp[A] <- v0
- .endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU32
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU32)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: mips/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- EAS2(a2, rFP, a2) # a2 <- &fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU64)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_iput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: mips/op_iput_object.S */
- /*
- * 32-bit instance field put.
- *
- * for: iput-object, iput-object-volatile
- */
- /* op vA, vB, field@CCCC */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpIPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_iput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: mips/op_iput_boolean.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU8)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2968,26 +2772,9 @@
.L_op_iput_byte: /* 0x5d */
/* File: mips/op_iput_byte.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutI8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutI8)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -2995,26 +2782,9 @@
.L_op_iput_char: /* 0x5e */
/* File: mips/op_iput_char.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutU16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutU16)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3022,105 +2792,37 @@
.L_op_iput_short: /* 0x5f */
/* File: mips/op_iput_short.S */
/* File: mips/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern MterpIPutI16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPB(a1) # a1 <- B
- GET_VREG(a1, a1) # a1 <- fp[B], the object pointer
- GET_OPA4(a2) # a2 <- A+
- GET_VREG(a2, a2) # a2 <- fp[A]
- lw a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST(2) # load rINST
- JAL(MterpIPutI16)
- bnez v0, MterpPossibleException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetU32
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU32)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: mips/op_sget_wide.S */
- /*
- * 64-bit SGET handler.
- */
- /* sget-wide vAA, field@BBBB */
- .extern MterpSGetU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU64)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- bnez a3, MterpException
- GET_OPA(a1) # a1 <- AA
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- SET_VREG64_GOTO(v0, v1, a1, t0) # vAA/vAA+1 <- v0/v1
+/* File: mips/op_sget.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: mips/op_sget_object.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetObj
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetObj)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 1
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3128,29 +2830,9 @@
.L_op_sget_boolean: /* 0x63 */
/* File: mips/op_sget_boolean.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetU8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3158,29 +2840,9 @@
.L_op_sget_byte: /* 0x64 */
/* File: mips/op_sget_byte.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetI8
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetI8)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3188,29 +2850,9 @@
.L_op_sget_char: /* 0x65 */
/* File: mips/op_sget_char.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetU16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetU16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3218,120 +2860,47 @@
.L_op_sget_short: /* 0x66 */
/* File: mips/op_sget_short.S */
/* File: mips/op_sget.S */
- /*
- * General SGET handler.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern MterpSGetI16
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- lw a1, OFF_FP_METHOD(rFP) # a1 <- method
- move a2, rSELF # a2 <- self
- JAL(MterpSGetI16)
- lw a3, THREAD_EXCEPTION_OFFSET(rSELF)
- GET_OPA(a2) # a2 <- AA
- PREFETCH_INST(2)
- bnez a3, MterpException # bail out
- ADVANCE(2)
- GET_INST_OPCODE(t0) # extract opcode from rINST
-.if 0
- SET_VREG_OBJECT_GOTO(v0, a2, t0) # fp[AA] <- v0
-.else
- SET_VREG_GOTO(v0, a2, t0) # fp[AA] <- v0
-.endif
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU32)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: mips/op_sput_wide.S */
- /*
- * 64-bit SPUT handler.
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref CCCC
- GET_OPA(a1) # a1 <- AA
- EAS2(a1, rFP, a1) # a1 <- &fp[AA]
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU64)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_sput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: mips/op_sput_object.S */
- /*
- * General 32-bit SPUT handler.
- *
- * for: sput-object,
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- addu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- JAL(MterpSPutObj)
- beqz v0, MterpException
- FETCH_ADVANCE_INST(2) # advance rPC, load rINST
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/op_sput.S */
+/* File: mips/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: mips/op_sput_boolean.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU8)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3339,24 +2908,9 @@
.L_op_sput_byte: /* 0x6b */
/* File: mips/op_sput_byte.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutI8)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3364,24 +2918,9 @@
.L_op_sput_char: /* 0x6c */
/* File: mips/op_sput_char.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutU16)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
@@ -3389,24 +2928,9 @@
.L_op_sput_short: /* 0x6d */
/* File: mips/op_sput_short.S */
/* File: mips/op_sput.S */
- /*
- * General SPUT handler.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- EXPORT_PC()
- FETCH(a0, 1) # a0 <- field ref BBBB
- GET_OPA(a3) # a3 <- AA
- GET_VREG(a1, a3) # a1 <- fp[AA], the object pointer
- lw a2, OFF_FP_METHOD(rFP) # a2 <- method
- move a3, rSELF # a3 <- self
- PREFETCH_INST(2) # load rINST
- JAL(MterpSPutI16)
- bnez v0, MterpException # bail out
- ADVANCE(2) # advance rPC
- GET_INST_OPCODE(t0) # extract opcode from rINST
- GOTO_OPCODE(t0) # jump to next instruction
+/* File: mips/field.S */
+TODO
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_mips64.S b/runtime/interpreter/mterp/out/mterp_mips64.S
index 6561691..40a8396 100644
--- a/runtime/interpreter/mterp/out/mterp_mips64.S
+++ b/runtime/interpreter/mterp/out/mterp_mips64.S
@@ -2241,88 +2241,28 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU32
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: mips64/op_iget_wide.S */
- /*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- .extern MterpIGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- SET_VREG_WIDE v0, a2 # fp[A] <- v0
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_iget.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: mips64/op_iget_object.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetObj
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetObj
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 1
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2330,31 +2270,9 @@
.L_op_iget_boolean: /* 0x55 */
/* File: mips64/op_iget_boolean.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2362,31 +2280,9 @@
.L_op_iget_byte: /* 0x56 */
/* File: mips64/op_iget_byte.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetI8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2394,31 +2290,9 @@
.L_op_iget_char: /* 0x57 */
/* File: mips64/op_iget_char.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetU16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2426,119 +2300,47 @@
.L_op_iget_short: /* 0x58 */
/* File: mips64/op_iget_short.S */
/* File: mips64/op_iget.S */
- /*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- .extern MterpIGetI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ld a2, OFF_FP_METHOD(rFP) # a2 <- referrer
- move a3, rSELF # a3 <- self
- jal MterpIGetI16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- ext a2, rINST, 8, 4 # a2 <- A
- PREFETCH_INST 2
- bnez a3, MterpPossibleException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[A] <- v0
- .else
- SET_VREG v0, a2 # fp[A] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU32
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: mips64/op_iput_wide.S */
- /* iput-wide vA, vB, field//CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- dlsa a2, a2, rFP, 2 # a2 <- &fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU64
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_iput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: mips64/op_iput_object.S */
- .extern MterpIPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpIPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_iput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: mips64/op_iput_boolean.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU8
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2546,26 +2348,9 @@
.L_op_iput_byte: /* 0x5d */
/* File: mips64/op_iput_byte.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutI8
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2573,26 +2358,9 @@
.L_op_iput_char: /* 0x5e */
/* File: mips64/op_iput_char.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutU16
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2600,111 +2368,37 @@
.L_op_iput_short: /* 0x5f */
/* File: mips64/op_iput_short.S */
/* File: mips64/op_iput.S */
- /*
- * General 32-bit instance field put.
- *
- * for: iput, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field//CCCC */
- .extern MterpIPutI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref CCCC
- srl a1, rINST, 12 # a1 <- B
- GET_VREG_U a1, a1 # a1 <- fp[B], the object pointer
- ext a2, rINST, 8, 4 # a2 <- A
- GET_VREG a2, a2 # a2 <- fp[A]
- ld a3, OFF_FP_METHOD(rFP) # a3 <- referrer
- PREFETCH_INST 2
- jal MterpIPutI16
- bnez v0, MterpPossibleException # bail out
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU32
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
-
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: mips64/op_sget_wide.S */
- /*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field//BBBB */
- .extern MterpSGetU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU64
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a4, rINST, 8 # a4 <- AA
- bnez a3, MterpException # bail out
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- SET_VREG_WIDE v0, a4
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_sget.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: mips64/op_sget_object.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetObj
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetObj
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
-
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 1
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2712,31 +2406,9 @@
.L_op_sget_boolean: /* 0x63 */
/* File: mips64/op_sget_boolean.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- and v0, v0, 0xff
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2744,31 +2416,9 @@
.L_op_sget_byte: /* 0x64 */
/* File: mips64/op_sget_byte.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetI8
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- seb v0, v0
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2776,31 +2426,9 @@
.L_op_sget_char: /* 0x65 */
/* File: mips64/op_sget_char.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetU16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- and v0, v0, 0xffff
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2808,120 +2436,47 @@
.L_op_sget_short: /* 0x66 */
/* File: mips64/op_sget_short.S */
/* File: mips64/op_sget.S */
- /*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSGetI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- ld a1, OFF_FP_METHOD(rFP)
- move a2, rSELF
- jal MterpSGetI16
- ld a3, THREAD_EXCEPTION_OFFSET(rSELF)
- srl a2, rINST, 8 # a2 <- AA
- seh v0, v0
- PREFETCH_INST 2
- bnez a3, MterpException # bail out
- .if 0
- SET_VREG_OBJECT v0, a2 # fp[AA] <- v0
- .else
- SET_VREG v0, a2 # fp[AA] <- v0
- .endif
- ADVANCE 2
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutU32
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU32
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: mips64/op_sput_wide.S */
- /*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field//BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a1, rINST, 8 # a2 <- AA
- dlsa a1, a1, rFP, 2
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU64
- bnezc v0, MterpException # 0 on success, -1 on failure
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_sput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: mips64/op_sput_object.S */
- .extern MterpSPutObj
- EXPORT_PC
- daddu a0, rFP, OFF_FP_SHADOWFRAME
- move a1, rPC
- move a2, rINST
- move a3, rSELF
- jal MterpSPutObj
- beqzc v0, MterpException
- FETCH_ADVANCE_INST 2 # advance rPC, load rINST
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/op_sput.S */
+/* File: mips64/field.S */
+TODO
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: mips64/op_sput_boolean.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutU8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU8
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2929,25 +2484,9 @@
.L_op_sput_byte: /* 0x6b */
/* File: mips64/op_sput_byte.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutI8
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutI8
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2955,25 +2494,9 @@
.L_op_sput_char: /* 0x6c */
/* File: mips64/op_sput_char.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutU16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutU16
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
@@ -2981,25 +2504,9 @@
.L_op_sput_short: /* 0x6d */
/* File: mips64/op_sput_short.S */
/* File: mips64/op_sput.S */
- /*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field//BBBB */
- .extern MterpSPutI16
- EXPORT_PC
- lhu a0, 2(rPC) # a0 <- field ref BBBB
- srl a3, rINST, 8 # a3 <- AA
- GET_VREG a1, a3 # a1 <- fp[AA]
- ld a2, OFF_FP_METHOD(rFP)
- move a3, rSELF
- PREFETCH_INST 2 # Get next inst, but don't advance rPC
- jal MterpSPutI16
- bnezc v0, MterpException # 0 on success
- ADVANCE 2 # Past exception point - now advance rPC
- GET_INST_OPCODE v0 # extract opcode from rINST
- GOTO_OPCODE v0 # jump to next instruction
+/* File: mips64/field.S */
+TODO
+
/* ------------------------------ */
diff --git a/runtime/interpreter/mterp/out/mterp_x86.S b/runtime/interpreter/mterp/out/mterp_x86.S
index 3f70919..32811ff 100644
--- a/runtime/interpreter/mterp/out/mterp_x86.S
+++ b/runtime/interpreter/mterp/out/mterp_x86.S
@@ -2120,832 +2120,694 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU32
+ REFRESH_INST 82 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU32)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: x86/op_iget_wide.S */
-/*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/op_iget.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU64
+ REFRESH_INST 83 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU64)
- mov rSELF, %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- SET_VREG %eax, rINST
- SET_VREG_HIGH %edx, rINST
- RESTORE_IBASE_FROM_SELF %ecx
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: x86/op_iget_object.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetObj
+ REFRESH_INST 84 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetObj)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 1
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: x86/op_iget_boolean.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU8
+ REFRESH_INST 85 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: x86/op_iget_byte.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI8
+ REFRESH_INST 86 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetI8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: x86/op_iget_char.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU16
+ REFRESH_INST 87 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetU16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: x86/op_iget_short.S */
/* File: x86/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI16
+ REFRESH_INST 88 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIGetI16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU32
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 89 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU32)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: x86/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
+/* File: x86/op_iput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl,%ecx # ecx <- BA
- sarl $4,%ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf,rINSTbl # rINST <- A
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG2(%esp) # &fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 90 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU64)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: x86/op_iput_object.S */
- EXPORT_PC
+/* File: x86/op_iput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ REFRESH_INST 91 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST 91
- movl rINST, OUT_ARG2(%esp)
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
movl rSELF, %eax
- movl %eax, OUT_ARG3(%esp)
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: x86/op_iput_boolean.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU8
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 92 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_byte: /* 0x5d */
/* File: x86/op_iput_byte.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI8
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 93 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutI8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_char: /* 0x5e */
/* File: x86/op_iput_char.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU16
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 94 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutU16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_short: /* 0x5f */
/* File: x86/op_iput_short.S */
/* File: x86/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI16
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
+ REFRESH_INST 95 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpIPutI16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU32
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 96 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU32)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: x86/op_sget_wide.S */
-/*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field@BBBB */
+/* File: x86/op_sget.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 97 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU64)
- movl rSELF, %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- SET_VREG %eax, rINST # fp[A]<- low part
- SET_VREG_HIGH %edx, rINST # fp[A+1]<- high part
- RESTORE_IBASE_FROM_SELF %ecx
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: x86/op_sget_object.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetObj
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 98 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetObj)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 1
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_boolean: /* 0x63 */
/* File: x86/op_sget_boolean.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 99 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_byte: /* 0x64 */
/* File: x86/op_sget_byte.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 100 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetI8)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_char: /* 0x65 */
/* File: x86/op_sget_char.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 101 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetU16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_short: /* 0x66 */
/* File: x86/op_sget_short.S */
/* File: x86/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
+ REFRESH_INST 102 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSGetI16)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU32
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 103 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU32)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: x86/op_sput_wide.S */
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
+/* File: x86/op_sput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG1(%esp) # &fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 104 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU64)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: x86/op_sput_object.S */
- EXPORT_PC
+/* File: x86/op_sput.S */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ REFRESH_INST 105 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST 105
- movl rINST, OUT_ARG2(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp)
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: x86/op_sput_boolean.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 106 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_byte: /* 0x6b */
/* File: x86/op_sput_byte.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI8
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 107 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutI8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_char: /* 0x6c */
/* File: x86/op_sput_char.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 108 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutU16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_short: /* 0x6d */
/* File: x86/op_sput_short.S */
/* File: x86/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI16
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
+ REFRESH_INST 109 # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
call SYMBOL(MterpSPutI16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
RESTORE_IBASE
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_invoke_virtual: /* 0x6e */
diff --git a/runtime/interpreter/mterp/out/mterp_x86_64.S b/runtime/interpreter/mterp/out/mterp_x86_64.S
index 89d5637..6d8bb4c 100644
--- a/runtime/interpreter/mterp/out/mterp_x86_64.S
+++ b/runtime/interpreter/mterp/out/mterp_x86_64.S
@@ -2067,770 +2067,610 @@
.balign 128
.L_op_iget: /* 0x52 */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU32
+ REFRESH_INST 82 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU32)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_wide: /* 0x53 */
/* File: x86_64/op_iget_wide.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU64
+ REFRESH_INST 83 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU64)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 1
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_object: /* 0x54 */
/* File: x86_64/op_iget_object.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetObj
+ REFRESH_INST 84 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetObj)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 1
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_boolean: /* 0x55 */
/* File: x86_64/op_iget_boolean.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU8
+ REFRESH_INST 85 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU8)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_byte: /* 0x56 */
/* File: x86_64/op_iget_byte.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI8
+ REFRESH_INST 86 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetI8)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_char: /* 0x57 */
/* File: x86_64/op_iget_char.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetU16
+ REFRESH_INST 87 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetU16)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iget_short: /* 0x58 */
/* File: x86_64/op_iget_short.S */
/* File: x86_64/op_iget.S */
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIGetI16
+ REFRESH_INST 88 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIGetI16)
- movq rSELF, %rcx
- cmpq $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $0xf, rINSTbl # rINST <- A
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput: /* 0x59 */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU32
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 89 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU32)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_wide: /* 0x5a */
/* File: x86_64/op_iput_wide.S */
- /* iput-wide vA, vB, field@CCCC */
+/* File: x86_64/op_iput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movzbq rINSTbl, %rcx # rcx <- BA
- sarl $4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST <- A
- leaq VREG_ADDRESS(rINSTq), OUT_ARG2 # &fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 90 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU64)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_object: /* 0x5b */
/* File: x86_64/op_iput_object.S */
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST 91
- movl rINST, OUT_32_ARG2
- movq rSELF, OUT_ARG3
+/* File: x86_64/op_iput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpIPutObj
+ REFRESH_INST 91 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_iput_boolean: /* 0x5c */
/* File: x86_64/op_iput_boolean.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU8
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 92 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_byte: /* 0x5d */
/* File: x86_64/op_iput_byte.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI8
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 93 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutI8)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_char: /* 0x5e */
/* File: x86_64/op_iput_char.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutU16
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 94 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutU16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_iput_short: /* 0x5f */
/* File: x86_64/op_iput_short.S */
/* File: x86_64/op_iput.S */
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpIPutI16
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
+ REFRESH_INST 95 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpIPutI16)
testb %al, %al
- jnz MterpPossibleException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget: /* 0x60 */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU32
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 96 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU32)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_wide: /* 0x61 */
/* File: x86_64/op_sget_wide.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 97 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU64)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 1
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_object: /* 0x62 */
/* File: x86_64/op_sget_object.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetObj
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 98 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetObj)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 1
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_boolean: /* 0x63 */
/* File: x86_64/op_sget_boolean.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 99 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU8)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_byte: /* 0x64 */
/* File: x86_64/op_sget_byte.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 100 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetI8)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_char: /* 0x65 */
/* File: x86_64/op_sget_char.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetU16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 101 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetU16)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sget_short: /* 0x66 */
/* File: x86_64/op_sget_short.S */
/* File: x86_64/op_sget.S */
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSGetI16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
+ REFRESH_INST 102 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSGetI16)
- movq rSELF, %rcx
- cmpl $0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if 0
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if 0
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
+ testb %al, %al
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput: /* 0x67 */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU32
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 103 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU32)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_wide: /* 0x68 */
/* File: x86_64/op_sput_wide.S */
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
+/* File: x86_64/op_sput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- leaq VREG_ADDRESS(rINSTq), OUT_ARG1 # &fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 104 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU64)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_object: /* 0x69 */
/* File: x86_64/op_sput_object.S */
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST 105
- movq rINSTq, OUT_ARG2
- movq rSELF, OUT_ARG3
+/* File: x86_64/op_sput.S */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern MterpSPutObj
+ REFRESH_INST 105 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutObj)
testb %al, %al
- jz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
+
/* ------------------------------ */
.balign 128
.L_op_sput_boolean: /* 0x6a */
/* File: x86_64/op_sput_boolean.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 106 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_byte: /* 0x6b */
/* File: x86_64/op_sput_byte.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI8
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 107 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutI8)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_char: /* 0x6c */
/* File: x86_64/op_sput_char.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutU16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 108 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutU16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_sput_short: /* 0x6d */
/* File: x86_64/op_sput_short.S */
/* File: x86_64/op_sput.S */
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
+/* File: x86_64/field.S */
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
.extern MterpSPutI16
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
+ REFRESH_INST 109 # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
call SYMBOL(MterpSPutI16)
testb %al, %al
- jnz MterpException
+ jz MterpPossibleException
ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+
/* ------------------------------ */
.balign 128
.L_op_invoke_virtual: /* 0x6e */
diff --git a/runtime/interpreter/mterp/x86/field.S b/runtime/interpreter/mterp/x86/field.S
new file mode 100644
index 0000000..8432c74
--- /dev/null
+++ b/runtime/interpreter/mterp/x86/field.S
@@ -0,0 +1,17 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ REFRESH_INST ${opnum} # fix rINST to include opcode
+ movl rPC, OUT_ARG0(%esp) # arg0: Instruction* inst
+ movl rINST, OUT_ARG1(%esp) # arg1: uint16_t inst_data
+ leal OFF_FP_SHADOWFRAME(rFP), %eax
+ movl %eax, OUT_ARG2(%esp) # arg2: ShadowFrame* sf
+ movl rSELF, %eax
+ movl %eax, OUT_ARG3(%esp) # arg3: Thread* self
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpPossibleException
+ RESTORE_IBASE
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86/op_iget.S b/runtime/interpreter/mterp/x86/op_iget.S
index 0af1bec..d85d54c 100644
--- a/runtime/interpreter/mterp/x86/op_iget.S
+++ b/runtime/interpreter/mterp/x86/op_iget.S
@@ -1,29 +1,2 @@
%default { "is_object":"0", "helper":"MterpIGetU32"}
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL($helper)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $$0xf, rINSTbl # rINST <- A
- .if $is_object
- SET_VREG_OBJECT %eax, rINST # fp[A] <-value
- .else
- SET_VREG %eax, rINST # fp[A] <-value
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_iget_wide.S b/runtime/interpreter/mterp/x86/op_iget_wide.S
index da27df9..741a64e 100644
--- a/runtime/interpreter/mterp/x86/op_iget_wide.S
+++ b/runtime/interpreter/mterp/x86/op_iget_wide.S
@@ -1,25 +1 @@
-/*
- * 64-bit instance field get.
- *
- * for: iget-wide
- */
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- mov rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL(MterpIGetU64)
- mov rSELF, %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException # bail out
- andb $$0xf, rINSTbl # rINST <- A
- SET_VREG %eax, rINST
- SET_VREG_HIGH %edx, rINST
- RESTORE_IBASE_FROM_SELF %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/x86/op_iput.S b/runtime/interpreter/mterp/x86/op_iput.S
index 4c6603a..3628ffd 100644
--- a/runtime/interpreter/mterp/x86/op_iput.S
+++ b/runtime/interpreter/mterp/x86/op_iput.S
@@ -1,25 +1,2 @@
-%default { "helper":"MterpIPutU32" }
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), %eax # eax<- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl, %ecx # ecx<- BA
- sarl $$4, %ecx # ecx<- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $$0xf, rINSTbl # rINST<- A
- GET_VREG %eax, rINST
- movl %eax, OUT_ARG2(%esp) # fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpPossibleException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_iput_object.S b/runtime/interpreter/mterp/x86/op_iput_object.S
index 56e026e..a124b7e 100644
--- a/runtime/interpreter/mterp/x86/op_iput_object.S
+++ b/runtime/interpreter/mterp/x86/op_iput_object.S
@@ -1,13 +1 @@
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- movl rSELF, %eax
- movl %eax, OUT_ARG3(%esp)
- call SYMBOL(MterpIPutObj)
- testb %al, %al
- jz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/x86/op_iput_wide.S b/runtime/interpreter/mterp/x86/op_iput_wide.S
index ea22b91..2820ede 100644
--- a/runtime/interpreter/mterp/x86/op_iput_wide.S
+++ b/runtime/interpreter/mterp/x86/op_iput_wide.S
@@ -1,19 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax # eax <- 0000CCCC
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movzbl rINSTbl,%ecx # ecx <- BA
- sarl $$4,%ecx # ecx <- B
- GET_VREG %ecx, %ecx
- movl %ecx, OUT_ARG1(%esp) # the object pointer
- andb $$0xf,rINSTbl # rINST <- A
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG2(%esp) # &fp[A]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG3(%esp) # referrer
- call SYMBOL(MterpIPutU64)
- testb %al, %al
- jnz MterpPossibleException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/x86/op_sget.S b/runtime/interpreter/mterp/x86/op_sget.S
index 66c7b0b..ada4e0e 100644
--- a/runtime/interpreter/mterp/x86/op_sget.S
+++ b/runtime/interpreter/mterp/x86/op_sget.S
@@ -1,26 +1,2 @@
%default { "is_object":"0", "helper":"MterpSGetU32" }
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
- call SYMBOL($helper)
- movl rSELF, %ecx
- RESTORE_IBASE_FROM_SELF %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- .if $is_object
- SET_VREG_OBJECT %eax, rINST # fp[A] <- value
- .else
- SET_VREG %eax, rINST # fp[A] <- value
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_sget_wide.S b/runtime/interpreter/mterp/x86/op_sget_wide.S
index 994cc3a..5923274 100644
--- a/runtime/interpreter/mterp/x86/op_sget_wide.S
+++ b/runtime/interpreter/mterp/x86/op_sget_wide.S
@@ -1,21 +1 @@
-/*
- * SGET_WIDE handler wrapper.
- *
- */
- /* sget-wide vAA, field@BBBB */
- .extern MterpSGetU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref CCCC
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG1(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG2(%esp) # self
- call SYMBOL(MterpSGetU64)
- movl rSELF, %ecx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%ecx)
- jnz MterpException
- SET_VREG %eax, rINST # fp[A]<- low part
- SET_VREG_HIGH %edx, rINST # fp[A+1]<- high part
- RESTORE_IBASE_FROM_SELF %ecx
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/x86/op_sput.S b/runtime/interpreter/mterp/x86/op_sput.S
index e99e7a7..2ad68e7 100644
--- a/runtime/interpreter/mterp/x86/op_sput.S
+++ b/runtime/interpreter/mterp/x86/op_sput.S
@@ -1,22 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- GET_VREG rINST, rINST
- movl rINST, OUT_ARG1(%esp) # fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "x86/field.S" { }
diff --git a/runtime/interpreter/mterp/x86/op_sput_object.S b/runtime/interpreter/mterp/x86/op_sput_object.S
index 941b072..4452dba 100644
--- a/runtime/interpreter/mterp/x86/op_sput_object.S
+++ b/runtime/interpreter/mterp/x86/op_sput_object.S
@@ -1,13 +1 @@
- EXPORT_PC
- leal OFF_FP_SHADOWFRAME(rFP), %eax
- movl %eax, OUT_ARG0(%esp)
- movl rPC, OUT_ARG1(%esp)
- REFRESH_INST ${opnum}
- movl rINST, OUT_ARG2(%esp)
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp)
- call SYMBOL(MterpSPutObj)
- testb %al, %al
- jz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/x86/op_sput_wide.S b/runtime/interpreter/mterp/x86/op_sput_wide.S
index f581507..d79b068 100644
--- a/runtime/interpreter/mterp/x86/op_sput_wide.S
+++ b/runtime/interpreter/mterp/x86/op_sput_wide.S
@@ -1,20 +1 @@
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- movzwl 2(rPC), %eax
- movl %eax, OUT_ARG0(%esp) # field ref BBBB
- leal VREG_ADDRESS(rINST), %eax
- movl %eax, OUT_ARG1(%esp) # &fp[AA]
- movl OFF_FP_METHOD(rFP), %eax
- movl %eax, OUT_ARG2(%esp) # referrer
- movl rSELF, %ecx
- movl %ecx, OUT_ARG3(%esp) # self
- call SYMBOL(MterpSPutU64)
- testb %al, %al
- jnz MterpException
- RESTORE_IBASE
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/interpreter/mterp/x86_64/field.S b/runtime/interpreter/mterp/x86_64/field.S
new file mode 100644
index 0000000..f8b0588
--- /dev/null
+++ b/runtime/interpreter/mterp/x86_64/field.S
@@ -0,0 +1,14 @@
+%default { }
+ /*
+ * General field read / write (iget-* iput-* sget-* sput-*).
+ */
+ .extern $helper
+ REFRESH_INST ${opnum} # fix rINST to include opcode
+ movq rPC, OUT_ARG0 # arg0: Instruction* inst
+ movl rINST, OUT_32_ARG1 # arg1: uint16_t inst_data
+ leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG2 # arg2: ShadowFrame* sf
+ movq rSELF, OUT_ARG3 # arg3: Thread* self
+ call SYMBOL($helper)
+ testb %al, %al
+ jz MterpPossibleException
+ ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
diff --git a/runtime/interpreter/mterp/x86_64/op_iget.S b/runtime/interpreter/mterp/x86_64/op_iget.S
index 5c6cab6..4ab7c27 100644
--- a/runtime/interpreter/mterp/x86_64/op_iget.S
+++ b/runtime/interpreter/mterp/x86_64/op_iget.S
@@ -1,28 +1,2 @@
-%default { "is_object":"0", "helper":"MterpIGetU32", "wide":"0"}
-/*
- * General instance field get.
- *
- * for: iget, iget-object, iget-boolean, iget-byte, iget-char, iget-short, iget-wide
- */
- EXPORT_PC
- movzbq rINSTbl, %rcx # rcx <- BA
- movzwl 2(rPC), OUT_32_ARG0 # eax <- field ref CCCC
- sarl $$4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3
- call SYMBOL($helper)
- movq rSELF, %rcx
- cmpq $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException # bail out
- andb $$0xf, rINSTbl # rINST <- A
- .if $is_object
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <-value
- .else
- .if $wide
- SET_WIDE_VREG %rax, rINSTq # fp[A] <-value
- .else
- SET_VREG %eax, rINSTq # fp[A] <-value
- .endif
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIGetU32"}
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_iget_wide.S b/runtime/interpreter/mterp/x86_64/op_iget_wide.S
index d9d1744..a85a474 100644
--- a/runtime/interpreter/mterp/x86_64/op_iget_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_iget_wide.S
@@ -1 +1 @@
-%include "x86_64/op_iget.S" { "helper":"MterpIGetU64", "wide":"1" }
+%include "x86_64/op_iget.S" { "helper":"MterpIGetU64" }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput.S b/runtime/interpreter/mterp/x86_64/op_iput.S
index 12affdb..dad5af6 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput.S
@@ -1,20 +1,2 @@
-%default { "helper":"MterpIPutU32"}
-/*
- * General 32-bit instance field put.
- *
- * for: iput, iput-object, iput-boolean, iput-byte, iput-char, iput-short
- */
- /* op vA, vB, field@CCCC */
- .extern $helper
- EXPORT_PC
- movzwl 2(rPC), OUT_32_ARG0 # field ref <- 0000CCCC
- movzbq rINSTbl, %rcx # rcx<- BA
- sarl $$4, %ecx # ecx<- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $$0xf, rINSTbl # rINST<- A
- GET_VREG OUT_32_ARG2, rINSTq # fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpIPutU32" }
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_object.S b/runtime/interpreter/mterp/x86_64/op_iput_object.S
index 22648cd..202e33f 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput_object.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST ${opnum}
- movl rINST, OUT_32_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpIPutObj)
- testb %al, %al
- jz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_iput.S" { "is_object":"1", "helper":"MterpIPutObj" }
diff --git a/runtime/interpreter/mterp/x86_64/op_iput_wide.S b/runtime/interpreter/mterp/x86_64/op_iput_wide.S
index 4f8c47c..db52016 100644
--- a/runtime/interpreter/mterp/x86_64/op_iput_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_iput_wide.S
@@ -1,14 +1 @@
- /* iput-wide vA, vB, field@CCCC */
- .extern MterpIPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movzbq rINSTbl, %rcx # rcx <- BA
- sarl $$4, %ecx # ecx <- B
- GET_VREG OUT_32_ARG1, %rcx # the object pointer
- andb $$0xf, rINSTbl # rINST <- A
- leaq VREG_ADDRESS(rINSTq), OUT_ARG2 # &fp[A]
- movq OFF_FP_METHOD(rFP), OUT_ARG3 # referrer
- call SYMBOL(MterpIPutU64)
- testb %al, %al
- jnz MterpPossibleException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_iput.S" { "helper":"MterpIPutU64" }
diff --git a/runtime/interpreter/mterp/x86_64/op_sget.S b/runtime/interpreter/mterp/x86_64/op_sget.S
index c15ac1e..21e8e64 100644
--- a/runtime/interpreter/mterp/x86_64/op_sget.S
+++ b/runtime/interpreter/mterp/x86_64/op_sget.S
@@ -1,26 +1,2 @@
-%default { "is_object":"0", "helper":"MterpSGetU32", "wide":"0" }
-/*
- * General SGET handler wrapper.
- *
- * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short, sget-wide
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref CCCC
- movq OFF_FP_METHOD(rFP), OUT_ARG1 # referrer
- movq rSELF, OUT_ARG2 # self
- call SYMBOL($helper)
- movq rSELF, %rcx
- cmpl $$0, THREAD_EXCEPTION_OFFSET(%rcx)
- jnz MterpException
- .if $is_object
- SET_VREG_OBJECT %eax, rINSTq # fp[A] <- value
- .else
- .if $wide
- SET_WIDE_VREG %rax, rINSTq # fp[A] <- value
- .else
- SET_VREG %eax, rINSTq # fp[A] <- value
- .endif
- .endif
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSGetU32" }
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_sget_wide.S b/runtime/interpreter/mterp/x86_64/op_sget_wide.S
index 65ddb8a..c53c077 100644
--- a/runtime/interpreter/mterp/x86_64/op_sget_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_sget_wide.S
@@ -1 +1 @@
-%include "x86_64/op_sget.S" {"helper":"MterpSGetU64", "wide":"1"}
+%include "x86_64/op_sget.S" {"helper":"MterpSGetU64"}
diff --git a/runtime/interpreter/mterp/x86_64/op_sput.S b/runtime/interpreter/mterp/x86_64/op_sput.S
index 9a33d52..7dd2498 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput.S
@@ -1,17 +1,2 @@
-%default { "helper":"MterpSPutU32"}
-/*
- * General SPUT handler wrapper.
- *
- * for: sput, sput-boolean, sput-byte, sput-char, sput-short
- */
- /* op vAA, field@BBBB */
- .extern $helper
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- GET_VREG OUT_32_ARG1, rINSTq # fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
- call SYMBOL($helper)
- testb %al, %al
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%default { "is_object":"0", "helper":"MterpSPutU32"}
+%include "x86_64/field.S" { }
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_object.S b/runtime/interpreter/mterp/x86_64/op_sput_object.S
index 8a47074..c2bd07b 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput_object.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput_object.S
@@ -1,10 +1 @@
- EXPORT_PC
- leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG0
- movq rPC, OUT_ARG1
- REFRESH_INST ${opnum}
- movq rINSTq, OUT_ARG2
- movq rSELF, OUT_ARG3
- call SYMBOL(MterpSPutObj)
- testb %al, %al
- jz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_sput.S" {"is_object":"1", "helper":"MterpSPutObj"}
diff --git a/runtime/interpreter/mterp/x86_64/op_sput_wide.S b/runtime/interpreter/mterp/x86_64/op_sput_wide.S
index 464d169..7e77072 100644
--- a/runtime/interpreter/mterp/x86_64/op_sput_wide.S
+++ b/runtime/interpreter/mterp/x86_64/op_sput_wide.S
@@ -1,15 +1 @@
-/*
- * SPUT_WIDE handler wrapper.
- *
- */
- /* sput-wide vAA, field@BBBB */
- .extern MterpSPutU64
- EXPORT_PC
- movzwq 2(rPC), OUT_ARG0 # field ref BBBB
- leaq VREG_ADDRESS(rINSTq), OUT_ARG1 # &fp[AA]
- movq OFF_FP_METHOD(rFP), OUT_ARG2 # referrer
- movq rSELF, OUT_ARG3 # self
- call SYMBOL(MterpSPutU64)
- testb %al, %al
- jnz MterpException
- ADVANCE_PC_FETCH_AND_GOTO_NEXT 2
+%include "x86_64/op_sput.S" {"helper":"MterpSPutU64"}
diff --git a/runtime/jdwp/jdwp_adb.cc b/runtime/jdwp/jdwp_adb.cc
index 481aff9..e6043c6 100644
--- a/runtime/jdwp/jdwp_adb.cc
+++ b/runtime/jdwp/jdwp_adb.cc
@@ -87,13 +87,13 @@
}
}
- virtual bool Accept() REQUIRES(!state_lock_);
+ bool Accept() override REQUIRES(!state_lock_);
- virtual bool Establish(const JdwpOptions*) {
+ bool Establish(const JdwpOptions*) override {
return false;
}
- virtual void Shutdown() REQUIRES(!state_lock_) {
+ void Shutdown() override REQUIRES(!state_lock_) {
int control_sock;
int local_clientSock;
{
@@ -116,7 +116,7 @@
WakePipe();
}
- virtual bool ProcessIncoming() REQUIRES(!state_lock_);
+ bool ProcessIncoming() override REQUIRES(!state_lock_);
private:
int ReceiveClientFd() REQUIRES(!state_lock_);
diff --git a/runtime/jdwp/jdwp_socket.cc b/runtime/jdwp/jdwp_socket.cc
index 673a942..29fa160 100644
--- a/runtime/jdwp/jdwp_socket.cc
+++ b/runtime/jdwp/jdwp_socket.cc
@@ -54,10 +54,10 @@
remote_port_(0U) {
}
- virtual bool Accept();
- virtual bool Establish(const JdwpOptions*);
- virtual void Shutdown();
- virtual bool ProcessIncoming();
+ bool Accept() override;
+ bool Establish(const JdwpOptions*) override;
+ void Shutdown() override;
+ bool ProcessIncoming() override;
private:
in_addr remote_addr_;
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 2b2898c..bcbdc3b 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -28,6 +28,7 @@
#include "base/stl_util.h"
#include "base/systrace.h"
#include "base/time_utils.h"
+#include "base/utils.h"
#include "cha.h"
#include "debugger_interface.h"
#include "dex/dex_file_loader.h"
@@ -53,8 +54,9 @@
namespace art {
namespace jit {
-static constexpr int kProtData = PROT_READ | PROT_WRITE;
static constexpr int kProtCode = PROT_READ | PROT_EXEC;
+static constexpr int kProtData = PROT_READ | PROT_WRITE;
+static constexpr int kProtProfile = PROT_READ;
static constexpr size_t kCodeSizeLogThreshold = 50 * KB;
static constexpr size_t kStackMapSizeLogThreshold = 50 * KB;
@@ -192,7 +194,7 @@
// to profile system server.
// NOTE 2: We could just not create the code section at all but we will need to
// special case too many cases.
- int memmap_flags_prot_code = used_only_for_profile_data ? (kProtCode & ~PROT_EXEC) : kProtCode;
+ int memmap_flags_prot_code = used_only_for_profile_data ? kProtProfile : kProtCode;
std::string error_str;
// Map name specific for android_os_Debug.cpp accounting.
@@ -528,7 +530,7 @@
// This does not need a read barrier because this is called by GC.
mirror::Class* cls = root_ptr->Read<kWithoutReadBarrier>();
if (cls != nullptr && cls != weak_sentinel) {
- DCHECK((cls->IsClass<kDefaultVerifyFlags, kWithoutReadBarrier>()));
+ DCHECK((cls->IsClass<kDefaultVerifyFlags>()));
// Look at the classloader of the class to know if it has been unloaded.
// This does not need a read barrier because this is called by GC.
mirror::Object* class_loader =
@@ -799,8 +801,18 @@
//
// For reference, this behavior is caused by this commit:
// https://android.googlesource.com/kernel/msm/+/3fbe6bc28a6b9939d0650f2f17eb5216c719950c
- FlushInstructionCache(reinterpret_cast<char*>(code_ptr),
- reinterpret_cast<char*>(code_ptr + code_size));
+ FlushInstructionCache(code_ptr, code_ptr + code_size);
+
+ // Ensure CPU instruction pipelines are flushed for all cores. This is necessary for
+ // correctness as code may still be in instruction pipelines despite the i-cache flush. It is
+ // not safe to assume that changing permissions with mprotect (RX->RWX->RX) will cause a TLB
+ // shootdown (incidentally invalidating the CPU pipelines by sending an IPI to all cores to
+ // notify them of the TLB invalidation). Some architectures, notably ARM and ARM64, have
+ // hardware support that broadcasts TLB invalidations and so their kernels have no software
+ // based TLB shootdown. FlushInstructionPipeline() is a wrapper around the Linux
+ // membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED) syscall which does the appropriate flushing.
+ FlushInstructionPipeline();
+
DCHECK(!Runtime::Current()->IsAotCompiler());
if (has_should_deoptimize_flag) {
method_header->SetHasShouldDeoptimizeFlag();
@@ -858,8 +870,7 @@
FillRootTable(roots_data, roots);
{
// Flush data cache, as compiled code references literals in it.
- FlushDataCache(reinterpret_cast<char*>(roots_data),
- reinterpret_cast<char*>(roots_data + data_size));
+ FlushDataCache(roots_data, roots_data + data_size);
}
method_code_map_.Put(code_ptr, method);
if (osr) {
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index d9ef922..9043f26 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -274,7 +274,7 @@
: profile_boot_class_path_(profile_boot_class_path),
out_(out) {}
- virtual bool operator()(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
if (klass->IsProxyClass() ||
klass->IsArrayClass() ||
klass->IsPrimitive() ||
diff --git a/runtime/jni/java_vm_ext_test.cc b/runtime/jni/java_vm_ext_test.cc
index 4049c6e..dfe50cf 100644
--- a/runtime/jni/java_vm_ext_test.cc
+++ b/runtime/jni/java_vm_ext_test.cc
@@ -27,7 +27,7 @@
class JavaVmExtTest : public CommonRuntimeTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
CommonRuntimeTest::SetUp();
vm_ = Runtime::Current()->GetJavaVM();
diff --git a/runtime/jni/jni_internal_test.cc b/runtime/jni/jni_internal_test.cc
index 3040b90..4ad4c14 100644
--- a/runtime/jni/jni_internal_test.cc
+++ b/runtime/jni/jni_internal_test.cc
@@ -34,7 +34,7 @@
// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
class JniInternalTest : public CommonCompilerTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
CommonCompilerTest::SetUp();
vm_ = Runtime::Current()->GetJavaVM();
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 51dc1a4..d3f8921 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -378,7 +378,7 @@
inline bool Class::IsVariableSize() {
// Classes, arrays, and strings vary in size, and so the object_size_ field cannot
// be used to Get their instance size
- return IsClassClass<kVerifyFlags, kReadBarrierOption>() ||
+ return IsClassClass<kVerifyFlags>() ||
IsArrayClass<kVerifyFlags, kReadBarrierOption>() ||
IsStringClass();
}
@@ -853,10 +853,12 @@
return size;
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline bool Class::IsClassClass() {
- ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
- template GetClass<kVerifyFlags, kReadBarrierOption>();
+ // OK to look at from-space copies since java.lang.Class.class is not movable.
+ // See b/114413743
+ ObjPtr<Class> java_lang_Class = GetClass<kVerifyFlags, kWithoutReadBarrier>()->
+ template GetClass<kVerifyFlags, kWithoutReadBarrier>();
return this == java_lang_Class;
}
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 811ee51..4015bd2 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -430,8 +430,7 @@
ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
bool IsArrayClass() REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsClassClass() REQUIRES_SHARED(Locks::mutator_lock_);
bool IsThrowableClass() REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index bd89907..1b03956 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -137,17 +137,18 @@
return klass->IsAssignableFrom(GetClass<kVerifyFlags>());
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline bool Object::IsClass() {
- constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags);
- Class* java_lang_Class = GetClass<kVerifyFlags, kReadBarrierOption>()->
- template GetClass<kVerifyFlags, kReadBarrierOption>();
- return GetClass<kNewFlags, kReadBarrierOption>() == java_lang_Class;
+ // OK to look at from-space copies since java.lang.Class.class is not movable.
+ // See b/114413743
+ ObjPtr<Class> klass = GetClass<kVerifyFlags, kWithoutReadBarrier>();
+ ObjPtr<Class> java_lang_Class = klass->template GetClass<kVerifyFlags, kWithoutReadBarrier>();
+ return klass == java_lang_Class;
}
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
+template<VerifyObjectFlags kVerifyFlags>
inline Class* Object::AsClass() {
- DCHECK((IsClass<kVerifyFlags, kReadBarrierOption>()));
+ DCHECK((IsClass<kVerifyFlags>()));
return down_cast<Class*>(this);
}
@@ -350,8 +351,8 @@
constexpr auto kNewFlags = RemoveThisFlags(kVerifyFlags);
if (IsArrayInstance<kVerifyFlags, kRBO>()) {
result = AsArray<kNewFlags, kRBO>()->template SizeOf<kNewFlags, kRBO>();
- } else if (IsClass<kNewFlags, kRBO>()) {
- result = AsClass<kNewFlags, kRBO>()->template SizeOf<kNewFlags, kRBO>();
+ } else if (IsClass<kNewFlags>()) {
+ result = AsClass<kNewFlags>()->template SizeOf<kNewFlags, kRBO>();
} else if (GetClass<kNewFlags, kRBO>()->IsStringClass()) {
result = AsString<kNewFlags, kRBO>()->template SizeOf<kNewFlags>();
} else {
@@ -364,7 +365,7 @@
template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
inline int8_t Object::GetFieldByte(MemberOffset field_offset) {
Verify<kVerifyFlags>();
- return GetField<int8_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int8_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags>
@@ -391,7 +392,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<uint8_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<uint8_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive,
@@ -407,7 +408,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int8_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int8_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -425,13 +426,13 @@
template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
inline uint16_t Object::GetFieldChar(MemberOffset field_offset) {
Verify<kVerifyFlags>();
- return GetField<uint16_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<uint16_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags, bool kIsVolatile>
inline int16_t Object::GetFieldShort(MemberOffset field_offset) {
Verify<kVerifyFlags>();
- return GetField<int16_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int16_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags>
@@ -457,7 +458,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<uint16_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<uint16_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive,
@@ -473,7 +474,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int16_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int16_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -501,7 +502,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int32_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int32_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -531,7 +532,7 @@
kIsVolatile);
}
Verify<kVerifyFlags>();
- SetField<int64_t, kIsVolatile>(field_offset, new_value);
+ SetFieldPrimitive<int64_t, kIsVolatile>(field_offset, new_value);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
@@ -867,7 +868,7 @@
// inheritance hierarchy and find reference offsets the hard way. In the static case, just
// consider this class.
for (ObjPtr<Class> klass = kIsStatic
- ? AsClass<kVerifyFlags, kReadBarrierOption>()
+ ? AsClass<kVerifyFlags>()
: GetClass<kVerifyFlags, kReadBarrierOption>();
klass != nullptr;
klass = kIsStatic ? nullptr : klass->GetSuperClass<kVerifyFlags, kReadBarrierOption>()) {
diff --git a/runtime/mirror/object-readbarrier-inl.h b/runtime/mirror/object-readbarrier-inl.h
index cc375bd..8689e4d 100644
--- a/runtime/mirror/object-readbarrier-inl.h
+++ b/runtime/mirror/object-readbarrier-inl.h
@@ -131,7 +131,7 @@
UNREACHABLE();
}
DCHECK(kUseBakerReadBarrier);
- LockWord lw(GetField<uint32_t, /*kIsVolatile*/false>(MonitorOffset()));
+ LockWord lw(GetFieldPrimitive<uint32_t, /*kIsVolatile*/false>(MonitorOffset()));
uint32_t rb_state = lw.ReadBarrierState();
DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state;
return rb_state;
diff --git a/runtime/mirror/object-refvisitor-inl.h b/runtime/mirror/object-refvisitor-inl.h
index 39e32bf..bd23971 100644
--- a/runtime/mirror/object-refvisitor-inl.h
+++ b/runtime/mirror/object-refvisitor-inl.h
@@ -39,7 +39,7 @@
if (LIKELY(class_flags == kClassFlagNormal)) {
DCHECK((!klass->IsVariableSize<kVerifyFlags, kReadBarrierOption>()));
VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor);
- DCHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
+ DCHECK((!klass->IsClassClass<kVerifyFlags>()));
DCHECK(!klass->IsStringClass());
DCHECK(!klass->IsClassLoaderClass());
DCHECK((!klass->IsArrayClass<kVerifyFlags, kReadBarrierOption>()));
@@ -47,8 +47,8 @@
if ((class_flags & kClassFlagNoReferenceFields) == 0) {
DCHECK(!klass->IsStringClass());
if (class_flags == kClassFlagClass) {
- DCHECK((klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
- ObjPtr<Class> as_klass = AsClass<kVerifyNone, kReadBarrierOption>();
+ DCHECK((klass->IsClassClass<kVerifyFlags>()));
+ ObjPtr<Class> as_klass = AsClass<kVerifyNone>();
as_klass->VisitReferences<kVisitNativeRoots, kVerifyFlags, kReadBarrierOption>(klass,
visitor);
} else if (class_flags == kClassFlagObjectArray) {
@@ -69,7 +69,7 @@
kReadBarrierOption>(klass, visitor);
}
} else if (kIsDebugBuild) {
- CHECK((!klass->IsClassClass<kVerifyFlags, kReadBarrierOption>()));
+ CHECK((!klass->IsClassClass<kVerifyFlags>()));
CHECK((!klass->IsObjectArrayClass<kVerifyFlags, kReadBarrierOption>()));
// String still has instance fields for reflection purposes but these don't exist in
// actual string instances.
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 47aded3..48ce5c1 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -169,11 +169,9 @@
void NotifyAll(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
void Wait(Thread* self, int64_t timeout, int32_t nanos) REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsClass() REQUIRES_SHARED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Class* AsClass() REQUIRES_SHARED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
@@ -349,11 +347,35 @@
HeapReference<Object>* GetFieldObjectReferenceAddr(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_);
+ template<typename kType, bool kIsVolatile>
+ ALWAYS_INLINE void SetFieldPrimitive(MemberOffset field_offset, kType new_value)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
+ kType* addr = reinterpret_cast<kType*>(raw_addr);
+ if (kIsVolatile) {
+ reinterpret_cast<Atomic<kType>*>(addr)->store(new_value, std::memory_order_seq_cst);
+ } else {
+ reinterpret_cast<Atomic<kType>*>(addr)->StoreJavaData(new_value);
+ }
+ }
+
+ template<typename kType, bool kIsVolatile>
+ ALWAYS_INLINE kType GetFieldPrimitive(MemberOffset field_offset)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
+ const kType* addr = reinterpret_cast<const kType*>(raw_addr);
+ if (kIsVolatile) {
+ return reinterpret_cast<const Atomic<kType>*>(addr)->load(std::memory_order_seq_cst);
+ } else {
+ return reinterpret_cast<const Atomic<kType>*>(addr)->LoadJavaData();
+ }
+ }
+
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
ALWAYS_INLINE uint8_t GetFieldBoolean(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
Verify<kVerifyFlags>();
- return GetField<uint8_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<uint8_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, bool kIsVolatile = false>
@@ -440,7 +462,7 @@
ALWAYS_INLINE int32_t GetField32(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
Verify<kVerifyFlags>();
- return GetField<int32_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int32_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -482,7 +504,7 @@
ALWAYS_INLINE int64_t GetField64(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_) {
Verify<kVerifyFlags>();
- return GetField<int64_t, kIsVolatile>(field_offset);
+ return GetFieldPrimitive<int64_t, kIsVolatile>(field_offset);
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -683,30 +705,6 @@
REQUIRES_SHARED(Locks::mutator_lock_);
private:
- template<typename kSize, bool kIsVolatile>
- ALWAYS_INLINE void SetField(MemberOffset field_offset, kSize new_value)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- kSize* addr = reinterpret_cast<kSize*>(raw_addr);
- if (kIsVolatile) {
- reinterpret_cast<Atomic<kSize>*>(addr)->store(new_value, std::memory_order_seq_cst);
- } else {
- reinterpret_cast<Atomic<kSize>*>(addr)->StoreJavaData(new_value);
- }
- }
-
- template<typename kSize, bool kIsVolatile>
- ALWAYS_INLINE kSize GetField(MemberOffset field_offset)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- const uint8_t* raw_addr = reinterpret_cast<const uint8_t*>(this) + field_offset.Int32Value();
- const kSize* addr = reinterpret_cast<const kSize*>(raw_addr);
- if (kIsVolatile) {
- return reinterpret_cast<const Atomic<kSize>*>(addr)->load(std::memory_order_seq_cst);
- } else {
- return reinterpret_cast<const Atomic<kSize>*>(addr)->LoadJavaData();
- }
- }
-
// Get a field with acquire semantics.
template<typename kSize>
ALWAYS_INLINE kSize GetFieldAcquire(MemberOffset field_offset)
diff --git a/runtime/monitor_test.cc b/runtime/monitor_test.cc
index c88748f..0b168f8 100644
--- a/runtime/monitor_test.cc
+++ b/runtime/monitor_test.cc
@@ -62,7 +62,7 @@
monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
expected_(expected) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
{
ScopedObjectAccess soa(self);
@@ -118,7 +118,7 @@
}
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
@@ -136,7 +136,7 @@
monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis),
expected_(expected) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
{
@@ -158,7 +158,7 @@
monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
@@ -174,7 +174,7 @@
InterruptTask(MonitorTest* monitor_test, uint64_t initial_sleep, uint64_t millis) :
monitor_test_(monitor_test), initial_sleep_(initial_sleep), millis_(millis) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
monitor_test_->barrier_->Wait(self); // Wait for the other thread to set up the monitor.
{
@@ -202,7 +202,7 @@
monitor_test_->complete_barrier_->Wait(self); // Wait for test completion.
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
@@ -216,7 +216,7 @@
public:
explicit WatchdogTask(MonitorTest* monitor_test) : monitor_test_(monitor_test) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
ScopedObjectAccess soa(self);
monitor_test_->watchdog_object_.Get()->MonitorEnter(self); // Lock the object.
@@ -231,7 +231,7 @@
}
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
@@ -326,14 +326,14 @@
public:
explicit TryLockTask(Handle<mirror::Object> obj) : obj_(obj) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
ScopedObjectAccess soa(self);
// Lock is held by other thread, try lock should fail.
ObjectTryLock<mirror::Object> lock(self, obj_);
EXPECT_FALSE(lock.Acquired());
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc
index 3919227..e3932df 100644
--- a/runtime/native/dalvik_system_VMStack.cc
+++ b/runtime/native/dalvik_system_VMStack.cc
@@ -113,7 +113,7 @@
: StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
class_loader(nullptr) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(class_loader == nullptr);
ObjPtr<mirror::Class> c = GetMethod()->GetDeclaringClass();
// c is null for runtime methods.
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 5a5fb16..f5039d1 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -62,7 +62,7 @@
caller(nullptr) {
}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod *m = GetMethod();
if (m == nullptr) {
// Attached native thread. Assume this is *not* boot class path.
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index efdefb1..3a974df 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -1148,7 +1148,7 @@
loaded_oat_file_(nullptr)
{}
- void Run(Thread* self ATTRIBUTE_UNUSED) {
+ void Run(Thread* self ATTRIBUTE_UNUSED) override {
// Load the dex files, and save a pointer to the loaded oat file, so that
// we can verify only one oat file was loaded for the dex location.
std::vector<std::unique_ptr<const DexFile>> dex_files;
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 7b92151..e882e73 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -165,7 +165,7 @@
CHECK_NE(frame_depth_, kInvalidFrameDepth);
}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
size_t current_frame_depth = GetFrameDepth();
if (current_frame_depth < frame_depth_) {
CHECK(GetMethod() != nullptr);
diff --git a/runtime/reflection_test.cc b/runtime/reflection_test.cc
index 424ee06..00e298e 100644
--- a/runtime/reflection_test.cc
+++ b/runtime/reflection_test.cc
@@ -33,7 +33,7 @@
// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
class ReflectionTest : public CommonCompilerTest {
protected:
- virtual void SetUp() {
+ void SetUp() override {
CommonCompilerTest::SetUp();
vm_ = Runtime::Current()->GetJavaVM();
@@ -73,7 +73,7 @@
}
}
- virtual void TearDown() {
+ void TearDown() override {
CleanUpJniEnv();
CommonCompilerTest::TearDown();
}
diff --git a/runtime/runtime_callbacks_test.cc b/runtime/runtime_callbacks_test.cc
index aaedb23..89f3124 100644
--- a/runtime/runtime_callbacks_test.cc
+++ b/runtime/runtime_callbacks_test.cc
@@ -458,20 +458,20 @@
ref_ = { &k->GetDexFile(), k->GetDexClassDefIndex() };
}
- void MonitorContendedLocking(Monitor* mon ATTRIBUTE_UNUSED)
+ void MonitorContendedLocking(Monitor* mon ATTRIBUTE_UNUSED) override
REQUIRES_SHARED(Locks::mutator_lock_) { }
- void MonitorContendedLocked(Monitor* mon ATTRIBUTE_UNUSED)
+ void MonitorContendedLocked(Monitor* mon ATTRIBUTE_UNUSED) override
REQUIRES_SHARED(Locks::mutator_lock_) { }
- void ObjectWaitStart(Handle<mirror::Object> obj, int64_t millis ATTRIBUTE_UNUSED)
+ void ObjectWaitStart(Handle<mirror::Object> obj, int64_t millis ATTRIBUTE_UNUSED) override
REQUIRES_SHARED(Locks::mutator_lock_) {
if (IsInterestingObject(obj.Get())) {
saw_wait_start_ = true;
}
}
- void MonitorWaitFinished(Monitor* m, bool timed_out ATTRIBUTE_UNUSED)
+ void MonitorWaitFinished(Monitor* m, bool timed_out ATTRIBUTE_UNUSED) override
REQUIRES_SHARED(Locks::mutator_lock_) {
if (IsInterestingObject(m->GetObject())) {
saw_wait_finished_ = true;
diff --git a/runtime/subtype_check_info_test.cc b/runtime/subtype_check_info_test.cc
index e40bca5..5323093 100644
--- a/runtime/subtype_check_info_test.cc
+++ b/runtime/subtype_check_info_test.cc
@@ -86,11 +86,11 @@
struct SubtypeCheckInfoTest : public ::testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
android::base::InitLogging(/*argv*/nullptr);
}
- virtual void TearDown() {
+ void TearDown() override {
}
static SubtypeCheckInfo MakeSubtypeCheckInfo(BitString path_to_root = {},
diff --git a/runtime/subtype_check_test.cc b/runtime/subtype_check_test.cc
index 666bf81..9aa3032 100644
--- a/runtime/subtype_check_test.cc
+++ b/runtime/subtype_check_test.cc
@@ -301,13 +301,13 @@
struct SubtypeCheckTest : public ::testing::Test {
protected:
- virtual void SetUp() {
+ void SetUp() override {
android::base::InitLogging(/*argv*/nullptr);
CreateRootedTree(BitString::kCapacity + 2u, BitString::kCapacity + 2u);
}
- virtual void TearDown() {
+ void TearDown() override {
}
void CreateRootedTree(size_t width, size_t height) {
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 19fe4ea..8a8f537 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -2515,7 +2515,7 @@
saved_frames_(saved_frames),
max_saved_frames_(max_saved_frames) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
// We want to skip frames up to and including the exception's constructor.
// Note we also skip the frame if it doesn't have a method (namely the callee
// save frame)
@@ -2603,7 +2603,7 @@
self_->EndAssertNoThreadSuspension(nullptr);
}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
if (trace_ == nullptr) {
return true; // We're probably trying to fillInStackTrace for an OutOfMemoryError.
}
@@ -3520,7 +3520,7 @@
: StackVisitor(thread, context, StackVisitor::StackWalkKind::kSkipInlinedFrames),
visitor_(visitor) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
if (false) {
LOG(INFO) << "Visiting stack roots in " << ArtMethod::PrettyMethod(GetMethod())
<< StringPrintf("@ PC:%04x", GetDexPc());
diff --git a/runtime/thread_pool_test.cc b/runtime/thread_pool_test.cc
index d784200..2600f55 100644
--- a/runtime/thread_pool_test.cc
+++ b/runtime/thread_pool_test.cc
@@ -29,7 +29,7 @@
public:
explicit CountTask(AtomicInteger* count) : count_(count), verbose_(false) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
if (verbose_) {
LOG(INFO) << "Running: " << *self;
}
@@ -39,7 +39,7 @@
++*count_;
}
- void Finalize() {
+ void Finalize() override {
if (verbose_) {
LOG(INFO) << "Finalizing: " << *Thread::Current();
}
@@ -129,7 +129,7 @@
count_(count),
depth_(depth) {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
if (depth_ > 1) {
thread_pool_->AddTask(self, new TreeTask(thread_pool_, count_, depth_ - 1));
thread_pool_->AddTask(self, new TreeTask(thread_pool_, count_, depth_ - 1));
@@ -138,7 +138,7 @@
++*count_;
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
@@ -164,12 +164,12 @@
public:
PeerTask() {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
ScopedObjectAccess soa(self);
CHECK(self->GetPeer() != nullptr);
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
};
@@ -178,12 +178,12 @@
public:
NoPeerTask() {}
- void Run(Thread* self) {
+ void Run(Thread* self) override {
ScopedObjectAccess soa(self);
CHECK(self->GetPeer() == nullptr);
}
- void Finalize() {
+ void Finalize() override {
delete this;
}
};
diff --git a/runtime/trace.cc b/runtime/trace.cc
index 949fabe..7e48bae 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -64,7 +64,7 @@
: StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
method_trace_(Trace::AllocStackTrace()) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
// Ignore runtime frames (in particular callee save).
if (!m->IsRuntimeMethod()) {
diff --git a/test/004-ReferenceMap/stack_walk_refmap_jni.cc b/test/004-ReferenceMap/stack_walk_refmap_jni.cc
index 1ce20e2..4c344a3 100644
--- a/test/004-ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/004-ReferenceMap/stack_walk_refmap_jni.cc
@@ -37,7 +37,7 @@
explicit ReferenceMap2Visitor(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_)
: CheckReferenceMapVisitor(thread) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
if (CheckReferenceMapVisitor::VisitFrame()) {
return true;
}
diff --git a/test/004-StackWalk/build b/test/004-StackWalk/build
index eeecbfc..3de541c 100644
--- a/test/004-StackWalk/build
+++ b/test/004-StackWalk/build
@@ -18,10 +18,8 @@
set -e
# This test depends on the exact format of the DEX file. Since dx is deprecated,
-# the classes.dex file is packaged as a test input. It was created with:
-#
-# $ javac -g -Xlint:-options -source 1.7 -target 1.7 -d classes src/Main.java
-# $ dx --debug --dex --output=classes.dex classes
+# the classes.dex file is packaged as a test input. See src/Main.java file
+# to check how it was created.
# Wrapper function for javac which for this test does nothing as the
# test uses a pre-built DEX file.
diff --git a/test/004-StackWalk/classes.dex b/test/004-StackWalk/classes.dex
index ad45296..61a7277 100644
--- a/test/004-StackWalk/classes.dex
+++ b/test/004-StackWalk/classes.dex
Binary files differ
diff --git a/test/004-StackWalk/src/Main.java b/test/004-StackWalk/src/Main.java
index 072b1d0..2a098f7 100644
--- a/test/004-StackWalk/src/Main.java
+++ b/test/004-StackWalk/src/Main.java
@@ -1,19 +1,36 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+// This test depends on the exact format of the DEX file. Since dx is deprecated,
+// the classes.dex file is packaged as a test input. It was created with:
+//
+// $ javac -g -Xlint:-options -source 1.7 -target 1.7 -d classes src/Main.java
+// $ dx --debug --dex --output=classes.dex classes
+
public class Main {
public Main() {
}
- boolean doThrow = false;
-
int $noinline$f() throws Exception {
- g(1);
- g(2);
-
- // This currently defeats inlining of `f`.
- if (doThrow) { throw new Error(); }
+ $noinline$g(1);
+ $noinline$g(2);
return 0;
}
- void g(int num_calls) {
+ void $noinline$g(int num_calls) {
if (num_calls == 1) {
System.out.println("1st call");
} else if (num_calls == 2) {
@@ -81,11 +98,14 @@
s4 = s18 = s19;
s += s4;
s += s18;
- stackmap(0);
- return s;
+ // Add a branch to workaround ART's large methods without branches heuristic.
+ if (testStackWalk(0) != 0) {
+ return s;
+ }
+ return s18;
}
- native int stackmap(int x);
+ native int testStackWalk(int x);
public static void main(String[] args) throws Exception {
System.loadLibrary(args[0]);
diff --git a/test/004-StackWalk/stack_walk_jni.cc b/test/004-StackWalk/stack_walk_jni.cc
index 89e2e66..81c27ec 100644
--- a/test/004-StackWalk/stack_walk_jni.cc
+++ b/test/004-StackWalk/stack_walk_jni.cc
@@ -20,7 +20,7 @@
namespace art {
-#define CHECK_REGS(...) do { \
+#define CHECK_REGS_ARE_REFERENCES(...) do { \
int t[] = {__VA_ARGS__}; \
int t_size = sizeof(t) / sizeof(*t); \
CheckReferences(t, t_size, GetNativePcOffset()); \
@@ -33,7 +33,7 @@
explicit TestReferenceMapVisitor(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_)
: CheckReferenceMapVisitor(thread) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
if (CheckReferenceMapVisitor::VisitFrame()) {
return true;
}
@@ -43,40 +43,50 @@
// Given the method name and the number of times the method has been called,
// we know the Dex registers with live reference values. Assert that what we
// find is what is expected.
- if (m_name == "f") {
+ if (m_name == "$noinline$f") {
if (gJava_StackWalk_refmap_calls == 1) {
CHECK_EQ(1U, GetDexPc());
- CHECK_REGS(4);
+ CHECK_REGS_ARE_REFERENCES(1);
} else {
CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
CHECK_EQ(5U, GetDexPc());
- CHECK_REGS(4);
+ CHECK_REGS_ARE_REFERENCES(1);
}
- } else if (m_name == "g") {
+ found_f_ = true;
+ } else if (m_name == "$noinline$g") {
if (gJava_StackWalk_refmap_calls == 1) {
CHECK_EQ(0xcU, GetDexPc());
- CHECK_REGS(0, 2); // Note that v1 is not in the minimal root set
+ CHECK_REGS_ARE_REFERENCES(0, 2); // Note that v1 is not in the minimal root set
} else {
CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
CHECK_EQ(0xcU, GetDexPc());
- CHECK_REGS(0, 2);
+ CHECK_REGS_ARE_REFERENCES(0, 2);
}
+ found_g_ = true;
} else if (m_name == "shlemiel") {
if (gJava_StackWalk_refmap_calls == 1) {
CHECK_EQ(0x380U, GetDexPc());
- CHECK_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
+ CHECK_REGS_ARE_REFERENCES(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
} else {
CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
CHECK_EQ(0x380U, GetDexPc());
- CHECK_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
+ CHECK_REGS_ARE_REFERENCES(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
}
+ found_shlemiel_ = true;
}
return true;
}
+
+ ~TestReferenceMapVisitor() {
+ }
+
+ bool found_f_ = false;
+ bool found_g_ = false;
+ bool found_shlemiel_ = false;
};
-extern "C" JNIEXPORT jint JNICALL Java_Main_stackmap(JNIEnv*, jobject, jint count) {
+extern "C" JNIEXPORT jint JNICALL Java_Main_testStackWalk(JNIEnv*, jobject, jint count) {
ScopedObjectAccess soa(Thread::Current());
CHECK_EQ(count, 0);
gJava_StackWalk_refmap_calls++;
@@ -84,17 +94,9 @@
// Visitor
TestReferenceMapVisitor mapper(soa.Self());
mapper.WalkStack();
-
- return count + 1;
-}
-
-extern "C" JNIEXPORT jint JNICALL Java_Main_refmap2(JNIEnv*, jobject, jint count) {
- ScopedObjectAccess soa(Thread::Current());
- gJava_StackWalk_refmap_calls++;
-
- // Visitor
- TestReferenceMapVisitor mapper(soa.Self());
- mapper.WalkStack();
+ CHECK(mapper.found_f_);
+ CHECK(mapper.found_g_);
+ CHECK(mapper.found_shlemiel_);
return count + 1;
}
diff --git a/test/454-get-vreg/get_vreg_jni.cc b/test/454-get-vreg/get_vreg_jni.cc
index 5fc5464..eb81f3b 100644
--- a/test/454-get-vreg/get_vreg_jni.cc
+++ b/test/454-get-vreg/get_vreg_jni.cc
@@ -34,7 +34,7 @@
this_value_(this_value),
found_method_index_(0) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
diff --git a/test/457-regs/regs_jni.cc b/test/457-regs/regs_jni.cc
index f867bdf..80abb3b 100644
--- a/test/457-regs/regs_jni.cc
+++ b/test/457-regs/regs_jni.cc
@@ -32,7 +32,7 @@
REQUIRES_SHARED(Locks::mutator_lock_)
: StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
diff --git a/test/461-get-reference-vreg/get_reference_vreg_jni.cc b/test/461-get-reference-vreg/get_reference_vreg_jni.cc
index 7eb3fe5..ddc86df 100644
--- a/test/461-get-reference-vreg/get_reference_vreg_jni.cc
+++ b/test/461-get-reference-vreg/get_reference_vreg_jni.cc
@@ -33,7 +33,7 @@
this_value_(this_value),
found_method_index_(0) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
diff --git a/test/466-get-live-vreg/get_live_vreg_jni.cc b/test/466-get-live-vreg/get_live_vreg_jni.cc
index 58ffe04..905d8e6 100644
--- a/test/466-get-live-vreg/get_live_vreg_jni.cc
+++ b/test/466-get-live-vreg/get_live_vreg_jni.cc
@@ -32,7 +32,7 @@
TestVisitor(Thread* thread, Context* context) REQUIRES_SHARED(Locks::mutator_lock_)
: StackVisitor(thread, context, StackVisitor::StackWalkKind::kIncludeInlinedFrames) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
diff --git a/test/543-env-long-ref/env_long_ref.cc b/test/543-env-long-ref/env_long_ref.cc
index ce5602f..165f5bf 100644
--- a/test/543-env-long-ref/env_long_ref.cc
+++ b/test/543-env-long-ref/env_long_ref.cc
@@ -34,7 +34,7 @@
found_(false),
soa_(soa) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
diff --git a/test/570-checker-osr/osr.cc b/test/570-checker-osr/osr.cc
index faec3c3..7b88842 100644
--- a/test/570-checker-osr/osr.cc
+++ b/test/570-checker-osr/osr.cc
@@ -35,7 +35,7 @@
in_osr_method_(false),
in_interpreter_(false) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
@@ -95,7 +95,7 @@
: StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
method_name_(method_name) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
@@ -129,7 +129,7 @@
: StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
method_name_(method_name) {}
- bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* m = GetMethod();
std::string m_name(m->GetName());
diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java
index ff6e335..4097e33 100644
--- a/test/623-checker-loop-regressions/src/Main.java
+++ b/test/623-checker-loop-regressions/src/Main.java
@@ -304,6 +304,19 @@
}
}
+ /// CHECK-START-ARM: void Main.$noinline$stringToShorts(short[], java.lang.String) loop_optimization (after)
+ /// CHECK-NOT: VecLoad
+
+ /// CHECK-START-ARM64: void Main.$noinline$stringToShorts(short[], java.lang.String) loop_optimization (after)
+ /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none
+ private static void $noinline$stringToShorts(short[] dest, String src) {
+ int min = Math.min(dest.length, src.length());
+ for (int i = 0; i < min; ++i) {
+ dest[i] = (short) src.charAt(i);
+ }
+ }
+
// A strange function that does not inline.
private static void $noinline$foo(boolean x, int n) {
if (n < 0)
@@ -684,6 +697,12 @@
expectEquals(aa[i], cc.charAt(i));
}
+ short[] s2s = new short[12];
+ $noinline$stringToShorts(s2s, "abcdefghijkl");
+ for (int i = 0; i < s2s.length; ++i) {
+ expectEquals((short) "abcdefghijkl".charAt(i), s2s[i]);
+ }
+
envUsesInCond();
short[] dd = new short[23];
diff --git a/test/669-moveable-string-class-equals/expected.txt b/test/669-moveable-string-class-equals/expected.txt
deleted file mode 100644
index 6a5618e..0000000
--- a/test/669-moveable-string-class-equals/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-JNI_OnLoad called
diff --git a/test/669-moveable-string-class-equals/info.txt b/test/669-moveable-string-class-equals/info.txt
deleted file mode 100644
index 1d3202ef..0000000
--- a/test/669-moveable-string-class-equals/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Regression test for String.equals() intrinsic instanceof check
-when the String.class is moveable.
diff --git a/test/669-moveable-string-class-equals/run b/test/669-moveable-string-class-equals/run
deleted file mode 100755
index 7c74d8c..0000000
--- a/test/669-moveable-string-class-equals/run
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2017 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.
-
-# Run without image, so that String.class is moveable.
-# Reduce heap size to force more frequent GCs.
-${RUN} --no-image --runtime-option -Xmx16m "$@"
diff --git a/test/669-moveable-string-class-equals/src/Main.java b/test/669-moveable-string-class-equals/src/Main.java
deleted file mode 100644
index d182d51..0000000
--- a/test/669-moveable-string-class-equals/src/Main.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2017 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) {
- System.loadLibrary(args[0]);
- if (!hasJit()) {
- // Make the test pass if not using JIT.
- return;
- }
- if (hasImage()) {
- throw new Error("The `run` script should prevent this test from running with an image!");
- }
- if (!isClassMoveable(String.class)) {
- throw new Error("String.class not moveable despite running without image!");
- }
-
- // Make sure the Main.test() is JIT-compiled and then call it.
- ensureJitCompiled(Main.class, "test");
- test();
- }
-
- public static void test() {
- int length = 5;
-
- // Hide the type of these strings in an Object array,
- // so that we treat them as Object for the String.equals() below.
- Object[] array = new Object[length];
- for (int i = 0; i != length; ++i) {
- array[i] = "V" + i;
- }
-
- // Continually check string equality between a newly allocated String and an
- // already allocated String with the same contents while allocating over 128MiB
- // memory (with heap size limited to 16MiB), ensuring we run GC and stress the
- // instanceof check in the String.equals() implementation.
- for (int count = 0; count != 128 * 1024; ++count) {
- for (int i = 0; i != length; ++i) {
- allocateAtLeast1KiB();
- assertTrue(("V" + i).equals(array[i]));
- }
- }
- }
-
- public static void allocateAtLeast1KiB() {
- // Give GC more work by allocating Object arrays.
- memory[allocationIndex] = new Object[1024 / 4];
- ++allocationIndex;
- if (allocationIndex == memory.length) {
- allocationIndex = 0;
- }
- }
-
- public static void assertTrue(boolean value) {
- if (!value) {
- throw new Error("Assertion failed!");
- }
- }
-
- private native static boolean hasJit();
- private native static boolean hasImage();
- private native static boolean isClassMoveable(Class<?> cls);
- private static native void ensureJitCompiled(Class<?> itf, String method_name);
-
- // We shall retain some allocated memory and release old allocations
- // so that the GC has something to do.
- public static Object[] memory = new Object[4096];
- public static int allocationIndex = 0;
-}
diff --git a/test/980-redefine-object/redef_object.cc b/test/980-redefine-object/redef_object.cc
index b4d82ad..a8393dc 100644
--- a/test/980-redefine-object/redef_object.cc
+++ b/test/980-redefine-object/redef_object.cc
@@ -80,13 +80,13 @@
public:
explicit JvmtiAllocator(jvmtiEnv* jvmti) : jvmti_(jvmti) {}
- void* Allocate(size_t size) {
+ void* Allocate(size_t size) override {
unsigned char* res = nullptr;
jvmti_->Allocate(size, &res);
return res;
}
- void Free(void* ptr) {
+ void Free(void* ptr) override {
jvmti_->Deallocate(reinterpret_cast<unsigned char*>(ptr));
}
diff --git a/test/Android.bp b/test/Android.bp
index e265651..4b61463 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -417,10 +417,11 @@
art_cc_defaults {
name: "libtistress-static-defaults",
- defaults: ["libtistress-srcs"],
- static_libs: art_static_dependencies + [
- "slicer",
+ defaults: [
+ "libtistress-srcs",
+ "libart_static_defaults",
],
+ static_libs: ["slicer"],
}
art_cc_test_library {
diff --git a/test/StackWalk2/StackWalk2.java b/test/StackWalk2/StackWalk2.java
deleted file mode 100644
index 5e7b22c..0000000
--- a/test/StackWalk2/StackWalk2.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2011 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 StackWalk2 {
- // use v1 for this
-
- String str = new String(); // use v0 for str in <init>
-
- int f() {
- g(1); // use v0 for 1, v1 for this
- g(2); // use v0 for 2, v1 for this
- strTest(); // use v1 for this
- return 0;
- }
-
- void g(int num_calls) throws RuntimeException {
- if (num_calls == 1) { // use v0 for 1, v3 for num_calls
- System.logI("1st call"); // use v0 for PrintStream, v1 for "1st call"
- refmap2(24); // use v0 for 24, v2 for this
- } else if (num_calls == 2) { // use v0 for 2, v3 for num_calls
- System.logI("2nd call"); // use v0 for PrintStream, v1 for "2nd call"
- refmap2(25); // use v0 for 24, v2 for this
- }
- throw new RuntimeException(); // use v0 for new RuntimeException
- }
-
- void strTest() {
- System.logI(str); // use v1 for PrintStream, v2, v3 for str
- str = null; // use v1 for null, v3 for str
- str = new String("ya"); // use v2 for "ya", v1 for new String
- String s = str; // use v0, v1, v3
- System.logI(str); // use v1 for PrintStream, v2, v3 for str
- System.logI(s); // use v1 for PrintStream, v0 for s
- s = null; // use v0
- System.logI(s); // use v1 for PrintStream, v0 for s
- }
-
- native int refmap2(int x);
-
- public static void main(String[] args) {
- System.loadLibrary(args[0]);
- StackWalk2 st = new StackWalk2();
- st.f();
- }
-}
diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc
index da79164..c9b789e 100644
--- a/test/common/runtime_state.cc
+++ b/test/common/runtime_state.cc
@@ -292,15 +292,6 @@
code_cache->GetProfiledMethods(unused_locations, unused_vector);
}
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_isClassMoveable(JNIEnv*,
- jclass,
- jclass cls) {
- Runtime* runtime = Runtime::Current();
- ScopedObjectAccess soa(Thread::Current());
- ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls);
- return runtime->GetHeap()->IsMovableObject(klass);
-}
-
extern "C" JNIEXPORT void JNICALL Java_Main_waitForCompilation(JNIEnv*, jclass) {
jit::Jit* jit = Runtime::Current()->GetJit();
if (jit != nullptr) {
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 6004f25..768bc79 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -697,9 +697,14 @@
"description": ["Tests that depend on input-vdex are not supported with compact dex"]
},
{
- "tests": "661-oat-writer-layout",
+ "tests": ["661-oat-writer-layout"],
"variant": "interp-ac | interpreter | jit | no-prebuild | no-image | trace | redefine-stress | jvmti-stress",
- "description": ["Test is designed to only check --compiler-filter=speed"]
+ "description": ["Test is designed to only check --optimizing"]
+ },
+ {
+ "tests": ["004-StackWalk"],
+ "variant": "interp-ac | interpreter | jit | no-prebuild | no-image | trace | redefine-stress | jvmti-stress | debuggable",
+ "description": ["Test is designed to only check --optimizing"]
},
{
"tests": "674-HelloWorld-Dm",
diff --git a/test/ti-stress/stress.cc b/test/ti-stress/stress.cc
index bd320c6..e123e9f 100644
--- a/test/ti-stress/stress.cc
+++ b/test/ti-stress/stress.cc
@@ -92,7 +92,7 @@
struct Allocator : public dex::Writer::Allocator {
explicit Allocator(jvmtiEnv* jvmti_env) : jvmti_env_(jvmti_env) {}
- virtual void* Allocate(size_t size) {
+ void* Allocate(size_t size) override {
unsigned char* out = nullptr;
if (JVMTI_ERROR_NONE != jvmti_env_->Allocate(size, &out)) {
return nullptr;
@@ -100,7 +100,7 @@
return out;
}
}
- virtual void Free(void* ptr) {
+ void Free(void* ptr) override {
jvmti_env_->Deallocate(reinterpret_cast<unsigned char*>(ptr));
}
private:
diff --git a/tools/ahat/etc/ahat_api.txt b/tools/ahat/etc/ahat_api.txt
index 5426f7b..7aa994a 100644
--- a/tools/ahat/etc/ahat_api.txt
+++ b/tools/ahat/etc/ahat_api.txt
@@ -96,6 +96,7 @@
method public boolean isArrayInstance();
method public boolean isClassInstance();
method public boolean isClassObj();
+ method public boolean isInstanceOfClass(java.lang.String);
method public boolean isPlaceHolder();
method public boolean isRoot();
method public boolean isStronglyReachable();
@@ -226,6 +227,7 @@
method public int getLineNumber();
method public java.lang.String getMethodName();
method public void getObjects(java.lang.String, java.lang.String, java.util.Collection<com.android.ahat.heapdump.AhatInstance>);
+ method public void getObjects(java.util.function.Predicate<com.android.ahat.heapdump.AhatInstance>, java.util.function.Consumer<com.android.ahat.heapdump.AhatInstance>);
method public java.util.List<com.android.ahat.heapdump.Site.ObjectsInfo> getObjectsInfos();
method public com.android.ahat.heapdump.Site getParent();
method public java.lang.String getSignature();
diff --git a/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java b/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
index 1a8f018..81611b6 100644
--- a/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
+++ b/tools/ahat/src/main/com/android/ahat/ObjectsHandler.java
@@ -16,6 +16,7 @@
package com.android.ahat;
+import com.android.ahat.heapdump.AhatHeap;
import com.android.ahat.heapdump.AhatInstance;
import com.android.ahat.heapdump.AhatSnapshot;
import com.android.ahat.heapdump.Site;
@@ -24,6 +25,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.function.Predicate;
class ObjectsHandler implements AhatHandler {
private static final String OBJECTS_ID = "objects";
@@ -34,32 +36,102 @@
mSnapshot = snapshot;
}
+ /**
+ * Get the list of instances that match the given site, class, and heap
+ * filters. This method is public to facilitate testing.
+ *
+ * @param site the site to get instances from
+ * @param className non-null name of the class to restrict instances to.
+ * @param subclass if true, include instances of subclasses of the named class.
+ * @param heapName name of the heap to restrict instances to. May be null to
+ * allow instances on any heap.
+ * @return list of matching instances
+ */
+ public static List<AhatInstance> getObjects(
+ Site site, String className, boolean subclass, String heapName) {
+ Predicate<AhatInstance> predicate = (x) -> {
+ return (heapName == null || x.getHeap().getName().equals(heapName))
+ && (subclass ? x.isInstanceOfClass(className) : className.equals(x.getClassName()));
+ };
+
+ List<AhatInstance> insts = new ArrayList<AhatInstance>();
+ site.getObjects(predicate, x -> insts.add(x));
+ return insts;
+ }
+
@Override
public void handle(Doc doc, Query query) throws IOException {
int id = query.getInt("id", 0);
- String className = query.get("class", null);
+ String className = query.get("class", "java.lang.Object");
String heapName = query.get("heap", null);
+ boolean subclass = (query.getInt("subclass", 0) != 0);
Site site = mSnapshot.getSite(id);
- List<AhatInstance> insts = new ArrayList<AhatInstance>();
- site.getObjects(heapName, className, insts);
+ List<AhatInstance> insts = getObjects(site, className, subclass, heapName);
Collections.sort(insts, Sort.defaultInstanceCompare(mSnapshot));
- doc.title("Objects");
+ doc.title("Instances");
- SizeTable.table(doc, mSnapshot.isDiffed(),
- new Column("Heap"),
- new Column("Object"));
+ // Write a description of the current settings, with links to adjust the
+ // settings, such as:
+ // Site: ROOT -
+ // Class: android.os.Binder
+ // Subclasses: excluded (switch to included)
+ // Heap: any (switch to app, image, zygote)
+ // Count: 17,424
+ doc.descriptions();
+ doc.description(DocString.text("Site"), Summarizer.summarize(site));
+ doc.description(DocString.text("Class"), DocString.text(className));
- SubsetSelector<AhatInstance> selector = new SubsetSelector(query, OBJECTS_ID, insts);
- for (AhatInstance inst : selector.selected()) {
- AhatInstance base = inst.getBaseline();
- SizeTable.row(doc, inst.getSize(), base.getSize(),
- DocString.text(inst.getHeap().getName()),
- Summarizer.summarize(inst));
+ DocString subclassChoice = DocString.text(subclass ? "included" : "excluded");
+ subclassChoice.append(" (switch to ");
+ subclassChoice.appendLink(query.with("subclass", subclass ? 0 : 1),
+ DocString.text(subclass ? "excluded" : "included"));
+ subclassChoice.append(")");
+ doc.description(DocString.text("Subclasses"), subclassChoice);
+
+ DocString heapChoice = DocString.text(heapName == null ? "any" : heapName);
+ heapChoice.append(" (switch to ");
+ String comma = "";
+ for (AhatHeap heap : mSnapshot.getHeaps()) {
+ if (!heap.getName().equals(heapName)) {
+ heapChoice.append(comma);
+ heapChoice.appendLink(
+ query.with("heap", heap.getName()),
+ DocString.text(heap.getName()));
+ comma = ", ";
+ }
}
- SizeTable.end(doc);
- selector.render(doc);
+ if (heapName != null) {
+ heapChoice.append(comma);
+ heapChoice.appendLink(
+ query.with("heap", null),
+ DocString.text("any"));
+ }
+ heapChoice.append(")");
+ doc.description(DocString.text("Heap"), heapChoice);
+
+ doc.description(DocString.text("Count"), DocString.format("%,14d", insts.size()));
+ doc.end();
+ doc.println(DocString.text(""));
+
+ if (insts.isEmpty()) {
+ doc.println(DocString.text("(none)"));
+ } else {
+ SizeTable.table(doc, mSnapshot.isDiffed(),
+ new Column("Heap"),
+ new Column("Object"));
+
+ SubsetSelector<AhatInstance> selector = new SubsetSelector(query, OBJECTS_ID, insts);
+ for (AhatInstance inst : selector.selected()) {
+ AhatInstance base = inst.getBaseline();
+ SizeTable.row(doc, inst.getSize(), base.getSize(),
+ DocString.text(inst.getHeap().getName()),
+ Summarizer.summarize(inst));
+ }
+ SizeTable.end(doc);
+ selector.render(doc);
+ }
}
}
diff --git a/tools/ahat/src/main/com/android/ahat/Query.java b/tools/ahat/src/main/com/android/ahat/Query.java
index 9c2783c..5f064cd 100644
--- a/tools/ahat/src/main/com/android/ahat/Query.java
+++ b/tools/ahat/src/main/com/android/ahat/Query.java
@@ -79,7 +79,9 @@
/**
* Return a uri suitable for an href target that links to the current
* page, except with the named query parameter set to the new value.
- *
+ * <p>
+ * <code>value</code> may be null to remove the named query parameter.
+ * <p>
* The generated parameters will be sorted alphabetically so it is easier to
* test.
*/
@@ -92,11 +94,13 @@
params.put(name, value);
String and = "";
for (Map.Entry<String, String> entry : params.entrySet()) {
- newQuery.append(and);
- newQuery.append(entry.getKey());
- newQuery.append('=');
- newQuery.append(entry.getValue());
- and = "&";
+ if (entry.getValue() != null) {
+ newQuery.append(and);
+ newQuery.append(entry.getKey());
+ newQuery.append('=');
+ newQuery.append(entry.getValue());
+ and = "&";
+ }
}
return DocString.uri(newQuery.toString());
}
diff --git a/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java b/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java
index 4c60d8b..0511798 100644
--- a/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java
+++ b/tools/ahat/src/main/com/android/ahat/heapdump/AhatClassInstance.java
@@ -107,21 +107,6 @@
return new ReferenceIterator();
}
- /**
- * Returns true if this is an instance of a (subclass of a) class with the
- * given name.
- */
- private boolean isInstanceOfClass(String className) {
- AhatClassObj cls = getClassObj();
- while (cls != null) {
- if (className.equals(cls.getName())) {
- return true;
- }
- cls = cls.getSuperClassObj();
- }
- return false;
- }
-
@Override public String asString(int maxChars) {
if (!isInstanceOfClass("java.lang.String")) {
return null;
diff --git a/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java b/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java
index 3d691c7..c85a057 100644
--- a/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java
+++ b/tools/ahat/src/main/com/android/ahat/heapdump/AhatInstance.java
@@ -330,6 +330,25 @@
}
/**
+ * Returns true if this is an instance of a (subclass of a) class with the
+ * given name.
+ *
+ * @param className the name of the class to check for
+ * @return true if this is an instance of a (subclass of a) class with the
+ * given name
+ */
+ public boolean isInstanceOfClass(String className) {
+ AhatClassObj cls = getClassObj();
+ while (cls != null) {
+ if (className.equals(cls.getName())) {
+ return true;
+ }
+ cls = cls.getSuperClassObj();
+ }
+ return false;
+ }
+
+ /**
* Returns true if the given instance is an array instance.
*
* @return true if the given instance is an array instance
diff --git a/tools/ahat/src/main/com/android/ahat/heapdump/Site.java b/tools/ahat/src/main/com/android/ahat/heapdump/Site.java
index 46a1729..4f0660f 100644
--- a/tools/ahat/src/main/com/android/ahat/heapdump/Site.java
+++ b/tools/ahat/src/main/com/android/ahat/heapdump/Site.java
@@ -23,6 +23,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
/**
* Used to collection information about objects allocated at a particular
@@ -259,22 +261,37 @@
* every heap should be collected.
* @param className the name of the class the collected objects should
* belong to. This may be null to indicate objects of
- * every class should be collected.
+ * every class should be collected. Instances of subclasses
+ * of this class are not included.
* @param objects out parameter. A collection of objects that all
* collected objects should be added to.
*/
public void getObjects(String heapName, String className, Collection<AhatInstance> objects) {
+ Predicate<AhatInstance> predicate = x -> {
+ return (heapName == null || x.getHeap().getName().equals(heapName))
+ && (className == null || x.getClassName().equals(className));
+ };
+ getObjects(predicate, x -> objects.add(x));
+ }
+
+ /**
+ * Collects the objects allocated under this site, filtered by the given
+ * predicate.
+ * Includes objects allocated in children sites.
+ * @param predicate limit instances to those satisfying this predicate
+ * @param consumer consumer of the objects
+ */
+ public void getObjects(Predicate<AhatInstance> predicate, Consumer<AhatInstance> consumer) {
for (AhatInstance inst : mObjects) {
- if ((heapName == null || inst.getHeap().getName().equals(heapName))
- && (className == null || inst.getClassName().equals(className))) {
- objects.add(inst);
+ if (predicate.test(inst)) {
+ consumer.accept(inst);
}
}
// Recursively visit children. Recursion should be okay here because the
// stack depth is limited by a reasonable amount (128 frames or so).
for (Site child : mChildren) {
- child.getObjects(heapName, className, objects);
+ child.getObjects(predicate, consumer);
}
}
diff --git a/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java b/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java
index 3aa52b5..abc3cc7 100644
--- a/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java
+++ b/tools/ahat/src/test/com/android/ahat/AhatTestSuite.java
@@ -29,6 +29,7 @@
InstanceTest.class,
NativeAllocationTest.class,
ObjectHandlerTest.class,
+ ObjectsHandlerTest.class,
OverviewHandlerTest.class,
PerformanceTest.class,
ProguardMapTest.class,
diff --git a/tools/ahat/src/test/com/android/ahat/ObjectsHandlerTest.java b/tools/ahat/src/test/com/android/ahat/ObjectsHandlerTest.java
new file mode 100644
index 0000000..927e017
--- /dev/null
+++ b/tools/ahat/src/test/com/android/ahat/ObjectsHandlerTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package com.android.ahat;
+
+import com.android.ahat.heapdump.AhatInstance;
+import com.android.ahat.heapdump.AhatSnapshot;
+import com.android.ahat.heapdump.Site;
+import java.io.IOException;
+import java.util.List;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ObjectsHandlerTest {
+ @Test
+ public void getObjects() throws IOException {
+ TestDump dump = TestDump.getTestDump();
+ AhatSnapshot snapshot = dump.getAhatSnapshot();
+
+ Site root = snapshot.getRootSite();
+
+ // We expect a single instance of DumpedStuff
+ List<AhatInstance> dumped = ObjectsHandler.getObjects(
+ root, "DumpedStuff", /* subclass */ false, /* heapName */ null);
+ assertEquals(1, dumped.size());
+ assertTrue(dumped.get(0).getClassName().equals("DumpedStuff"));
+
+ // We expect no direct instances of SuperDumpedStuff
+ List<AhatInstance> direct = ObjectsHandler.getObjects(
+ root, "SuperDumpedStuff", /* subclass */ false, /* heapName */ null);
+ assertTrue(direct.isEmpty());
+
+ // We expect one subclass instance of SuperDumpedStuff
+ List<AhatInstance> subclass = ObjectsHandler.getObjects(
+ root, "SuperDumpedStuff", /* subclass */ true, /* heapName */ null);
+ assertEquals(1, subclass.size());
+ assertTrue(subclass.get(0).getClassName().equals("DumpedStuff"));
+ assertEquals(dumped.get(0), subclass.get(0));
+ }
+}
diff --git a/tools/ahat/src/test/com/android/ahat/QueryTest.java b/tools/ahat/src/test/com/android/ahat/QueryTest.java
index 5bcf8ea..52cf963 100644
--- a/tools/ahat/src/test/com/android/ahat/QueryTest.java
+++ b/tools/ahat/src/test/com/android/ahat/QueryTest.java
@@ -41,6 +41,7 @@
assertEquals("/object?answer=43&foo=bar", query.with("answer", "43").toString());
assertEquals("/object?answer=43&foo=bar", query.with("answer", 43).toString());
assertEquals("/object?answer=42&bar=finally&foo=bar", query.with("bar", "finally").toString());
+ assertEquals("/object?answer=42", query.with("foo", null).toString());
}
@Test
@@ -55,6 +56,7 @@
assertEquals("/object?answer=43&foo=sludge", query.with("answer", "43").toString());
assertEquals("/object?answer=42&bar=finally&foo=sludge",
query.with("bar", "finally").toString());
+ assertEquals("/object?answer=42", query.with("foo", null).toString());
}
@Test
@@ -66,5 +68,6 @@
assertEquals(2, query.getInt("foo", 2));
assertEquals("/object?foo=sludge", query.with("foo", "sludge").toString());
assertEquals("/object?answer=43", query.with("answer", "43").toString());
+ assertEquals("/object?", query.with("foo", null).toString());
}
}
diff --git a/tools/amm/Android.bp b/tools/amm/Android.bp
new file mode 100644
index 0000000..e6f6ff7
--- /dev/null
+++ b/tools/amm/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2017 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.
+
+// --- ammtestjni.so -------------
+
+cc_library_shared {
+ name: "libammtestjni",
+
+ srcs: [
+ "AmmTest/jni/ammtest.c",
+ ],
+
+ sdk_version: "current",
+}
diff --git a/tools/amm/Android.mk b/tools/amm/Android.mk
index 47030c5..fa4ca44 100644
--- a/tools/amm/Android.mk
+++ b/tools/amm/Android.mk
@@ -14,13 +14,6 @@
LOCAL_PATH := $(call my-dir)
-# --- ammtestjni.so -------------
-include $(CLEAR_VARS)
-LOCAL_MODULE := libammtestjni
-LOCAL_SRC_FILES := $(call all-c-files-under, AmmTest/jni)
-LOCAL_SDK_VERSION := current
-include $(BUILD_SHARED_LIBRARY)
-
# --- AmmTest.apk --------------
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := AmmTest
@@ -31,4 +24,3 @@
LOCAL_JAVA_RESOURCE_FILES := $(LOCAL_PATH)/AmmTest/aahat.png
LOCAL_MANIFEST_FILE := AmmTest/AndroidManifest.xml
include $(BUILD_PACKAGE)
-
diff --git a/tools/art_verifier/Android.bp b/tools/art_verifier/Android.bp
index afd52fb..6fff27a 100644
--- a/tools/art_verifier/Android.bp
+++ b/tools/art_verifier/Android.bp
@@ -16,7 +16,10 @@
art_cc_defaults {
name: "art_verifier-defaults",
- defaults: ["art_defaults"],
+ defaults: [
+ "art_defaults",
+ "libart_static_defaults",
+ ],
host_supported: true,
srcs: [
"art_verifier.cc",
@@ -24,11 +27,8 @@
header_libs: [
"art_cmdlineparser_headers",
],
- static_libs: art_static_dependencies + [
- "libart",
- "libartbase",
- "libdexfile",
- "libprofile",
+ static_libs: [
+ "libsigchain_dummy",
],
target: {
android: {
diff --git a/tools/art_verifier/art_verifier.cc b/tools/art_verifier/art_verifier.cc
index 8f412bf..45c1a33 100644
--- a/tools/art_verifier/art_verifier.cc
+++ b/tools/art_verifier/art_verifier.cc
@@ -137,7 +137,7 @@
return kParseOk;
}
- virtual std::string GetUsage() const {
+ std::string GetUsage() const override {
std::string usage;
usage +=
diff --git a/tools/buildbot-build.sh b/tools/buildbot-build.sh
index 8305051..b5d39e1 100755
--- a/tools/buildbot-build.sh
+++ b/tools/buildbot-build.sh
@@ -68,15 +68,15 @@
make_command+=" dx-tests"
mode_suffix="-host"
elif [[ $mode == "target" ]]; then
- if [[ -z "$TARGET_PRODUCT" ]]; then
- echo 'TARGET_PRODUCT environment variable is empty; did you forget to run `lunch`?'
+ if [[ -z "${ANDROID_PRODUCT_OUT}" ]]; then
+ echo 'ANDROID_PRODUCT_OUT environment variable is empty; did you forget to run `lunch`?'
exit 1
fi
make_command="make $j_arg $extra_args $showcommands build-art-target-tests $common_targets"
make_command+=" libjavacrypto-target libnetd_client-target linker toybox toolbox sh"
make_command+=" debuggerd su"
make_command+=" ${out_dir}/host/linux-x86/bin/adb libstdc++ "
- make_command+=" ${out_dir}/target/product/${TARGET_PRODUCT}/system/etc/public.libraries.txt"
+ make_command+=" ${ANDROID_PRODUCT_OUT#"${ANDROID_BUILD_TOP}/"}/system/etc/public.libraries.txt"
if [[ -n "$ART_TEST_CHROOT" ]]; then
# These targets are needed for the chroot environment.
make_command+=" crash_dump event-log-tags"
diff --git a/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java b/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java
index 9262076..53157a3 100644
--- a/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java
+++ b/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java
@@ -33,10 +33,12 @@
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -71,9 +73,10 @@
.hasArgs()
.withDescription(
"Specify file to write greylist to. Can be specified multiple times. " +
- "Format is either just a filename, or \"int:filename\". If an integer is " +
- "given, members with a matching maxTargetSdk are written to the file; if " +
- "no integer is given, members with no maxTargetSdk are written.")
+ "Format is either just a filename, or \"int[,int,...]:filename\". If " +
+ "integers are given, members with matching maxTargetSdk values are " +
+ "written to the file; if no integer or \"none\" is given, members with " +
+ "no maxTargetSdk are written.")
.create("g"));
options.addOption(OptionBuilder
.withLongOpt("write-whitelist")
@@ -204,15 +207,22 @@
static Map<Integer, String> readGreylistMap(Status status, String[] argValues) {
Map<Integer, String> map = new HashMap<>();
for (String sdkFile : argValues) {
- Integer maxTargetSdk = null;
+ List<Integer> maxTargetSdks = new ArrayList<>();
String filename;
int colonPos = sdkFile.indexOf(':');
if (colonPos != -1) {
- try {
- maxTargetSdk = Integer.valueOf(sdkFile.substring(0, colonPos));
- } catch (NumberFormatException nfe) {
- status.error("Not a valid integer: %s from argument value '%s'",
- sdkFile.substring(0, colonPos), sdkFile);
+ String[] targets = sdkFile.substring(0, colonPos).split(",");
+ for (String target : targets) {
+ if ("none".equals(target)) {
+ maxTargetSdks.add(null);
+ } else {
+ try {
+ maxTargetSdks.add(Integer.valueOf(target));
+ } catch (NumberFormatException nfe) {
+ status.error("Not a valid integer: %s from argument value '%s'",
+ sdkFile.substring(0, colonPos), sdkFile);
+ }
+ }
}
filename = sdkFile.substring(colonPos + 1);
if (filename.length() == 0) {
@@ -220,13 +230,16 @@
filename, sdkFile);
}
} else {
- maxTargetSdk = null;
+ maxTargetSdks.add(null);
filename = sdkFile;
}
- if (map.containsKey(maxTargetSdk)) {
- status.error("Multiple output files for maxTargetSdk %s", maxTargetSdk);
- } else {
- map.put(maxTargetSdk, filename);
+ for (Integer maxTargetSdk : maxTargetSdks) {
+ if (map.containsKey(maxTargetSdk)) {
+ status.error("Multiple output files for maxTargetSdk %s",
+ maxTargetSdk == null ? "none" : maxTargetSdk);
+ } else {
+ map.put(maxTargetSdk, filename);
+ }
}
}
return map;
diff --git a/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java b/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java
index 9f33467..bfd2310 100644
--- a/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java
+++ b/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java
@@ -1,5 +1,7 @@
package com.android.class2greylist;
+import com.google.common.annotations.VisibleForTesting;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@@ -20,11 +22,16 @@
return new PrintStream(new FileOutputStream(new File(filename)));
}
- private static Map<Integer, PrintStream> openFiles(
+ @VisibleForTesting
+ public static Map<Integer, PrintStream> openFiles(
Map<Integer, String> filenames) throws FileNotFoundException {
+ Map<String, PrintStream> streamsByName = new HashMap<>();
Map<Integer, PrintStream> streams = new HashMap<>();
for (Map.Entry<Integer, String> entry : filenames.entrySet()) {
- streams.put(entry.getKey(), openFile(entry.getValue()));
+ if (!streamsByName.containsKey(entry.getValue())) {
+ streamsByName.put(entry.getValue(), openFile(entry.getValue()));
+ }
+ streams.put(entry.getKey(), streamsByName.get(entry.getValue()));
}
return streams;
}
diff --git a/tools/class2greylist/test/src/com/android/class2greylist/Class2GreylistTest.java b/tools/class2greylist/test/src/com/android/class2greylist/Class2GreylistTest.java
index cb75dd3..b87a5b1 100644
--- a/tools/class2greylist/test/src/com/android/class2greylist/Class2GreylistTest.java
+++ b/tools/class2greylist/test/src/com/android/class2greylist/Class2GreylistTest.java
@@ -56,6 +56,31 @@
}
@Test
+ public void testReadGreylistMapNone() throws IOException {
+ Map<Integer, String> map = Class2Greylist.readGreylistMap(mStatus,
+ new String[]{"none:noApi"});
+ verifyZeroInteractions(mStatus);
+ assertThat(map).containsExactly(null, "noApi");
+ }
+
+ @Test
+ public void testReadGreylistMapMulti() throws IOException {
+ Map<Integer, String> map = Class2Greylist.readGreylistMap(mStatus,
+ new String[]{"1,none:noOr1Api", "3:apiThree"});
+ verifyZeroInteractions(mStatus);
+ assertThat(map).containsExactly(null, "noOr1Api", 1, "noOr1Api", 3, "apiThree");
+ }
+
+ @Test
+ public void testReadGreylistMapMulti2() throws IOException {
+ Map<Integer, String> map = Class2Greylist.readGreylistMap(mStatus,
+ new String[]{"1,none,2,3,4:allApi"});
+ verifyZeroInteractions(mStatus);
+ assertThat(map).containsExactly(
+ null, "allApi", 1, "allApi", 2, "allApi", 3, "allApi", 4, "allApi");
+ }
+
+ @Test
public void testReadGreylistMapDuplicate() throws IOException {
Class2Greylist.readGreylistMap(mStatus,
new String[]{"noApi", "1:apiOne", "1:anotherOne"});
diff --git a/tools/class2greylist/test/src/com/android/class2greylist/FileWritingGreylistConsumerTest.java b/tools/class2greylist/test/src/com/android/class2greylist/FileWritingGreylistConsumerTest.java
new file mode 100644
index 0000000..1e1b1df
--- /dev/null
+++ b/tools/class2greylist/test/src/com/android/class2greylist/FileWritingGreylistConsumerTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package com.android.class2greylist;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.mockito.Mock;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+public class FileWritingGreylistConsumerTest {
+
+ @Mock
+ Status mStatus;
+ @Rule
+ public TestName mTestName = new TestName();
+ private int mFileNameSeq = 0;
+ private final List<String> mTempFiles = new ArrayList<>();
+
+ @Before
+ public void setup() throws IOException {
+ System.out.println(String.format("\n============== STARTING TEST: %s ==============\n",
+ mTestName.getMethodName()));
+ initMocks(this);
+ }
+
+ @After
+ public void removeTempFiles() {
+ for (String name : mTempFiles) {
+ new File(name).delete();
+ }
+ }
+
+ private String tempFileName() {
+ String name = String.format(Locale.US, "/tmp/test-%s-%d",
+ mTestName.getMethodName(), mFileNameSeq++);
+ mTempFiles.add(name);
+ return name;
+ }
+
+ @Test
+ public void testSimpleMap() throws FileNotFoundException {
+ Map<Integer, PrintStream> streams = FileWritingGreylistConsumer.openFiles(
+ ImmutableMap.of(1, tempFileName(), 2, tempFileName()));
+ assertThat(streams.keySet()).containsExactly(1, 2);
+ assertThat(streams.get(1)).isNotNull();
+ assertThat(streams.get(2)).isNotNull();
+ assertThat(streams.get(2)).isNotSameAs(streams.get(1));
+ }
+
+ @Test
+ public void testCommonMappings() throws FileNotFoundException {
+ String name = tempFileName();
+ Map<Integer, PrintStream> streams = FileWritingGreylistConsumer.openFiles(
+ ImmutableMap.of(1, name, 2, name));
+ assertThat(streams.keySet()).containsExactly(1, 2);
+ assertThat(streams.get(1)).isNotNull();
+ assertThat(streams.get(2)).isSameAs(streams.get(1));
+ }
+}
diff --git a/tools/field-null-percent/check-null-fields.py b/tools/field-null-percent/check-null-fields.py
new file mode 100755
index 0000000..c11d51a
--- /dev/null
+++ b/tools/field-null-percent/check-null-fields.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 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.
+
+"""
+Retrieves the counts of how many objects have a particular field null on all running processes.
+
+Prints a json map from pid -> (log-tag, field-name, null-count, total-count).
+"""
+
+
+import adb
+import argparse
+import concurrent.futures
+import itertools
+import json
+import logging
+import os
+import os.path
+import signal
+import subprocess
+import time
+
+def main():
+ parser = argparse.ArgumentParser(description="Get counts of null fields from a device.")
+ parser.add_argument("-S", "--serial", metavar="SERIAL", type=str,
+ required=False,
+ default=os.environ.get("ANDROID_SERIAL", None),
+ help="Android serial to use. Defaults to ANDROID_SERIAL")
+ parser.add_argument("-p", "--pid", required=False,
+ default=[], action="append",
+ help="Specific pids to check. By default checks all running dalvik processes")
+ has_out = "OUT" in os.environ
+ def_32 = os.path.join(os.environ.get("OUT", ""), "system", "lib", "libfieldnull.so")
+ def_64 = os.path.join(os.environ.get("OUT", ""), "system", "lib64", "libfieldnull.so")
+ has_32 = has_out and os.path.exists(def_32)
+ has_64 = has_out and os.path.exists(def_64)
+ def pushable_lib(name):
+ if os.path.isfile(name):
+ return name
+ else:
+ raise argparse.ArgumentTypeError(name + " is not a file!")
+ parser.add_argument('--lib32', type=pushable_lib,
+ required=not has_32,
+ action='store',
+ default=def_32,
+ help="Location of 32 bit agent to push")
+ parser.add_argument('--lib64', type=pushable_lib,
+ required=not has_64,
+ action='store',
+ default=def_64 if has_64 else None,
+ help="Location of 64 bit agent to push")
+ parser.add_argument("fields", nargs="+",
+ help="fields to check")
+
+ out = parser.parse_args()
+
+ device = adb.device.get_device(out.serial)
+ print("getting root")
+ device.root()
+
+ print("Disabling selinux")
+ device.shell("setenforce 0".split())
+
+ print("Pushing libraries")
+ lib32 = device.shell("mktemp".split())[0].strip()
+ lib64 = device.shell("mktemp".split())[0].strip()
+
+ print(out.lib32 + " -> " + lib32)
+ device.push(out.lib32, lib32)
+
+ print(out.lib64 + " -> " + lib64)
+ device.push(out.lib64, lib64)
+
+ cmd32 = "'{}={}'".format(lib32, ','.join(out.fields))
+ cmd64 = "'{}={}'".format(lib64, ','.join(out.fields))
+
+ if len(out.pid) == 0:
+ print("Getting jdwp pids")
+ new_env = dict(os.environ)
+ new_env["ANDROID_SERIAL"] = device.serial
+ p = subprocess.Popen([device.adb_path, "jdwp"], env=new_env, stdout=subprocess.PIPE)
+ # ADB jdwp doesn't ever exit so just kill it after 1 second to get a list of pids.
+ with concurrent.futures.ProcessPoolExecutor() as ppe:
+ ppe.submit(kill_it, p.pid).result()
+ out.pid = p.communicate()[0].strip().split()
+ p.wait()
+ print(out.pid)
+ print("Clearing logcat")
+ device.shell("logcat -c".split())
+ final = {}
+ print("Getting info from every process dumped to logcat")
+ for p in out.pid:
+ res = check_single_process(p, device, cmd32, cmd64);
+ if res is not None:
+ final[p] = res
+ device.shell('rm {}'.format(lib32).split())
+ device.shell('rm {}'.format(lib64).split())
+ print(json.dumps(final, indent=2))
+
+def kill_it(p):
+ time.sleep(1)
+ os.kill(p, signal.SIGINT)
+
+def check_single_process(pid, device, bit32, bit64):
+ try:
+ # Just try attaching both 32 and 64 bit. Wrong one will fail silently.
+ device.shell(['am', 'attach-agent', str(pid), bit32])
+ device.shell(['am', 'attach-agent', str(pid), bit64])
+ time.sleep(0.5)
+ device.shell('kill -3 {}'.format(pid).split())
+ time.sleep(0.5)
+ out = []
+ all_fields = []
+ lc_cmd = "logcat -d -b main --pid={} -e '^\\t.*\\t[0-9]*\\t[0-9]*$'".format(pid).split(' ')
+ for l in device.shell(lc_cmd)[0].strip().split('\n'):
+ # first 4 are just date and other useless data.
+ data = l.strip().split()[5:]
+ if len(data) < 4:
+ continue
+ # If we run multiple times many copies of the agent will be attached. Just choose one of any
+ # copies for each field.
+ field = data[1]
+ if field not in all_fields:
+ out.append((str(data[0]), str(data[1]), int(data[2]), int(data[3])))
+ all_fields.append(field)
+ if len(out) != 0:
+ print("pid: " + pid + " -> " + str(out))
+ return out
+ else:
+ return None
+ except adb.device.ShellError as e:
+ print("failed on pid " + repr(pid) + " because " + repr(e))
+ return None
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/field-null-percent/fieldnull.cc b/tools/field-null-percent/fieldnull.cc
index 86459d2..1bd122a 100644
--- a/tools/field-null-percent/fieldnull.cc
+++ b/tools/field-null-percent/fieldnull.cc
@@ -147,7 +147,7 @@
delete list;
}
-static void CreateFieldList(jvmtiEnv* jvmti, JNIEnv* env, std::string args) {
+static void CreateFieldList(jvmtiEnv* jvmti, JNIEnv* env, const std::string& args) {
RequestList* list = nullptr;
CHECK_JVMTI(jvmti->Allocate(sizeof(*list), reinterpret_cast<unsigned char**>(&list)));
new (list) RequestList { .fields_ = GetRequestedFields(env, args), };
diff --git a/tools/libcore_gcstress_failures.txt b/tools/libcore_gcstress_failures.txt
index 965e85c..fff1c70 100644
--- a/tools/libcore_gcstress_failures.txt
+++ b/tools/libcore_gcstress_failures.txt
@@ -29,6 +29,7 @@
modes: [device],
names: ["libcore.java.lang.StringTest#testFastPathString_wellFormedUtf8Sequence",
"org.apache.harmony.tests.java.lang.ref.ReferenceQueueTest#test_remove",
+ "org.apache.harmony.tests.java.text.DateFormatTest#test_getAvailableLocales",
"org.apache.harmony.tests.java.util.TimerTest#testOverdueTaskExecutesImmediately",
"org.apache.harmony.tests.java.util.WeakHashMapTest#test_keySet_hasNext",
"libcore.java.text.DecimalFormatTest#testCurrencySymbolSpacing",
diff --git a/tools/titrace/instruction_decoder.cc b/tools/titrace/instruction_decoder.cc
index d8fb713..7f8b296 100644
--- a/tools/titrace/instruction_decoder.cc
+++ b/tools/titrace/instruction_decoder.cc
@@ -32,7 +32,7 @@
return Bytecode::ToString(op);
}
- virtual size_t LocationToOffset(size_t j_location) {
+ size_t LocationToOffset(size_t j_location) override {
return j_location;
}
@@ -474,7 +474,7 @@
return Bytecode::ToString(op);
}
- virtual size_t LocationToOffset(size_t j_location) {
+ size_t LocationToOffset(size_t j_location) override {
// dex pc is uint16_t*, but offset needs to be in bytes.
return j_location * (sizeof(uint16_t) / sizeof(uint8_t));
}
diff --git a/tools/veridex/hidden_api_finder.cc b/tools/veridex/hidden_api_finder.cc
index 4eba10e..d81f133 100644
--- a/tools/veridex/hidden_api_finder.cc
+++ b/tools/veridex/hidden_api_finder.cc
@@ -178,7 +178,8 @@
stats->linking_count = method_locations_.size() + field_locations_.size();
// Dump methods from hidden APIs linked against.
- for (const std::pair<std::string, std::vector<MethodReference>>& pair : method_locations_) {
+ for (const std::pair<const std::string,
+ std::vector<MethodReference>>& pair : method_locations_) {
HiddenApiAccessFlags::ApiList api_list = hidden_api_.GetApiList(pair.first);
stats->api_counts[api_list]++;
os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";
@@ -190,7 +191,8 @@
}
// Dump fields from hidden APIs linked against.
- for (const std::pair<std::string, std::vector<MethodReference>>& pair : field_locations_) {
+ for (const std::pair<const std::string,
+ std::vector<MethodReference>>& pair : field_locations_) {
HiddenApiAccessFlags::ApiList api_list = hidden_api_.GetApiList(pair.first);
stats->api_counts[api_list]++;
os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";