Merge "Replace ObjectSet with LargeObjectBitmap."
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index 055f60c..1847921 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -1586,7 +1586,7 @@
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_src2 = LoadValue(rl_src2, kCoreReg);
if (check_zero) {
- GenDivZeroCheck(rl_src2.reg);
+ GenDivZeroCheck(rl_src2.reg);
}
rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
done = true;
@@ -1597,7 +1597,7 @@
rl_src1 = LoadValue(rl_src1, kCoreReg);
rl_src2 = LoadValue(rl_src2, kCoreReg);
if (check_zero) {
- GenDivZeroCheck(rl_src2.reg);
+ GenDivZeroCheck(rl_src2.reg);
}
rl_result = GenDivRem(rl_dest, rl_src1.reg, rl_src2.reg, op == kOpDiv);
done = true;
diff --git a/compiler/dex/quick/mips/int_mips.cc b/compiler/dex/quick/mips/int_mips.cc
index ac0847f..60358b4 100644
--- a/compiler/dex/quick/mips/int_mips.cc
+++ b/compiler/dex/quick/mips/int_mips.cc
@@ -346,7 +346,7 @@
DCHECK(reg.IsPair()); // TODO: support k64BitSolo.
RegStorage t_reg = AllocTemp();
OpRegRegReg(kOpOr, t_reg, reg.GetLow(), reg.GetHigh());
- GenDivZeroCheck(kCondEq);
+ GenDivZeroCheck(t_reg);
FreeTemp(t_reg);
}
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc
index 8175c35..864dadc 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -50,7 +50,11 @@
CHECK(host_dir != NULL);
elf_filename = StringPrintf("%s/framework/core.oat", host_dir);
} else {
+#ifdef __LP64__
+ elf_filename = "/data/art-test64/core.oat";
+#else
elf_filename = "/data/art-test/core.oat";
+#endif
}
LOG(INFO) << "elf_filename=" << elf_filename;
diff --git a/runtime/monitor.h b/runtime/monitor.h
index c459278..0b80892 100644
--- a/runtime/monitor.h
+++ b/runtime/monitor.h
@@ -231,6 +231,10 @@
EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
private:
+ // During sweeping we may free an object and on a separate thread have an object created using
+ // the newly freed memory. That object may then have its lock-word inflated and a monitor created.
+ // If we allow new monitor registration during sweeping this monitor may be incorrectly freed as
+ // the object wasn't marked when sweeping began.
bool allow_new_monitors_ GUARDED_BY(monitor_list_lock_);
Mutex monitor_list_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
ConditionVariable monitor_add_condition_ GUARDED_BY(monitor_list_lock_);
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index eb0522a..611ce0b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1230,6 +1230,10 @@
void Runtime::AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector<std::string>* argv)
const {
+ if (GetInstrumentation()->InterpretOnly()) {
+ argv->push_back("--compiler-filter=interpret-only");
+ }
+
argv->push_back("--runtime-arg");
std::string checkstr = "-implicit-checks";
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 462711e..1ee0b1a 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -359,6 +359,10 @@
bool InitZygote();
void DidForkFromZygote();
+ const instrumentation::Instrumentation* GetInstrumentation() const {
+ return &instrumentation_;
+ }
+
instrumentation::Instrumentation* GetInstrumentation() {
return &instrumentation_;
}
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index dbde7c7..535c76d 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -361,7 +361,7 @@
SirtRef<mirror::DexCache> dex_cache(self, mh.GetDexCache());
SirtRef<mirror::ClassLoader> class_loader(self, mh.GetClassLoader());
MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader, &mh.GetClassDef(),
- mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
+ mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
true);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -375,11 +375,11 @@
// got what we wanted.
bool success = Verify();
if (!success) {
- return NULL;
+ return nullptr;
}
RegisterLine* register_line = reg_table_.GetLine(dex_pc);
if (register_line == NULL) {
- return NULL;
+ return nullptr;
}
const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
return GetQuickFieldAccess(inst, register_line);
@@ -3118,37 +3118,14 @@
DCHECK(inst->Opcode() == Instruction::INVOKE_VIRTUAL_QUICK ||
inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
const RegType& actual_arg_type = reg_line->GetInvocationThis(inst, is_range);
- if (actual_arg_type.IsConflict()) { // GetInvocationThis failed.
- return nullptr;
- } else if (actual_arg_type.IsZero()) { // Invoke on "null" instance: we can't go further.
+ if (!actual_arg_type.HasClass()) {
+ VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'";
return nullptr;
}
- mirror::Class* this_class = NULL;
- if (!actual_arg_type.IsUnresolvedTypes()) {
- this_class = actual_arg_type.GetClass();
- } else {
- const std::string& descriptor(actual_arg_type.GetDescriptor());
- // Try to resolve type.
- const RegType& resolved_arg_type = reg_types_.FromDescriptor(class_loader_->get(),
- descriptor.c_str(), false);
- if (!resolved_arg_type.HasClass()) {
- return nullptr; // Resolution failed.
- }
- this_class = resolved_arg_type.GetClass();
- if (this_class == NULL) {
- Thread* self = Thread::Current();
- self->ClearException();
- // Look for a system class
- this_class = reg_types_.FromDescriptor(nullptr, descriptor.c_str(), false).GetClass();
- }
- }
- if (this_class == NULL) {
- return NULL;
- }
- mirror::ObjectArray<mirror::ArtMethod>* vtable = this_class->GetVTable();
- CHECK(vtable != NULL);
+ mirror::ObjectArray<mirror::ArtMethod>* vtable = actual_arg_type.GetClass()->GetVTable();
+ CHECK(vtable != nullptr);
uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
- CHECK(vtable_index < vtable->GetLength());
+ CHECK_LT(static_cast<int32_t>(vtable_index), vtable->GetLength());
mirror::ArtMethod* res_method = vtable->Get(vtable_index);
CHECK(!Thread::Current()->IsExceptionPending());
return res_method;
@@ -3636,12 +3613,12 @@
if (klass->GetSuperClass() != NULL) {
return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset);
} else {
- return NULL;
+ VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
+ << "' from '" << PrettyDescriptor(klass) << "'";
+ return nullptr;
}
}
-// Returns the access field of a quick field access (iget/iput-quick) or NULL
-// if it cannot be found.
mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
RegisterLine* reg_line) {
DCHECK(inst->Opcode() == Instruction::IGET_QUICK ||
@@ -3651,29 +3628,12 @@
inst->Opcode() == Instruction::IPUT_WIDE_QUICK ||
inst->Opcode() == Instruction::IPUT_OBJECT_QUICK);
const RegType& object_type = reg_line->GetRegisterType(inst->VRegB_22c());
- mirror::Class* object_class = NULL;
- if (!object_type.IsUnresolvedTypes()) {
- object_class = object_type.GetClass();
- } else {
- // We need to resolve the class from its descriptor.
- const std::string& descriptor(object_type.GetDescriptor());
- Thread* self = Thread::Current();
- object_class = reg_types_.FromDescriptor(class_loader_->get(), descriptor.c_str(),
- false).GetClass();
- if (object_class == NULL) {
- self->ClearException();
- // Look for a system class
- object_class = reg_types_.FromDescriptor(nullptr, descriptor.c_str(),
- false).GetClass();
- }
- }
- if (object_class == NULL) {
- // Failed to get the Class* from reg type.
- LOG(WARNING) << "Failed to get Class* from " << object_type;
- return NULL;
+ if (!object_type.HasClass()) {
+ VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'";
+ return nullptr;
}
uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c());
- return FindInstanceFieldWithOffset(object_class, field_offset);
+ return FindInstanceFieldWithOffset(object_type.GetClass(), field_offset);
}
void MethodVerifier::VerifyIGetQuick(const Instruction* inst, const RegType& insn_type,