Merge changes Id7509ef1,Id33b8c54,I2f9e5c62
* changes:
ART: Add GetClassFields support
ART: Add Field methods
ART: Add IsInterface and IsArrayClass support
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index afa17ce..8c64d25 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -5762,7 +5762,6 @@
: HInstruction(SideEffectsForArchRuntimeCalls(), dex_pc),
special_input_(HUserRecord<HInstruction*>(current_method)),
string_index_(string_index) {
- SetPackedFlag<kFlagIsInDexCache>(false);
SetPackedField<LoadKindField>(LoadKind::kDexCacheViaMethod);
load_data_.dex_file_ = &dex_file;
}
@@ -5789,7 +5788,6 @@
const DexFile& GetDexFile() const;
dex::StringIndex GetStringIndex() const {
- DCHECK(HasStringReference(GetLoadKind()) || /* For slow paths. */ !IsInDexCache());
return string_index_;
}
@@ -5814,7 +5812,7 @@
load_kind == LoadKind::kJitTableAddress) {
return false;
}
- return !IsInDexCache();
+ return true;
}
bool NeedsDexCacheOfDeclaringClass() const OVERRIDE {
@@ -5828,15 +5826,6 @@
return SideEffects::CanTriggerGC();
}
- bool IsInDexCache() const { return GetPackedFlag<kFlagIsInDexCache>(); }
-
- void MarkInDexCache() {
- SetPackedFlag<kFlagIsInDexCache>(true);
- DCHECK(!NeedsEnvironment());
- RemoveEnvironment();
- SetSideEffects(SideEffects::None());
- }
-
void AddSpecialInput(HInstruction* special_input);
using HInstruction::GetInputRecords; // Keep the const version visible.
@@ -5852,8 +5841,7 @@
DECLARE_INSTRUCTION(LoadString);
private:
- static constexpr size_t kFlagIsInDexCache = kNumberOfGenericPackedBits;
- static constexpr size_t kFieldLoadKind = kFlagIsInDexCache + 1;
+ static constexpr size_t kFieldLoadKind = kNumberOfGenericPackedBits;
static constexpr size_t kFieldLoadKindSize =
MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast));
static constexpr size_t kNumberOfLoadStringPackedBits = kFieldLoadKind + kFieldLoadKindSize;
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 9fdeccf..ca26c30 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -270,7 +270,6 @@
void HSharpening::ProcessLoadString(HLoadString* load_string) {
DCHECK_EQ(load_string->GetLoadKind(), HLoadString::LoadKind::kDexCacheViaMethod);
- DCHECK(!load_string->IsInDexCache());
const DexFile& dex_file = load_string->GetDexFile();
dex::StringIndex string_index = load_string->GetStringIndex();
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index b889913..dccec9f 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -843,8 +843,26 @@
ss << "\n";
Locks::mutator_lock_->Dump(ss);
ss << "\n";
- runtime->GetThreadList()->Dump(ss);
- LOG(FATAL) << ss.str();
+ LOG(FATAL_WITHOUT_ABORT) << ss.str();
+ // Some threads in 'runnable_thread_ids' are probably stuck. Try to dump their stacks.
+ // Avoid using ThreadList::Dump() because it is likely to get stuck as well.
+ {
+ ReaderMutexLock mu0(self, *Locks::mutator_lock_);
+ MutexLock mu1(self, *Locks::thread_list_lock_);
+ for (Thread* thread : runtime->GetThreadList()->GetList()) {
+ uint32_t tid = thread->GetThreadId();
+ bool is_in_runnable_thread_ids =
+ std::find(runnable_thread_ids.begin(), runnable_thread_ids.end(), tid) !=
+ runnable_thread_ids.end();
+ if (is_in_runnable_thread_ids &&
+ thread->ReadFlag(kEmptyCheckpointRequest)) {
+ // Found a runnable thread that hasn't responded to the empty checkpoint request.
+ // Assume it's stuck and safe to dump its stack.
+ thread->Dump(LOG_STREAM(FATAL_WITHOUT_ABORT));
+ }
+ }
+ }
+ LOG(FATAL) << "Dumped runnable threads that haven't responded to empty checkpoint.";
}
} else {
barrier->Increment(self, barrier_count);