summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-09-03 16:16:56 -0700
committerIan Rogers <irogers@google.com>2014-09-03 17:15:54 -0700
commitc0542af3e2170143ba40d89136e284997e16bf64 (patch)
treea61e3b9cd297a4c52a0c0488a502cb77c47f0690
parentd3c9358544bbab15093614c5c2b6a9de86e11f7b (diff)
downloadandroid_art-c0542af3e2170143ba40d89136e284997e16bf64.tar.gz
android_art-c0542af3e2170143ba40d89136e284997e16bf64.tar.bz2
android_art-c0542af3e2170143ba40d89136e284997e16bf64.zip
Remove abuse of mirror::Object* to reference special values.
Remove kInvalidIndirectRefObject, kClearedJniWeakGlobal and ObjectRegistry::kInvalidObject. Handle error conditions by passing in or returning an error value. GetObjectRefType is simplified to be faster and not return invalid references that are not expected according to the spec. Adjust check JNI and jni_internal_test appropriately. Fix cases in the debugger/JDWP of out arguments being passed by reference. Bug: 17376993 Change-Id: I3ce8a28c01827e163f4dc288449959464da788b1
-rw-r--r--runtime/check_jni.cc30
-rw-r--r--runtime/class_linker-inl.h5
-rw-r--r--runtime/class_linker.h3
-rw-r--r--runtime/debugger.cc737
-rw-r--r--runtime/debugger.h51
-rw-r--r--runtime/entrypoints/entrypoint_utils.cc11
-rw-r--r--runtime/indirect_reference_table-inl.h20
-rw-r--r--runtime/indirect_reference_table.cc4
-rw-r--r--runtime/indirect_reference_table.h15
-rw-r--r--runtime/indirect_reference_table_test.cc62
-rw-r--r--runtime/java_vm_ext.cc3
-rw-r--r--runtime/jdwp/jdwp.h2
-rw-r--r--runtime/jdwp/jdwp_event.cc4
-rw-r--r--runtime/jdwp/jdwp_handler.cc490
-rw-r--r--runtime/jdwp/jdwp_main.cc2
-rw-r--r--runtime/jdwp/object_registry.cc8
-rw-r--r--runtime/jdwp/object_registry.h15
-rw-r--r--runtime/jni_internal.cc18
-rw-r--r--runtime/jni_internal_test.cc31
-rw-r--r--runtime/reference_table.cc17
-rw-r--r--runtime/runtime-inl.h12
-rw-r--r--runtime/runtime.cc8
-rw-r--r--runtime/runtime.h10
-rw-r--r--runtime/thread.cc17
24 files changed, 829 insertions, 746 deletions
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index b0f8e22ab2..95223d856c 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -650,6 +650,24 @@ class ScopedCheck {
}
mirror::Object* obj = soa.Decode<mirror::Object*>(java_object);
+ if (obj == nullptr) {
+ // Either java_object is invalid or is a cleared weak.
+ IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
+ bool okay;
+ if (GetIndirectRefKind(ref) != kWeakGlobal) {
+ okay = false;
+ } else {
+ obj = soa.Vm()->DecodeWeakGlobal(soa.Self(), ref);
+ okay = Runtime::Current()->IsClearedJniWeakGlobal(obj);
+ }
+ if (!okay) {
+ AbortF("%s is an invalid %s: %p (%p)",
+ what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(),
+ java_object, obj);
+ return false;
+ }
+ }
+
if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(obj)) {
Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
AbortF("%s is an invalid %s: %p (%p)",
@@ -784,8 +802,7 @@ class ScopedCheck {
mirror::Class* c = soa.Decode<mirror::Class*>(jc);
if (c == nullptr) {
*msg += "NULL";
- } else if (c == kInvalidIndirectRefObject ||
- !Runtime::Current()->GetHeap()->IsValidObjectAddress(c)) {
+ } else if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(c)) {
StringAppendF(msg, "INVALID POINTER:%p", jc);
} else if (!c->IsClass()) {
*msg += "INVALID NON-CLASS OBJECT OF TYPE:" + PrettyTypeOf(c);
@@ -1453,12 +1470,13 @@ class CheckJNI {
}
static jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj) {
- // Note: we use "Ep" rather than "EL" because this is the one JNI function that it's okay to
- // pass an invalid reference to.
+ // Note: we use "EL" here but "Ep" has been used in the past on the basis that we'd like to
+ // know the object is invalid. The spec says that passing invalid objects or even ones that
+ // are deleted isn't supported.
ScopedObjectAccess soa(env);
ScopedCheck sc(kFlag_Default, __FUNCTION__);
- JniValueType args[2] = {{.E = env }, {.p = obj}};
- if (sc.Check(soa, true, "Ep", args)) {
+ JniValueType args[2] = {{.E = env }, {.L = obj}};
+ if (sc.Check(soa, true, "EL", args)) {
JniValueType result;
result.w = baseEnv(env)->GetObjectRefType(env, obj);
if (sc.Check(soa, false, "w", &result)) {
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index d05f7af870..1306546801 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -155,6 +155,11 @@ inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx, mirror::A
return resolved_field;
}
+inline mirror::Object* ClassLinker::AllocObject(Thread* self) {
+ return GetClassRoot(kJavaLangObject)->Alloc<false, false>(self,
+ Runtime::Current()->GetHeap()->GetCurrentAllocator());
+}
+
template <class T>
inline mirror::ObjectArray<T>* ClassLinker::AllocObjectArray(Thread* self, size_t length) {
return mirror::ObjectArray<T>::Alloc(self, GetClassRoot(kObjectArrayClass), length);
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 064a85d130..a7a68b7546 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -288,6 +288,9 @@ class ClassLinker {
InstructionSet instruction_set,
std::string* error_msg);
+ // Allocate an instance of a java.lang.Object.
+ mirror::Object* AllocObject(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// TODO: replace this with multiple methods that allocate the correct managed type.
template <class T>
mirror::ObjectArray<T>* AllocObjectArray(Thread* self, size_t length)
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 9136f9f8d8..8b8e7c827e 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -132,12 +132,12 @@ class AllocRecord {
}
void SetType(mirror::Class* t) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- type_ = Dbg::GetTypeCache().Add(t);
+ type_ = Dbg::GetTypeCache()->Add(t);
}
size_t GetDepth() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
size_t depth = 0;
- while (depth < kMaxAllocRecordStackDepth && stack_[depth].Method() != NULL) {
+ while (depth < kMaxAllocRecordStackDepth && stack_[depth].Method() != nullptr) {
++depth;
}
return depth;
@@ -168,7 +168,7 @@ class AllocRecord {
jobject type_; // This is a weak global.
size_t byte_count_;
uint16_t thin_lock_id_;
- AllocRecordStackTraceElement stack_[kMaxAllocRecordStackDepth]; // Unused entries have NULL method.
+ AllocRecordStackTraceElement stack_[kMaxAllocRecordStackDepth]; // Unused entries have nullptr method.
};
class Breakpoint {
@@ -287,7 +287,7 @@ static bool gJdwpConfigured = false;
static JDWP::JdwpOptions gJdwpOptions;
// Runtime JDWP state.
-static JDWP::JdwpState* gJdwpState = NULL;
+static JDWP::JdwpState* gJdwpState = nullptr;
static bool gDebuggerConnected; // debugger or DDMS is connected.
static bool gDebuggerActive; // debugger is making requests.
static bool gDisposed; // debugger called VirtualMachine.Dispose, so we should drop the connection.
@@ -391,58 +391,60 @@ static bool IsSuspendedForDebugger(ScopedObjectAccessUnchecked& soa, Thread* thr
return thread->IsSuspended() && thread->GetDebugSuspendCount() > 0;
}
-static mirror::Array* DecodeArray(JDWP::RefTypeId id, JDWP::JdwpError& status)
+static mirror::Array* DecodeNonNullArray(JDWP::RefTypeId id, JDWP::JdwpError* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
- status = JDWP::ERR_INVALID_OBJECT;
- return NULL;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id, error);
+ if (o == nullptr) {
+ *error = JDWP::ERR_INVALID_OBJECT;
+ return nullptr;
}
if (!o->IsArrayInstance()) {
- status = JDWP::ERR_INVALID_ARRAY;
- return NULL;
+ *error = JDWP::ERR_INVALID_ARRAY;
+ return nullptr;
}
- status = JDWP::ERR_NONE;
+ *error = JDWP::ERR_NONE;
return o->AsArray();
}
-static mirror::Class* DecodeClass(JDWP::RefTypeId id, JDWP::JdwpError& status)
+static mirror::Class* DecodeClass(JDWP::RefTypeId id, JDWP::JdwpError* error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
- status = JDWP::ERR_INVALID_OBJECT;
- return NULL;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id, error);
+ if (o == nullptr) {
+ *error = JDWP::ERR_INVALID_OBJECT;
+ return nullptr;
}
if (!o->IsClass()) {
- status = JDWP::ERR_INVALID_CLASS;
- return NULL;
+ *error = JDWP::ERR_INVALID_CLASS;
+ return nullptr;
}
- status = JDWP::ERR_NONE;
+ *error = JDWP::ERR_NONE;
return o->AsClass();
}
-static JDWP::JdwpError DecodeThread(ScopedObjectAccessUnchecked& soa, JDWP::ObjectId thread_id, Thread*& thread)
+static Thread* DecodeThread(ScopedObjectAccessUnchecked& soa, JDWP::ObjectId thread_id,
+ JDWP::JdwpError* error)
EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* thread_peer = gRegistry->Get<mirror::Object*>(thread_id);
- if (thread_peer == NULL || thread_peer == ObjectRegistry::kInvalidObject) {
+ mirror::Object* thread_peer = gRegistry->Get<mirror::Object*>(thread_id, error);
+ if (thread_peer == nullptr) {
// This isn't even an object.
- return JDWP::ERR_INVALID_OBJECT;
+ *error = JDWP::ERR_INVALID_OBJECT;
+ return nullptr;
}
mirror::Class* java_lang_Thread = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread);
if (!java_lang_Thread->IsAssignableFrom(thread_peer->GetClass())) {
// This isn't a thread.
- return JDWP::ERR_INVALID_THREAD;
+ *error = JDWP::ERR_INVALID_THREAD;
+ return nullptr;
}
- thread = Thread::FromManagedThread(soa, thread_peer);
- if (thread == NULL) {
- // This is a java.lang.Thread without a Thread*. Must be a zombie.
- return JDWP::ERR_THREAD_NOT_ALIVE;
- }
- return JDWP::ERR_NONE;
+ Thread* thread = Thread::FromManagedThread(soa, thread_peer);
+ // If thread is null then this a java.lang.Thread without a Thread*. Must be a un-started or a
+ // zombie.
+ *error = (thread == nullptr) ? JDWP::ERR_THREAD_NOT_ALIVE : JDWP::ERR_NONE;
+ return thread;
}
static JDWP::JdwpTag BasicTagFromDescriptor(const char* descriptor) {
@@ -460,7 +462,7 @@ static JDWP::JdwpTag BasicTagFromClass(mirror::Class* klass)
static JDWP::JdwpTag TagFromClass(const ScopedObjectAccessUnchecked& soa, mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(c != NULL);
+ CHECK(c != nullptr);
if (c->IsArrayClass()) {
return JDWP::JT_ARRAY;
}
@@ -503,7 +505,7 @@ static JDWP::JdwpTag TagFromClass(const ScopedObjectAccessUnchecked& soa, mirror
*/
static JDWP::JdwpTag TagFromObject(const ScopedObjectAccessUnchecked& soa, mirror::Object* o)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return (o == NULL) ? JDWP::JT_OBJECT : TagFromClass(soa, o->GetClass());
+ return (o == nullptr) ? JDWP::JT_OBJECT : TagFromClass(soa, o->GetClass());
}
static bool IsPrimitiveTag(JDWP::JdwpTag tag) {
@@ -646,7 +648,7 @@ void Dbg::StartJdwp() {
// debugger, passively listen for a debugger, or block waiting for a
// debugger.
gJdwpState = JDWP::JdwpState::Create(&gJdwpOptions);
- if (gJdwpState == NULL) {
+ if (gJdwpState == nullptr) {
// We probably failed because some other process has the port already, which means that
// if we don't abort the user is likely to think they're talking to us when they're actually
// talking to that other process.
@@ -708,7 +710,7 @@ DebugInvokeReq* Dbg::GetInvokeReq() {
}
Thread* Dbg::GetDebugThread() {
- return (gJdwpState != NULL) ? gJdwpState->GetDebugThread() : NULL;
+ return (gJdwpState != nullptr) ? gJdwpState->GetDebugThread() : nullptr;
}
void Dbg::ClearWaitForEventThread() {
@@ -826,12 +828,14 @@ void Dbg::UndoDebuggerSuspensions() {
}
std::string Dbg::GetClassName(JDWP::RefTypeId class_id) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(class_id);
- if (o == NULL) {
- return "NULL";
- }
- if (o == ObjectRegistry::kInvalidObject) {
- return StringPrintf("invalid object %p", reinterpret_cast<void*>(class_id));
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(class_id, &error);
+ if (o == nullptr) {
+ if (error == JDWP::ERR_NONE) {
+ return "NULL";
+ } else {
+ return StringPrintf("invalid object %p", reinterpret_cast<void*>(class_id));
+ }
}
if (!o->IsClass()) {
return StringPrintf("non-class %p", o); // This is only used for debugging output anyway.
@@ -840,34 +844,37 @@ std::string Dbg::GetClassName(JDWP::RefTypeId class_id) {
return DescriptorToName(o->AsClass()->GetDescriptor(&temp));
}
-JDWP::JdwpError Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& class_object_id) {
+JDWP::JdwpError Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId* class_object_id) {
JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(id, status);
- if (c == NULL) {
+ mirror::Class* c = DecodeClass(id, &status);
+ if (c == nullptr) {
+ *class_object_id = 0;
return status;
}
- class_object_id = gRegistry->Add(c);
+ *class_object_id = gRegistry->Add(c);
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclass_id) {
+JDWP::JdwpError Dbg::GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId* superclass_id) {
JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(id, status);
- if (c == NULL) {
+ mirror::Class* c = DecodeClass(id, &status);
+ if (c == nullptr) {
+ *superclass_id = 0;
return status;
}
if (c->IsInterface()) {
// http://code.google.com/p/android/issues/detail?id=20856
- superclass_id = 0;
+ *superclass_id = 0;
} else {
- superclass_id = gRegistry->Add(c->GetSuperClass());
+ *superclass_id = gRegistry->Add(c->GetSuperClass());
}
return JDWP::ERR_NONE;
}
JDWP::JdwpError Dbg::GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id, &error);
+ if (o == nullptr) {
return JDWP::ERR_INVALID_OBJECT;
}
expandBufAddObjectId(pReply, gRegistry->Add(o->GetClass()->GetClassLoader()));
@@ -875,10 +882,10 @@ JDWP::JdwpError Dbg::GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
}
JDWP::JdwpError Dbg::GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(id, status);
- if (c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(id, &error);
+ if (c == nullptr) {
+ return error;
}
uint32_t access_flags = c->GetAccessFlags() & kAccJavaFlagsMask;
@@ -895,10 +902,10 @@ JDWP::JdwpError Dbg::GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
+JDWP::JdwpError Dbg::GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply) {
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if (o == nullptr) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -913,10 +920,10 @@ JDWP::JdwpError Dbg::GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* r
Runtime::Current()->GetThreadList()->ResumeAll();
self->TransitionFromSuspendedToRunnable();
- if (monitor_info.owner_ != NULL) {
+ if (monitor_info.owner_ != nullptr) {
expandBufAddObjectId(reply, gRegistry->Add(monitor_info.owner_->GetPeer()));
} else {
- expandBufAddObjectId(reply, gRegistry->Add(NULL));
+ expandBufAddObjectId(reply, gRegistry->Add(nullptr));
}
expandBufAdd4BE(reply, monitor_info.entry_count_);
expandBufAdd4BE(reply, monitor_info.waiters_.size());
@@ -927,8 +934,8 @@ JDWP::JdwpError Dbg::GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* r
}
JDWP::JdwpError Dbg::GetOwnedMonitors(JDWP::ObjectId thread_id,
- std::vector<JDWP::ObjectId>& monitors,
- std::vector<uint32_t>& stack_depths) {
+ std::vector<JDWP::ObjectId>* monitors,
+ std::vector<uint32_t>* stack_depths) {
struct OwnedMonitorVisitor : public StackVisitor {
OwnedMonitorVisitor(Thread* thread, Context* context,
std::vector<JDWP::ObjectId>* monitor_vector,
@@ -955,16 +962,17 @@ JDWP::JdwpError Dbg::GetOwnedMonitors(JDWP::ObjectId thread_id,
}
size_t current_stack_depth;
- std::vector<JDWP::ObjectId>* monitors;
- std::vector<uint32_t>* stack_depths;
+ std::vector<JDWP::ObjectId>* const monitors;
+ std::vector<uint32_t>* const stack_depths;
};
ScopedObjectAccessUnchecked soa(Thread::Current());
Thread* thread;
{
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
- if (error != JDWP::ERR_NONE) {
+ JDWP::JdwpError error;
+ thread = DecodeThread(soa, thread_id, &error);
+ if (thread == nullptr) {
return error;
}
if (!IsSuspendedForDebugger(soa, thread)) {
@@ -972,20 +980,21 @@ JDWP::JdwpError Dbg::GetOwnedMonitors(JDWP::ObjectId thread_id,
}
}
std::unique_ptr<Context> context(Context::Create());
- OwnedMonitorVisitor visitor(thread, context.get(), &monitors, &stack_depths);
+ OwnedMonitorVisitor visitor(thread, context.get(), monitors, stack_depths);
visitor.WalkStack();
return JDWP::ERR_NONE;
}
JDWP::JdwpError Dbg::GetContendedMonitor(JDWP::ObjectId thread_id,
- JDWP::ObjectId& contended_monitor) {
+ JDWP::ObjectId* contended_monitor) {
mirror::Object* contended_monitor_obj;
ScopedObjectAccessUnchecked soa(Thread::Current());
+ *contended_monitor = 0;
{
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
- if (error != JDWP::ERR_NONE) {
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
+ if (thread == nullptr) {
return error;
}
if (!IsSuspendedForDebugger(soa, thread)) {
@@ -995,108 +1004,105 @@ JDWP::JdwpError Dbg::GetContendedMonitor(JDWP::ObjectId thread_id,
}
// Add() requires the thread_list_lock_ not held to avoid the lock
// level violation.
- contended_monitor = gRegistry->Add(contended_monitor_obj);
+ *contended_monitor = gRegistry->Add(contended_monitor_obj);
return JDWP::ERR_NONE;
}
JDWP::JdwpError Dbg::GetInstanceCounts(const std::vector<JDWP::RefTypeId>& class_ids,
- std::vector<uint64_t>& counts)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ std::vector<uint64_t>* counts) {
gc::Heap* heap = Runtime::Current()->GetHeap();
heap->CollectGarbage(false);
std::vector<mirror::Class*> classes;
- counts.clear();
+ counts->clear();
for (size_t i = 0; i < class_ids.size(); ++i) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_ids[i], status);
- if (c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_ids[i], &error);
+ if (c == nullptr) {
+ return error;
}
classes.push_back(c);
- counts.push_back(0);
+ counts->push_back(0);
}
- heap->CountInstances(classes, false, &counts[0]);
+ heap->CountInstances(classes, false, &(*counts)[0]);
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::GetInstances(JDWP::RefTypeId class_id, int32_t max_count, std::vector<JDWP::ObjectId>& instances)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+JDWP::JdwpError Dbg::GetInstances(JDWP::RefTypeId class_id, int32_t max_count,
+ std::vector<JDWP::ObjectId>* instances) {
gc::Heap* heap = Runtime::Current()->GetHeap();
// We only want reachable instances, so do a GC.
heap->CollectGarbage(false);
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
if (c == nullptr) {
- return status;
+ return error;
}
std::vector<mirror::Object*> raw_instances;
Runtime::Current()->GetHeap()->GetInstances(c, max_count, raw_instances);
for (size_t i = 0; i < raw_instances.size(); ++i) {
- instances.push_back(gRegistry->Add(raw_instances[i]));
+ instances->push_back(gRegistry->Add(raw_instances[i]));
}
return JDWP::ERR_NONE;
}
JDWP::JdwpError Dbg::GetReferringObjects(JDWP::ObjectId object_id, int32_t max_count,
- std::vector<JDWP::ObjectId>& referring_objects)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ std::vector<JDWP::ObjectId>* referring_objects) {
gc::Heap* heap = Runtime::Current()->GetHeap();
heap->CollectGarbage(false);
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if (o == nullptr) {
return JDWP::ERR_INVALID_OBJECT;
}
std::vector<mirror::Object*> raw_instances;
heap->GetReferringObjects(o, max_count, raw_instances);
for (size_t i = 0; i < raw_instances.size(); ++i) {
- referring_objects.push_back(gRegistry->Add(raw_instances[i]));
+ referring_objects->push_back(gRegistry->Add(raw_instances[i]));
}
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::DisableCollection(JDWP::ObjectId object_id)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
+JDWP::JdwpError Dbg::DisableCollection(JDWP::ObjectId object_id) {
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if (o == nullptr) {
return JDWP::ERR_INVALID_OBJECT;
}
gRegistry->DisableCollection(object_id);
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::EnableCollection(JDWP::ObjectId object_id)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
+JDWP::JdwpError Dbg::EnableCollection(JDWP::ObjectId object_id) {
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
// Unlike DisableCollection, JDWP specs do not state an invalid object causes an error. The RI
// also ignores these cases and never return an error. However it's not obvious why this command
// should behave differently from DisableCollection and IsCollected commands. So let's be more
// strict and return an error if this happens.
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
+ if (o == nullptr) {
return JDWP::ERR_INVALID_OBJECT;
}
gRegistry->EnableCollection(object_id);
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::IsCollected(JDWP::ObjectId object_id, bool& is_collected)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+JDWP::JdwpError Dbg::IsCollected(JDWP::ObjectId object_id, bool* is_collected) {
+ *is_collected = true;
if (object_id == 0) {
// Null object id is invalid.
return JDWP::ERR_INVALID_OBJECT;
}
// JDWP specs state an INVALID_OBJECT error is returned if the object ID is not valid. However
// the RI seems to ignore this and assume object has been collected.
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
- is_collected = true;
- } else {
- is_collected = gRegistry->IsCollected(object_id);
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if (o != nullptr) {
+ *is_collected = gRegistry->IsCollected(object_id);
}
return JDWP::ERR_NONE;
}
-void Dbg::DisposeObject(JDWP::ObjectId object_id, uint32_t reference_count)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+void Dbg::DisposeObject(JDWP::ObjectId object_id, uint32_t reference_count) {
gRegistry->DisposeObject(object_id, reference_count);
}
@@ -1113,10 +1119,10 @@ static JDWP::JdwpTypeTag GetTypeTag(mirror::Class* klass)
}
JDWP::JdwpError Dbg::GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
}
JDWP::JdwpTypeTag type_tag = GetTypeTag(c);
@@ -1125,12 +1131,12 @@ JDWP::JdwpError Dbg::GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf*
return JDWP::ERR_NONE;
}
-void Dbg::GetClassList(std::vector<JDWP::RefTypeId>& classes) {
+void Dbg::GetClassList(std::vector<JDWP::RefTypeId>* classes) {
// Get the complete list of reference classes (i.e. all classes except
// the primitive types).
// Returns a newly-allocated buffer full of RefTypeId values.
struct ClassListCreator {
- explicit ClassListCreator(std::vector<JDWP::RefTypeId>& classes) : classes(classes) {
+ explicit ClassListCreator(std::vector<JDWP::RefTypeId>* classes) : classes(classes) {
}
static bool Visit(mirror::Class* c, void* arg) {
@@ -1141,12 +1147,12 @@ void Dbg::GetClassList(std::vector<JDWP::RefTypeId>& classes) {
// annotalysis.
bool Visit(mirror::Class* c) NO_THREAD_SAFETY_ANALYSIS {
if (!c->IsPrimitive()) {
- classes.push_back(gRegistry->AddRefType(c));
+ classes->push_back(gRegistry->AddRefType(c));
}
return true;
}
- std::vector<JDWP::RefTypeId>& classes;
+ std::vector<JDWP::RefTypeId>* const classes;
};
ClassListCreator clc(classes);
@@ -1155,10 +1161,10 @@ void Dbg::GetClassList(std::vector<JDWP::RefTypeId>& classes) {
JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag,
uint32_t* pStatus, std::string* pDescriptor) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
}
if (c->IsArrayClass()) {
@@ -1173,26 +1179,26 @@ JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* p
*pTypeTag = c->IsInterface() ? JDWP::TT_INTERFACE : JDWP::TT_CLASS;
}
- if (pDescriptor != NULL) {
+ if (pDescriptor != nullptr) {
std::string temp;
*pDescriptor = c->GetDescriptor(&temp);
}
return JDWP::ERR_NONE;
}
-void Dbg::FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids) {
+void Dbg::FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>* ids) {
std::vector<mirror::Class*> classes;
Runtime::Current()->GetClassLinker()->LookupClasses(descriptor, classes);
- ids.clear();
+ ids->clear();
for (size_t i = 0; i < classes.size(); ++i) {
- ids.push_back(gRegistry->Add(classes[i]));
+ ids->push_back(gRegistry->Add(classes[i]));
}
}
-JDWP::JdwpError Dbg::GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if (o == NULL || o == ObjectRegistry::kInvalidObject) {
+JDWP::JdwpError Dbg::GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply) {
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if (o == nullptr) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -1206,37 +1212,39 @@ JDWP::JdwpError Dbg::GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf*
}
JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId class_id, std::string* signature) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
}
std::string temp;
*signature = c->GetDescriptor(&temp);
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string& result) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
+JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string* result) {
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
if (c == nullptr) {
- return status;
+ return error;
}
const char* source_file = c->GetSourceFile();
if (source_file == nullptr) {
return JDWP::ERR_ABSENT_INFORMATION;
}
- result = source_file;
+ *result = source_file;
return JDWP::ERR_NONE;
}
-JDWP::JdwpError Dbg::GetObjectTag(JDWP::ObjectId object_id, uint8_t& tag) {
+JDWP::JdwpError Dbg::GetObjectTag(JDWP::ObjectId object_id, uint8_t* tag) {
ScopedObjectAccessUnchecked soa(Thread::Current());
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if (o == ObjectRegistry::kInvalidObject) {
- return JDWP::ERR_INVALID_OBJECT;
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if (error != JDWP::ERR_NONE) {
+ *tag = JDWP::JT_VOID;
+ return error;
}
- tag = TagFromObject(soa, o);
+ *tag = TagFromObject(soa, o);
return JDWP::ERR_NONE;
}
@@ -1270,21 +1278,21 @@ size_t Dbg::GetTagWidth(JDWP::JdwpTag tag) {
}
}
-JDWP::JdwpError Dbg::GetArrayLength(JDWP::ObjectId array_id, int& length) {
- JDWP::JdwpError status;
- mirror::Array* a = DecodeArray(array_id, status);
- if (a == NULL) {
- return status;
+JDWP::JdwpError Dbg::GetArrayLength(JDWP::ObjectId array_id, int32_t* length) {
+ JDWP::JdwpError error;
+ mirror::Array* a = DecodeNonNullArray(array_id, &error);
+ if (a == nullptr) {
+ return error;
}
- length = a->GetLength();
+ *length = a->GetLength();
return JDWP::ERR_NONE;
}
JDWP::JdwpError Dbg::OutputArray(JDWP::ObjectId array_id, int offset, int count, JDWP::ExpandBuf* pReply) {
- JDWP::JdwpError status;
- mirror::Array* a = DecodeArray(array_id, status);
+ JDWP::JdwpError error;
+ mirror::Array* a = DecodeNonNullArray(array_id, &error);
if (a == nullptr) {
- return status;
+ return error;
}
if (offset < 0 || count < 0 || offset > a->GetLength() || a->GetLength() - offset < count) {
@@ -1327,24 +1335,23 @@ JDWP::JdwpError Dbg::OutputArray(JDWP::ObjectId array_id, int offset, int count,
}
template <typename T>
-static void CopyArrayData(mirror::Array* a, JDWP::Request& src, int offset, int count)
+static void CopyArrayData(mirror::Array* a, JDWP::Request* src, int offset, int count)
NO_THREAD_SAFETY_ANALYSIS {
// TODO: fix when annotalysis correctly handles non-member functions.
DCHECK(a->GetClass()->IsPrimitiveArray());
T* dst = reinterpret_cast<T*>(a->GetRawData(sizeof(T), offset));
for (int i = 0; i < count; ++i) {
- *dst++ = src.ReadValue(sizeof(T));
+ *dst++ = src->ReadValue(sizeof(T));
}
}
JDWP::JdwpError Dbg::SetArrayElements(JDWP::ObjectId array_id, int offset, int count,
- JDWP::Request& request)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- JDWP::JdwpError status;
- mirror::Array* dst = DecodeArray(array_id, status);
- if (dst == NULL) {
- return status;
+ JDWP::Request* request) {
+ JDWP::JdwpError error;
+ mirror::Array* dst = DecodeNonNullArray(array_id, &error);
+ if (dst == nullptr) {
+ return error;
}
if (offset < 0 || count < 0 || offset > dst->GetLength() || dst->GetLength() - offset < count) {
@@ -1367,10 +1374,11 @@ JDWP::JdwpError Dbg::SetArrayElements(JDWP::ObjectId array_id, int offset, int c
} else {
mirror::ObjectArray<mirror::Object>* oa = dst->AsObjectArray<mirror::Object>();
for (int i = 0; i < count; ++i) {
- JDWP::ObjectId id = request.ReadObjectId();
- mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
- if (o == ObjectRegistry::kInvalidObject) {
- return JDWP::ERR_INVALID_OBJECT;
+ JDWP::ObjectId id = request->ReadObjectId();
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id, &error);
+ if (error != JDWP::ERR_NONE) {
+ return error;
}
oa->Set<false>(offset + i, o);
}
@@ -1383,13 +1391,14 @@ JDWP::ObjectId Dbg::CreateString(const std::string& str) {
return gRegistry->Add(mirror::String::AllocFromModifiedUtf8(Thread::Current(), str.c_str()));
}
-JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId& new_object) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
- return status;
+JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object) {
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ *new_object = 0;
+ return error;
}
- new_object = gRegistry->Add(c->AllocObject(Thread::Current()));
+ *new_object = gRegistry->Add(c->AllocObject(Thread::Current()));
return JDWP::ERR_NONE;
}
@@ -1397,24 +1406,25 @@ JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId& new_
* Used by Eclipse's "Display" view to evaluate "new byte[5]" to get "(byte[]) [0, 0, 0, 0, 0]".
*/
JDWP::JdwpError Dbg::CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length,
- JDWP::ObjectId& new_array) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(array_class_id, status);
- if (c == NULL) {
- return status;
+ JDWP::ObjectId* new_array) {
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(array_class_id, &error);
+ if (c == nullptr) {
+ *new_array = 0;
+ return error;
}
- new_array = gRegistry->Add(mirror::Array::Alloc<true>(Thread::Current(), c, length,
- c->GetComponentSize(),
- Runtime::Current()->GetHeap()->GetCurrentAllocator()));
+ *new_array = gRegistry->Add(mirror::Array::Alloc<true>(Thread::Current(), c, length,
+ c->GetComponentSize(),
+ Runtime::Current()->GetHeap()->GetCurrentAllocator()));
return JDWP::ERR_NONE;
}
bool Dbg::MatchType(JDWP::RefTypeId instance_class_id, JDWP::RefTypeId class_id) {
- JDWP::JdwpError status;
- mirror::Class* c1 = DecodeClass(instance_class_id, status);
- CHECK(c1 != NULL);
- mirror::Class* c2 = DecodeClass(class_id, status);
- CHECK(c2 != NULL);
+ JDWP::JdwpError error;
+ mirror::Class* c1 = DecodeClass(instance_class_id, &error);
+ CHECK(c1 != nullptr);
+ mirror::Class* c2 = DecodeClass(class_id, &error);
+ CHECK(c2 != nullptr);
return c2->IsAssignableFrom(c1);
}
@@ -1442,27 +1452,25 @@ static mirror::ArtMethod* FromMethodId(JDWP::MethodId mid)
return reinterpret_cast<mirror::ArtMethod*>(static_cast<uintptr_t>(mid));
}
-static void SetLocation(JDWP::JdwpLocation& location, mirror::ArtMethod* m, uint32_t dex_pc)
+static void SetLocation(JDWP::JdwpLocation* location, mirror::ArtMethod* m, uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (m == NULL) {
+ if (m == nullptr) {
memset(&location, 0, sizeof(location));
} else {
mirror::Class* c = m->GetDeclaringClass();
- location.type_tag = GetTypeTag(c);
- location.class_id = gRegistry->AddRefType(c);
- location.method_id = ToMethodId(m);
- location.dex_pc = (m->IsNative() || m->IsProxyMethod()) ? static_cast<uint64_t>(-1) : dex_pc;
+ location->type_tag = GetTypeTag(c);
+ location->class_id = gRegistry->AddRefType(c);
+ location->method_id = ToMethodId(m);
+ location->dex_pc = (m->IsNative() || m->IsProxyMethod()) ? static_cast<uint64_t>(-1) : dex_pc;
}
}
-std::string Dbg::GetMethodName(JDWP::MethodId method_id)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+std::string Dbg::GetMethodName(JDWP::MethodId method_id) {
mirror::ArtMethod* m = FromMethodId(method_id);
return m->GetName();
}
-std::string Dbg::GetFieldName(JDWP::FieldId field_id)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+std::string Dbg::GetFieldName(JDWP::FieldId field_id) {
return FromFieldId(field_id)->GetName();
}
@@ -1525,10 +1533,10 @@ static uint16_t DemangleSlot(uint16_t slot, mirror::ArtMethod* m)
}
JDWP::JdwpError Dbg::OutputDeclaredFields(JDWP::RefTypeId class_id, bool with_generic, JDWP::ExpandBuf* pReply) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
}
size_t instance_field_count = c->NumInstanceFields();
@@ -1552,10 +1560,10 @@ JDWP::JdwpError Dbg::OutputDeclaredFields(JDWP::RefTypeId class_id, bool with_ge
JDWP::JdwpError Dbg::OutputDeclaredMethods(JDWP::RefTypeId class_id, bool with_generic,
JDWP::ExpandBuf* pReply) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
}
size_t direct_method_count = c->NumDirectMethods();
@@ -1578,12 +1586,12 @@ JDWP::JdwpError Dbg::OutputDeclaredMethods(JDWP::RefTypeId class_id, bool with_g
}
JDWP::JdwpError Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
- JDWP::JdwpError status;
+ JDWP::JdwpError error;
Thread* self = Thread::Current();
StackHandleScope<1> hs(self);
- Handle<mirror::Class> c(hs.NewHandle(DecodeClass(class_id, status)));
+ Handle<mirror::Class> c(hs.NewHandle(DecodeClass(class_id, &error)));
if (c.Get() == nullptr) {
- return status;
+ return error;
}
size_t interface_count = c->NumDirectInterfaces();
expandBufAdd4BE(pReply, interface_count);
@@ -1594,8 +1602,7 @@ JDWP::JdwpError Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId class_id, JDWP::Ex
return JDWP::ERR_NONE;
}
-void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::ExpandBuf* pReply)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::ExpandBuf* pReply) {
struct DebugCallbackContext {
int numItems;
JDWP::ExpandBuf* pReply;
@@ -1634,7 +1641,7 @@ void Dbg::OutputLineTable(JDWP::RefTypeId, JDWP::MethodId method_id, JDWP::Expan
if (code_item != nullptr) {
m->GetDexFile()->DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(),
- DebugCallbackContext::Callback, NULL, &context);
+ DebugCallbackContext::Callback, nullptr, &context);
}
JDWP::Set4BE(expandBufGetBuffer(pReply) + numLinesOffset, context.numItems);
@@ -1692,7 +1699,7 @@ void Dbg::OutputVariableTable(JDWP::RefTypeId, JDWP::MethodId method_id, bool wi
const DexFile::CodeItem* code_item = m->GetCodeItem();
if (code_item != nullptr) {
m->GetDexFile()->DecodeDebugInfo(
- code_item, m->IsStatic(), m->GetDexMethodIndex(), NULL, DebugCallbackContext::Callback,
+ code_item, m->IsStatic(), m->GetDexMethodIndex(), nullptr, DebugCallbackContext::Callback,
&context);
}
@@ -1714,10 +1721,9 @@ void Dbg::OutputFieldValue(JDWP::FieldId field_id, const JValue* field_value,
}
JDWP::JdwpError Dbg::GetBytecodes(JDWP::RefTypeId, JDWP::MethodId method_id,
- std::vector<uint8_t>& bytecodes)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ std::vector<uint8_t>* bytecodes) {
mirror::ArtMethod* m = FromMethodId(method_id);
- if (m == NULL) {
+ if (m == nullptr) {
return JDWP::ERR_INVALID_METHODID;
}
const DexFile::CodeItem* code_item = m->GetCodeItem();
@@ -1725,7 +1731,7 @@ JDWP::JdwpError Dbg::GetBytecodes(JDWP::RefTypeId, JDWP::MethodId method_id,
const uint8_t* begin = reinterpret_cast<const uint8_t*>(code_item->insns_);
const uint8_t* end = begin + byte_count;
for (const uint8_t* p = begin; p != end; ++p) {
- bytecodes.push_back(*p);
+ bytecodes->push_back(*p);
}
return JDWP::ERR_NONE;
}
@@ -1742,24 +1748,24 @@ static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::Obje
JDWP::FieldId field_id, JDWP::ExpandBuf* pReply,
bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- JDWP::JdwpError status;
- mirror::Class* c = DecodeClass(ref_type_id, status);
- if (ref_type_id != 0 && c == NULL) {
- return status;
+ JDWP::JdwpError error;
+ mirror::Class* c = DecodeClass(ref_type_id, &error);
+ if (ref_type_id != 0 && c == nullptr) {
+ return error;
}
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if ((!is_static && o == NULL) || o == ObjectRegistry::kInvalidObject) {
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
mirror::ArtField* f = FromFieldId(field_id);
mirror::Class* receiver_class = c;
- if (receiver_class == NULL && o != NULL) {
+ if (receiver_class == nullptr && o != nullptr) {
receiver_class = o->GetClass();
}
- // TODO: should we give up now if receiver_class is NULL?
- if (receiver_class != NULL && !f->GetDeclaringClass()->IsAssignableFrom(receiver_class)) {
+ // TODO: should we give up now if receiver_class is nullptr?
+ if (receiver_class != nullptr && !f->GetDeclaringClass()->IsAssignableFrom(receiver_class)) {
LOG(INFO) << "ERR_INVALID_FIELDID: " << PrettyField(f) << " " << PrettyClass(receiver_class);
return JDWP::ERR_INVALID_FIELDID;
}
@@ -1772,7 +1778,8 @@ static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::Obje
}
} else {
if (f->IsStatic()) {
- LOG(WARNING) << "Ignoring non-NULL receiver for ObjectReference.SetValues on static field " << PrettyField(f);
+ LOG(WARNING) << "Ignoring non-nullptr receiver for ObjectReference.SetValues on static field "
+ << PrettyField(f);
}
}
if (f->IsStatic()) {
@@ -1800,15 +1807,17 @@ JDWP::JdwpError Dbg::GetFieldValue(JDWP::ObjectId object_id, JDWP::FieldId field
return GetFieldValueImpl(0, object_id, field_id, pReply, false);
}
-JDWP::JdwpError Dbg::GetStaticFieldValue(JDWP::RefTypeId ref_type_id, JDWP::FieldId field_id, JDWP::ExpandBuf* pReply) {
+JDWP::JdwpError Dbg::GetStaticFieldValue(JDWP::RefTypeId ref_type_id, JDWP::FieldId field_id,
+ JDWP::ExpandBuf* pReply) {
return GetFieldValueImpl(ref_type_id, 0, field_id, pReply, true);
}
static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId field_id,
uint64_t value, int width, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
- if ((!is_static && o == NULL) || o == ObjectRegistry::kInvalidObject) {
+ JDWP::JdwpError error;
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
mirror::ArtField* f = FromFieldId(field_id);
@@ -1821,7 +1830,7 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId
}
} else {
if (f->IsStatic()) {
- LOG(WARNING) << "Ignoring non-NULL receiver for ObjectReference.SetValues on static field " << PrettyField(f);
+ LOG(WARNING) << "Ignoring non-nullptr receiver for ObjectReference.SetValues on static field " << PrettyField(f);
}
}
if (f->IsStatic()) {
@@ -1841,11 +1850,11 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId
f->Set32<false>(o, value);
}
} else {
- mirror::Object* v = gRegistry->Get<mirror::Object*>(value);
- if (v == ObjectRegistry::kInvalidObject) {
+ mirror::Object* v = gRegistry->Get<mirror::Object*>(value, &error);
+ if (error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
- if (v != NULL) {
+ if (v != nullptr) {
mirror::Class* field_type;
{
StackHandleScope<3> hs(Thread::Current());
@@ -1875,7 +1884,9 @@ JDWP::JdwpError Dbg::SetStaticFieldValue(JDWP::FieldId field_id, uint64_t value,
}
std::string Dbg::StringToUtf8(JDWP::ObjectId string_id) {
- mirror::String* s = gRegistry->Get<mirror::String*>(string_id);
+ JDWP::JdwpError error;
+ mirror::String* s = gRegistry->Get<mirror::String*>(string_id, &error);
+ CHECK(s != nullptr) << error;
return s->ToModifiedUtf8();
}
@@ -1901,40 +1912,42 @@ void Dbg::OutputJValue(JDWP::JdwpTag tag, const JValue* return_value, JDWP::Expa
}
}
-JDWP::JdwpError Dbg::GetThreadName(JDWP::ObjectId thread_id, std::string& name) {
+JDWP::JdwpError Dbg::GetThreadName(JDWP::ObjectId thread_id, std::string* name) {
ScopedObjectAccessUnchecked soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
+ UNUSED(thread);
if (error != JDWP::ERR_NONE && error != JDWP::ERR_THREAD_NOT_ALIVE) {
return error;
}
// We still need to report the zombie threads' names, so we can't just call Thread::GetThreadName.
- mirror::Object* thread_object = gRegistry->Get<mirror::Object*>(thread_id);
+ mirror::Object* thread_object = gRegistry->Get<mirror::Object*>(thread_id, &error);
+ CHECK(thread_object != nullptr) << error;
mirror::ArtField* java_lang_Thread_name_field =
soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
mirror::String* s =
reinterpret_cast<mirror::String*>(java_lang_Thread_name_field->GetObject(thread_object));
- if (s != NULL) {
- name = s->ToModifiedUtf8();
+ if (s != nullptr) {
+ *name = s->ToModifiedUtf8();
}
return JDWP::ERR_NONE;
}
JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply) {
ScopedObjectAccess soa(Thread::Current());
- mirror::Object* thread_object = gRegistry->Get<mirror::Object*>(thread_id);
- if (thread_object == ObjectRegistry::kInvalidObject) {
+ JDWP::JdwpError error;
+ mirror::Object* thread_object = gRegistry->Get<mirror::Object*>(thread_id, &error);
+ if (error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
const char* old_cause = soa.Self()->StartAssertNoThreadSuspension("Debugger: GetThreadGroup");
// Okay, so it's an object, but is it actually a thread?
- JDWP::JdwpError error;
{
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- error = DecodeThread(soa, thread_id, thread);
+ Thread* thread = DecodeThread(soa, thread_id, &error);
+ UNUSED(thread);
}
if (error == JDWP::ERR_THREAD_NOT_ALIVE) {
// Zombie threads are in the null group.
@@ -1956,13 +1969,14 @@ JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* p
std::string Dbg::GetThreadGroupName(JDWP::ObjectId thread_group_id) {
ScopedObjectAccess soa(Thread::Current());
- mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
- CHECK(thread_group != nullptr);
+ JDWP::JdwpError error;
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id, &error);
+ CHECK(thread_group != nullptr) << error;
const char* old_cause = soa.Self()->StartAssertNoThreadSuspension("Debugger: GetThreadGroupName");
mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ThreadGroup);
CHECK(c != nullptr);
mirror::ArtField* f = c->FindInstanceField("name", "Ljava/lang/String;");
- CHECK(f != NULL);
+ CHECK(f != nullptr);
mirror::String* s = reinterpret_cast<mirror::String*>(f->GetObject(thread_group));
soa.Self()->EndAssertNoThreadSuspension(old_cause);
return s->ToModifiedUtf8();
@@ -1970,13 +1984,14 @@ std::string Dbg::GetThreadGroupName(JDWP::ObjectId thread_group_id) {
JDWP::ObjectId Dbg::GetThreadGroupParent(JDWP::ObjectId thread_group_id) {
ScopedObjectAccessUnchecked soa(Thread::Current());
- mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
- CHECK(thread_group != nullptr);
+ JDWP::JdwpError error;
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id, &error);
+ CHECK(thread_group != nullptr) << error;
const char* old_cause = soa.Self()->StartAssertNoThreadSuspension("Debugger: GetThreadGroupParent");
mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ThreadGroup);
CHECK(c != nullptr);
mirror::ArtField* f = c->FindInstanceField("parent", "Ljava/lang/ThreadGroup;");
- CHECK(f != NULL);
+ CHECK(f != nullptr);
mirror::Object* parent = f->GetObject(thread_group);
soa.Self()->EndAssertNoThreadSuspension(old_cause);
return gRegistry->Add(parent);
@@ -2037,8 +2052,8 @@ JDWP::JdwpError Dbg::GetThreadStatus(JDWP::ObjectId thread_id, JDWP::JdwpThreadS
*pSuspendStatus = JDWP::SUSPEND_STATUS_NOT_SUSPENDED;
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
if (error == JDWP::ERR_THREAD_NOT_ALIVE) {
*pThreadStatus = JDWP::TS_ZOMBIE;
@@ -2058,8 +2073,8 @@ JDWP::JdwpError Dbg::GetThreadStatus(JDWP::ObjectId thread_id, JDWP::JdwpThreadS
JDWP::JdwpError Dbg::GetThreadDebugSuspendCount(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply) {
ScopedObjectAccess soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
return error;
}
@@ -2071,8 +2086,8 @@ JDWP::JdwpError Dbg::GetThreadDebugSuspendCount(JDWP::ObjectId thread_id, JDWP::
JDWP::JdwpError Dbg::Interrupt(JDWP::ObjectId thread_id) {
ScopedObjectAccess soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
return error;
}
@@ -2080,11 +2095,11 @@ JDWP::JdwpError Dbg::Interrupt(JDWP::ObjectId thread_id) {
return JDWP::ERR_NONE;
}
-void Dbg::GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& thread_ids) {
+void Dbg::GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>* thread_ids) {
class ThreadListVisitor {
public:
ThreadListVisitor(const ScopedObjectAccessUnchecked& soa, mirror::Object* desired_thread_group,
- std::vector<JDWP::ObjectId>& thread_ids)
+ std::vector<JDWP::ObjectId>* thread_ids)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: soa_(soa), desired_thread_group_(desired_thread_group), thread_ids_(thread_ids) {}
@@ -2107,15 +2122,15 @@ void Dbg::GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>
}
mirror::Object* peer = t->GetPeer();
if (IsInDesiredThreadGroup(peer)) {
- thread_ids_.push_back(gRegistry->Add(peer));
+ thread_ids_->push_back(gRegistry->Add(peer));
}
}
private:
bool IsInDesiredThreadGroup(mirror::Object* peer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // peer might be NULL if the thread is still starting up.
- if (peer == NULL) {
+ // peer might be nullptr if the thread is still starting up.
+ if (peer == nullptr) {
// We can't tell the debugger about this thread yet.
// TODO: if we identified threads to the debugger by their Thread*
// rather than their peer's mirror::Object*, we could fix this.
@@ -2123,7 +2138,7 @@ void Dbg::GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>
return false;
}
// Do we want threads from all thread groups?
- if (desired_thread_group_ == NULL) {
+ if (desired_thread_group_ == nullptr) {
return true;
}
mirror::Object* group = soa_.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(peer);
@@ -2132,19 +2147,24 @@ void Dbg::GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>
const ScopedObjectAccessUnchecked& soa_;
mirror::Object* const desired_thread_group_;
- std::vector<JDWP::ObjectId>& thread_ids_;
+ std::vector<JDWP::ObjectId>* const thread_ids_;
};
ScopedObjectAccessUnchecked soa(Thread::Current());
- mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
+ JDWP::JdwpError error;
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id, &error);
+ CHECK_EQ(error, JDWP::ERR_NONE);
ThreadListVisitor tlv(soa, thread_group, thread_ids);
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Runtime::Current()->GetThreadList()->ForEach(ThreadListVisitor::Visit, &tlv);
}
-void Dbg::GetChildThreadGroups(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& child_thread_group_ids) {
+void Dbg::GetChildThreadGroups(JDWP::ObjectId thread_group_id,
+ std::vector<JDWP::ObjectId>* child_thread_group_ids) {
ScopedObjectAccess soa(Thread::Current());
- mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
+ JDWP::JdwpError error;
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id, &error);
+ CHECK(thread_group != nullptr) << error;
// Get the ArrayList<ThreadGroup> "groups" out of this thread group...
mirror::ArtField* groups_field = thread_group->GetClass()->FindInstanceField("groups", "Ljava/util/List;");
@@ -2159,15 +2179,14 @@ void Dbg::GetChildThreadGroups(JDWP::ObjectId thread_group_id, std::vector<JDWP:
// Copy the first 'size' elements out of the array into the result.
for (int32_t i = 0; i < size; ++i) {
- child_thread_group_ids.push_back(gRegistry->Add(groups_array->Get(i)));
+ child_thread_group_ids->push_back(gRegistry->Add(groups_array->Get(i)));
}
}
-static int GetStackDepth(Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+static int GetStackDepth(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
struct CountStackDepthVisitor : public StackVisitor {
explicit CountStackDepthVisitor(Thread* thread)
- : StackVisitor(thread, NULL), depth(0) {}
+ : StackVisitor(thread, nullptr), depth(0) {}
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
@@ -2185,18 +2204,19 @@ static int GetStackDepth(Thread* thread)
return visitor.depth;
}
-JDWP::JdwpError Dbg::GetThreadFrameCount(JDWP::ObjectId thread_id, size_t& result) {
+JDWP::JdwpError Dbg::GetThreadFrameCount(JDWP::ObjectId thread_id, size_t* result) {
ScopedObjectAccess soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ *result = 0;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
return error;
}
if (!IsSuspendedForDebugger(soa, thread)) {
return JDWP::ERR_THREAD_NOT_SUSPENDED;
}
- result = GetStackDepth(thread);
+ *result = GetStackDepth(thread);
return JDWP::ERR_NONE;
}
@@ -2206,7 +2226,7 @@ JDWP::JdwpError Dbg::GetThreadFrames(JDWP::ObjectId thread_id, size_t start_fram
public:
GetFrameVisitor(Thread* thread, size_t start_frame, size_t frame_count, JDWP::ExpandBuf* buf)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : StackVisitor(thread, NULL), depth_(0),
+ : StackVisitor(thread, nullptr), depth_(0),
start_frame_(start_frame), frame_count_(frame_count), buf_(buf) {
expandBufAdd4BE(buf_, frame_count_);
}
@@ -2223,7 +2243,7 @@ JDWP::JdwpError Dbg::GetThreadFrames(JDWP::ObjectId thread_id, size_t start_fram
if (depth_ >= start_frame_) {
JDWP::FrameId frame_id(GetFrameId());
JDWP::JdwpLocation location;
- SetLocation(location, GetMethod(), GetDexPc());
+ SetLocation(&location, GetMethod(), GetDexPc());
VLOG(jdwp) << StringPrintf(" Frame %3zd: id=%3" PRIu64 " ", depth_, frame_id) << location;
expandBufAdd8BE(buf_, frame_id);
expandBufAddLocation(buf_, location);
@@ -2241,8 +2261,8 @@ JDWP::JdwpError Dbg::GetThreadFrames(JDWP::ObjectId thread_id, size_t start_fram
ScopedObjectAccessUnchecked soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
return error;
}
@@ -2269,12 +2289,13 @@ void Dbg::ResumeVM() {
JDWP::JdwpError Dbg::SuspendThread(JDWP::ObjectId thread_id, bool request_suspension) {
Thread* self = Thread::Current();
- ScopedLocalRef<jobject> peer(self->GetJniEnv(), NULL);
+ ScopedLocalRef<jobject> peer(self->GetJniEnv(), nullptr);
{
ScopedObjectAccess soa(self);
- peer.reset(soa.AddLocalReference<jobject>(gRegistry->Get<mirror::Object*>(thread_id)));
+ JDWP::JdwpError error;
+ peer.reset(soa.AddLocalReference<jobject>(gRegistry->Get<mirror::Object*>(thread_id, &error)));
}
- if (peer.get() == NULL) {
+ if (peer.get() == nullptr) {
return JDWP::ERR_THREAD_NOT_ALIVE;
}
// Suspend thread to build stack trace. Take suspend thread lock to avoid races with threads
@@ -2284,7 +2305,7 @@ JDWP::JdwpError Dbg::SuspendThread(JDWP::ObjectId thread_id, bool request_suspen
ThreadList* thread_list = Runtime::Current()->GetThreadList();
Thread* thread = thread_list->SuspendThreadByPeer(peer.get(), request_suspension, true,
&timed_out);
- if (thread != NULL) {
+ if (thread != nullptr) {
return JDWP::ERR_NONE;
} else if (timed_out) {
return JDWP::ERR_INTERNAL;
@@ -2295,13 +2316,15 @@ JDWP::JdwpError Dbg::SuspendThread(JDWP::ObjectId thread_id, bool request_suspen
void Dbg::ResumeThread(JDWP::ObjectId thread_id) {
ScopedObjectAccessUnchecked soa(Thread::Current());
- mirror::Object* peer = gRegistry->Get<mirror::Object*>(thread_id);
+ JDWP::JdwpError error;
+ mirror::Object* peer = gRegistry->Get<mirror::Object*>(thread_id, &error);
+ CHECK(peer != nullptr) << error;
Thread* thread;
{
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
thread = Thread::FromManagedThread(soa, peer);
}
- if (thread == NULL) {
+ if (thread == nullptr) {
LOG(WARNING) << "No such thread for resume: " << peer;
return;
}
@@ -2322,7 +2345,7 @@ void Dbg::SuspendSelf() {
struct GetThisVisitor : public StackVisitor {
GetThisVisitor(Thread* thread, Context* context, JDWP::FrameId frame_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : StackVisitor(thread, context), this_object(NULL), frame_id(frame_id) {}
+ : StackVisitor(thread, context), this_object(nullptr), frame_id(frame_id) {}
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
@@ -2345,7 +2368,8 @@ JDWP::JdwpError Dbg::GetThisObject(JDWP::ObjectId thread_id, JDWP::FrameId frame
Thread* thread;
{
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
return error;
}
@@ -2514,8 +2538,8 @@ JDWP::JdwpError Dbg::GetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame
ScopedObjectAccessUnchecked soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
return error;
}
@@ -2596,9 +2620,11 @@ JDWP::JdwpError Dbg::SetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame
case JDWP::JT_THREAD:
case JDWP::JT_THREAD_GROUP: {
CHECK_EQ(width_, sizeof(JDWP::ObjectId));
- mirror::Object* o = gRegistry->Get<mirror::Object*>(static_cast<JDWP::ObjectId>(value_));
- if (o == ObjectRegistry::kInvalidObject) {
- VLOG(jdwp) << tag_ << " object " << o << " is an invalid object";
+ JDWP::JdwpError error;
+ mirror::Object* o =
+ gRegistry->Get<mirror::Object*>(static_cast<JDWP::ObjectId>(value_), &error);
+ if (error != JDWP::ERR_NONE) {
+ VLOG(jdwp) << tag_ << " object " << value_ << " is an invalid object";
error_ = JDWP::ERR_INVALID_OBJECT;
} else if (!SetVReg(m, reg, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(o)),
kReferenceVReg)) {
@@ -2642,8 +2668,8 @@ JDWP::JdwpError Dbg::SetLocalValue(JDWP::ObjectId thread_id, JDWP::FrameId frame
ScopedObjectAccessUnchecked soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
return error;
}
@@ -2674,7 +2700,7 @@ void Dbg::PostLocationEvent(mirror::ArtMethod* m, int dex_pc, mirror::Object* th
DCHECK(m != nullptr);
DCHECK_EQ(m->IsStatic(), this_object == nullptr);
JDWP::JdwpLocation location;
- SetLocation(location, m, dex_pc);
+ SetLocation(&location, m, dex_pc);
// We need 'this' for InstanceOnly filters only.
JDWP::ObjectId this_id = GetThisObjectIdForEvent(this_object);
@@ -2689,7 +2715,7 @@ void Dbg::PostFieldAccessEvent(mirror::ArtMethod* m, int dex_pc,
DCHECK(m != nullptr);
DCHECK(f != nullptr);
JDWP::JdwpLocation location;
- SetLocation(location, m, dex_pc);
+ SetLocation(&location, m, dex_pc);
JDWP::RefTypeId type_id = gRegistry->AddRefType(f->GetDeclaringClass());
JDWP::FieldId field_id = ToFieldId(f);
@@ -2708,7 +2734,7 @@ void Dbg::PostFieldModificationEvent(mirror::ArtMethod* m, int dex_pc,
DCHECK(f != nullptr);
DCHECK(field_value != nullptr);
JDWP::JdwpLocation location;
- SetLocation(location, m, dex_pc);
+ SetLocation(&location, m, dex_pc);
JDWP::RefTypeId type_id = gRegistry->AddRefType(f->GetDeclaringClass());
JDWP::FieldId field_id = ToFieldId(f);
@@ -2725,9 +2751,9 @@ void Dbg::PostException(const ThrowLocation& throw_location,
}
JDWP::JdwpLocation jdwp_throw_location;
- SetLocation(jdwp_throw_location, throw_location.GetMethod(), throw_location.GetDexPc());
+ SetLocation(&jdwp_throw_location, throw_location.GetMethod(), throw_location.GetDexPc());
JDWP::JdwpLocation catch_location;
- SetLocation(catch_location, catch_method, catch_dex_pc);
+ SetLocation(&catch_location, catch_method, catch_dex_pc);
// We need 'this' for InstanceOnly filters only.
JDWP::ObjectId this_id = GetThisObjectIdForEvent(throw_location.GetThis());
@@ -3159,7 +3185,7 @@ class ScopedThreadSuspension {
ScopedObjectAccessUnchecked soa(self);
{
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- error_ = DecodeThread(soa, thread_id, thread_);
+ thread_ = DecodeThread(soa, thread_id, &error_);
}
if (error_ == JDWP::ERR_NONE) {
if (thread_ == soa.Self()) {
@@ -3225,10 +3251,10 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize
explicit SingleStepStackVisitor(Thread* thread, SingleStepControl* single_step_control,
int32_t* line_number)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : StackVisitor(thread, NULL), single_step_control_(single_step_control),
+ : StackVisitor(thread, nullptr), single_step_control_(single_step_control),
line_number_(line_number) {
DCHECK_EQ(single_step_control_, thread->GetSingleStepControl());
- single_step_control_->method = NULL;
+ single_step_control_->method = nullptr;
single_step_control_->stack_depth = 0;
}
@@ -3238,11 +3264,11 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize
mirror::ArtMethod* m = GetMethod();
if (!m->IsRuntimeMethod()) {
++single_step_control_->stack_depth;
- if (single_step_control_->method == NULL) {
+ if (single_step_control_->method == nullptr) {
mirror::DexCache* dex_cache = m->GetDeclaringClass()->GetDexCache();
single_step_control_->method = m;
*line_number_ = -1;
- if (dex_cache != NULL) {
+ if (dex_cache != nullptr) {
const DexFile& dex_file = *dex_cache->GetDexFile();
*line_number_ = dex_file.GetLineNumFromPC(m, GetDexPc());
}
@@ -3315,7 +3341,7 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize
const DexFile::CodeItem* const code_item = m->GetCodeItem();
DebugCallbackContext context(single_step_control, line_number, code_item);
m->GetDexFile()->DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(),
- DebugCallbackContext::Callback, NULL, &context);
+ DebugCallbackContext::Callback, nullptr, &context);
}
//
@@ -3345,8 +3371,8 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize
void Dbg::UnconfigureStep(JDWP::ObjectId thread_id) {
ScopedObjectAccessUnchecked soa(Thread::Current());
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- Thread* thread;
- JDWP::JdwpError error = DecodeThread(soa, thread_id, thread);
+ JDWP::JdwpError error;
+ Thread* thread = DecodeThread(soa, thread_id, &error);
if (error == JDWP::ERR_NONE) {
SingleStepControl* single_step_control = thread->GetSingleStepControl();
DCHECK(single_step_control != nullptr);
@@ -3390,13 +3416,14 @@ JDWP::JdwpError Dbg::InvokeMethod(JDWP::ObjectId thread_id, JDWP::ObjectId objec
JDWP::ObjectId* pExceptionId) {
ThreadList* thread_list = Runtime::Current()->GetThreadList();
- Thread* targetThread = NULL;
- DebugInvokeReq* req = NULL;
+ Thread* targetThread = nullptr;
+ DebugInvokeReq* req = nullptr;
Thread* self = Thread::Current();
{
ScopedObjectAccessUnchecked soa(self);
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
- JDWP::JdwpError error = DecodeThread(soa, thread_id, targetThread);
+ JDWP::JdwpError error;
+ targetThread = DecodeThread(soa, thread_id, &error);
if (error != JDWP::ERR_NONE) {
LOG(ERROR) << "InvokeMethod request for invalid thread id " << thread_id;
return error;
@@ -3431,25 +3458,24 @@ JDWP::JdwpError Dbg::InvokeMethod(JDWP::ObjectId thread_id, JDWP::ObjectId objec
return JDWP::ERR_THREAD_SUSPENDED; // Probably not expected here.
}
- JDWP::JdwpError status;
- mirror::Object* receiver = gRegistry->Get<mirror::Object*>(object_id);
- if (receiver == ObjectRegistry::kInvalidObject) {
+ mirror::Object* receiver = gRegistry->Get<mirror::Object*>(object_id, &error);
+ if (error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
- mirror::Object* thread = gRegistry->Get<mirror::Object*>(thread_id);
- if (thread == ObjectRegistry::kInvalidObject) {
+ mirror::Object* thread = gRegistry->Get<mirror::Object*>(thread_id, &error);
+ if (error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
// TODO: check that 'thread' is actually a java.lang.Thread!
- mirror::Class* c = DecodeClass(class_id, status);
- if (c == NULL) {
- return status;
+ mirror::Class* c = DecodeClass(class_id, &error);
+ if (c == nullptr) {
+ return error;
}
mirror::ArtMethod* m = FromMethodId(method_id);
- if (m->IsStatic() != (receiver == NULL)) {
+ if (m->IsStatic() != (receiver == nullptr)) {
return JDWP::ERR_INVALID_METHODID;
}
if (m->IsStatic()) {
@@ -3483,11 +3509,11 @@ JDWP::JdwpError Dbg::InvokeMethod(JDWP::ObjectId thread_id, JDWP::ObjectId objec
if (shorty[i + 1] == 'L') {
// Did we really get an argument of an appropriate reference type?
mirror::Class* parameter_type = mh.GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
- mirror::Object* argument = gRegistry->Get<mirror::Object*>(arg_values[i]);
- if (argument == ObjectRegistry::kInvalidObject) {
+ mirror::Object* argument = gRegistry->Get<mirror::Object*>(arg_values[i], &error);
+ if (error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
- if (argument != NULL && !argument->InstanceOf(parameter_type)) {
+ if (argument != nullptr && !argument->InstanceOf(parameter_type)) {
return JDWP::ERR_ILLEGAL_ARGUMENT;
}
@@ -3598,7 +3624,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) {
// Translate the method through the vtable, unless the debugger wants to suppress it.
Handle<mirror::ArtMethod> m(hs.NewHandle(pReq->method));
- if ((pReq->options & JDWP::INVOKE_NONVIRTUAL) == 0 && pReq->receiver != NULL) {
+ if ((pReq->options & JDWP::INVOKE_NONVIRTUAL) == 0 && pReq->receiver != nullptr) {
mirror::ArtMethod* actual_method = pReq->klass->FindVirtualMethodForVirtualOrInterface(m.Get());
if (actual_method != m.Get()) {
VLOG(jdwp) << "ExecuteMethod translated " << PrettyMethod(m.Get()) << " to " << PrettyMethod(actual_method);
@@ -3615,7 +3641,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) {
pReq->result_value = InvokeWithJValues(soa, pReq->receiver, soa.EncodeMethod(m.Get()),
reinterpret_cast<jvalue*>(pReq->arg_values));
- mirror::Throwable* exception = soa.Self()->GetException(NULL);
+ mirror::Throwable* exception = soa.Self()->GetException(nullptr);
soa.Self()->ClearException();
pReq->exception = gRegistry->Add(exception);
pReq->result_tag = BasicTagFromDescriptor(m.Get()->GetShorty());
@@ -3643,7 +3669,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) {
gRegistry->Add(pReq->result_value.GetL());
}
- if (old_exception.Get() != NULL) {
+ if (old_exception.Get() != nullptr) {
ThrowLocation gc_safe_throw_location(old_throw_this_object.Get(), old_throw_method.Get(),
old_throw_dex_pc);
soa.Self()->SetException(gc_safe_throw_location, old_exception.Get());
@@ -3662,23 +3688,24 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) {
* OLD-TODO: we currently assume that the request and reply include a single
* chunk. If this becomes inconvenient we will need to adapt.
*/
-bool Dbg::DdmHandlePacket(JDWP::Request& request, uint8_t** pReplyBuf, int* pReplyLen) {
+bool Dbg::DdmHandlePacket(JDWP::Request* request, uint8_t** pReplyBuf, int* pReplyLen) {
Thread* self = Thread::Current();
JNIEnv* env = self->GetJniEnv();
- uint32_t type = request.ReadUnsigned32("type");
- uint32_t length = request.ReadUnsigned32("length");
+ uint32_t type = request->ReadUnsigned32("type");
+ uint32_t length = request->ReadUnsigned32("length");
// Create a byte[] corresponding to 'request'.
- size_t request_length = request.size();
+ size_t request_length = request->size();
ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(request_length));
- if (dataArray.get() == NULL) {
+ if (dataArray.get() == nullptr) {
LOG(WARNING) << "byte[] allocation failed: " << request_length;
env->ExceptionClear();
return false;
}
- env->SetByteArrayRegion(dataArray.get(), 0, request_length, reinterpret_cast<const jbyte*>(request.data()));
- request.Skip(request_length);
+ env->SetByteArrayRegion(dataArray.get(), 0, request_length,
+ reinterpret_cast<const jbyte*>(request->data()));
+ request->Skip(request_length);
// Run through and find all chunks. [Currently just find the first.]
ScopedByteArrayRO contents(env, dataArray.get());
@@ -3698,7 +3725,7 @@ bool Dbg::DdmHandlePacket(JDWP::Request& request, uint8_t** pReplyBuf, int* pRep
return false;
}
- if (chunk.get() == NULL) {
+ if (chunk.get() == nullptr) {
return false;
}
@@ -3720,13 +3747,13 @@ bool Dbg::DdmHandlePacket(JDWP::Request& request, uint8_t** pReplyBuf, int* pRep
type = env->GetIntField(chunk.get(), WellKnownClasses::org_apache_harmony_dalvik_ddmc_Chunk_type);
VLOG(jdwp) << StringPrintf("DDM reply: type=0x%08x data=%p offset=%d length=%d", type, replyData.get(), offset, length);
- if (length == 0 || replyData.get() == NULL) {
+ if (length == 0 || replyData.get() == nullptr) {
return false;
}
const int kChunkHdrLen = 8;
uint8_t* reply = new uint8_t[length + kChunkHdrLen];
- if (reply == NULL) {
+ if (reply == nullptr) {
LOG(WARNING) << "malloc failed: " << (length + kChunkHdrLen);
return false;
}
@@ -3791,8 +3818,8 @@ void Dbg::DdmSendThreadNotification(Thread* t, uint32_t type) {
ScopedObjectAccessUnchecked soa(Thread::Current());
StackHandleScope<1> hs(soa.Self());
Handle<mirror::String> name(hs.NewHandle(t->GetThreadName(soa)));
- size_t char_count = (name.Get() != NULL) ? name->GetLength() : 0;
- const jchar* chars = (name.Get() != NULL) ? name->GetCharArray()->GetData() : NULL;
+ size_t char_count = (name.Get() != nullptr) ? name->GetLength() : 0;
+ const jchar* chars = (name.Get() != nullptr) ? name->GetCharArray()->GetData() : nullptr;
std::vector<uint8_t> bytes;
JDWP::Append4BE(bytes, t->GetThreadId());
@@ -3844,7 +3871,7 @@ void Dbg::PostThreadDeath(Thread* t) {
}
void Dbg::DdmSendChunk(uint32_t type, size_t byte_count, const uint8_t* buf) {
- CHECK(buf != NULL);
+ CHECK(buf != nullptr);
iovec vec[1];
vec[0].iov_base = reinterpret_cast<void*>(const_cast<uint8_t*>(buf));
vec[0].iov_len = byte_count;
@@ -3856,7 +3883,7 @@ void Dbg::DdmSendChunk(uint32_t type, const std::vector<uint8_t>& bytes) {
}
void Dbg::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) {
- if (gJdwpState == NULL) {
+ if (gJdwpState == nullptr) {
VLOG(jdwp) << "Debugger thread not active, ignoring DDM send: " << type;
} else {
gJdwpState->DdmSendChunkV(type, iov, iov_count);
@@ -4013,7 +4040,7 @@ class HeapChunkContext {
}
void Flush() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (pieceLenField_ == NULL) {
+ if (pieceLenField_ == nullptr) {
// Flush immediately post Reset (maybe back-to-back Flush). Ignore.
CHECK(needHeader_);
return;
@@ -4041,7 +4068,7 @@ class HeapChunkContext {
ResetStartOfNextChunk();
totalAllocationUnits_ = 0;
needHeader_ = true;
- pieceLenField_ = NULL;
+ pieceLenField_ = nullptr;
}
void HeapChunkCallback(void* start, void* /*end*/, size_t used_bytes)
@@ -4050,9 +4077,9 @@ class HeapChunkContext {
// Note: heap call backs cannot manipulate the heap upon which they are crawling, care is taken
// in the following code not to allocate memory, by ensuring buf_ is of the correct size
if (used_bytes == 0) {
- if (start == NULL) {
+ if (start == nullptr) {
// Reset for start of new heap.
- startOfNextMemoryChunk_ = NULL;
+ startOfNextMemoryChunk_ = nullptr;
Flush();
}
// Only process in use memory so that free region information
@@ -4067,7 +4094,7 @@ class HeapChunkContext {
// TODO: I'm not sure using start of next chunk works well with multiple spaces. We shouldn't
// count gaps inbetween spaces as free memory.
- if (startOfNextMemoryChunk_ != NULL) {
+ if (startOfNextMemoryChunk_ != nullptr) {
// Transmit any pending free memory. Native free memory of
// over kMaxFreeLen could be because of the use of mmaps, so
// don't report. If not free memory then start a new segment.
@@ -4083,7 +4110,7 @@ class HeapChunkContext {
}
}
if (flush) {
- startOfNextMemoryChunk_ = NULL;
+ startOfNextMemoryChunk_ = nullptr;
Flush();
}
}
@@ -4129,7 +4156,7 @@ class HeapChunkContext {
uint8_t ExamineObject(mirror::Object* o, bool is_native_heap)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
- if (o == NULL) {
+ if (o == nullptr) {
return HPSG_STATE(SOLIDITY_FREE, 0);
}
@@ -4146,7 +4173,7 @@ class HeapChunkContext {
}
mirror::Class* c = o->GetClass();
- if (c == NULL) {
+ if (c == nullptr) {
// The object was probably just created but hasn't been initialized yet.
return HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT);
}
@@ -4295,14 +4322,14 @@ void Dbg::SetAllocTrackingEnabled(bool enabled) {
if (enabled) {
{
MutexLock mu(Thread::Current(), *alloc_tracker_lock_);
- if (recent_allocation_records_ == NULL) {
+ if (recent_allocation_records_ == nullptr) {
alloc_record_max_ = GetAllocTrackerMax();
LOG(INFO) << "Enabling alloc tracker (" << alloc_record_max_ << " entries of "
<< kMaxAllocRecordStackDepth << " frames, taking "
<< PrettySize(sizeof(AllocRecord) * alloc_record_max_) << ")";
alloc_record_head_ = alloc_record_count_ = 0;
recent_allocation_records_ = new AllocRecord[alloc_record_max_];
- CHECK(recent_allocation_records_ != NULL);
+ CHECK(recent_allocation_records_ != nullptr);
}
}
Runtime::Current()->GetInstrumentation()->InstrumentQuickAllocEntryPoints();
@@ -4312,7 +4339,7 @@ void Dbg::SetAllocTrackingEnabled(bool enabled) {
MutexLock mu(Thread::Current(), *alloc_tracker_lock_);
LOG(INFO) << "Disabling alloc tracker";
delete[] recent_allocation_records_;
- recent_allocation_records_ = NULL;
+ recent_allocation_records_ = nullptr;
type_cache_.Clear();
}
}
@@ -4321,7 +4348,7 @@ void Dbg::SetAllocTrackingEnabled(bool enabled) {
struct AllocRecordStackVisitor : public StackVisitor {
AllocRecordStackVisitor(Thread* thread, AllocRecord* record)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : StackVisitor(thread, NULL), record(record), depth(0) {}
+ : StackVisitor(thread, nullptr), record(record), depth(0) {}
// TODO: Enable annotalysis. We know lock is held in constructor, but abstraction confuses
// annotalysis.
@@ -4352,10 +4379,10 @@ struct AllocRecordStackVisitor : public StackVisitor {
void Dbg::RecordAllocation(mirror::Class* type, size_t byte_count) {
Thread* self = Thread::Current();
- CHECK(self != NULL);
+ CHECK(self != nullptr);
MutexLock mu(self, *alloc_tracker_lock_);
- if (recent_allocation_records_ == NULL) {
+ if (recent_allocation_records_ == nullptr) {
return;
}
@@ -4395,7 +4422,7 @@ size_t Dbg::HeadIndex() {
void Dbg::DumpRecentAllocations() {
ScopedObjectAccess soa(Thread::Current());
MutexLock mu(soa.Self(), *alloc_tracker_lock_);
- if (recent_allocation_records_ == NULL) {
+ if (recent_allocation_records_ == nullptr) {
LOG(INFO) << "Not recording tracked allocations";
return;
}
@@ -4415,7 +4442,7 @@ void Dbg::DumpRecentAllocations() {
for (size_t stack_frame = 0; stack_frame < kMaxAllocRecordStackDepth; ++stack_frame) {
AllocRecordStackTraceElement* stack_element = record->StackElement(stack_frame);
mirror::ArtMethod* m = stack_element->Method();
- if (m == NULL) {
+ if (m == nullptr) {
break;
}
LOG(INFO) << " " << PrettyMethod(m) << " line " << stack_element->LineNumber();
@@ -4543,7 +4570,7 @@ jbyteArray Dbg::GetRecentAllocations() {
class_names.Add(record->Type()->GetDescriptor(&temp));
for (size_t i = 0; i < kMaxAllocRecordStackDepth; i++) {
mirror::ArtMethod* m = record->StackElement(i)->Method();
- if (m != NULL) {
+ if (m != nullptr) {
class_names.Add(m->GetDeclaringClassDescriptor());
method_names.Add(m->GetName());
filenames.Add(GetMethodSourceFile(m));
@@ -4626,7 +4653,7 @@ jbyteArray Dbg::GetRecentAllocations() {
}
JNIEnv* env = self->GetJniEnv();
jbyteArray result = env->NewByteArray(bytes.size());
- if (result != NULL) {
+ if (result != nullptr) {
env->SetByteArrayRegion(result, 0, bytes.size(), reinterpret_cast<const jbyte*>(&bytes[0]));
}
return result;
diff --git a/runtime/debugger.h b/runtime/debugger.h
index 1d3668c1f6..52ae7a916d 100644
--- a/runtime/debugger.h
+++ b/runtime/debugger.h
@@ -248,9 +248,9 @@ class Dbg {
*/
static std::string GetClassName(JDWP::RefTypeId id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& class_object_id)
+ static JDWP::JdwpError GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId* class_object_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclass_id)
+ static JDWP::JdwpError GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId* superclass_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -258,38 +258,38 @@ class Dbg {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void GetClassList(std::vector<JDWP::RefTypeId>& classes)
+ static void GetClassList(std::vector<JDWP::RefTypeId>* classes)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag,
uint32_t* pStatus, std::string* pDescriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids)
+ static void FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>* ids)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetSignature(JDWP::RefTypeId ref_type_id, std::string* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId ref_type_id, std::string& source_file)
+ static JDWP::JdwpError GetSourceFile(JDWP::RefTypeId ref_type_id, std::string* source_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static JDWP::JdwpError GetObjectTag(JDWP::ObjectId object_id, uint8_t& tag)
+ static JDWP::JdwpError GetObjectTag(JDWP::ObjectId object_id, uint8_t* tag)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static size_t GetTagWidth(JDWP::JdwpTag tag);
- static JDWP::JdwpError GetArrayLength(JDWP::ObjectId array_id, int& length)
+ static JDWP::JdwpError GetArrayLength(JDWP::ObjectId array_id, int32_t* length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError OutputArray(JDWP::ObjectId array_id, int offset, int count,
JDWP::ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError SetArrayElements(JDWP::ObjectId array_id, int offset, int count,
- JDWP::Request& request)
+ JDWP::Request* request)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::ObjectId CreateString(const std::string& str)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static JDWP::JdwpError CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId& new_object)
+ static JDWP::JdwpError CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId* new_object)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length,
- JDWP::ObjectId& new_array)
+ JDWP::ObjectId* new_array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static bool MatchType(JDWP::RefTypeId instance_class_id, JDWP::RefTypeId class_id)
@@ -301,12 +301,12 @@ class Dbg {
static JDWP::JdwpError GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetOwnedMonitors(JDWP::ObjectId thread_id,
- std::vector<JDWP::ObjectId>& monitors,
- std::vector<uint32_t>& stack_depths)
+ std::vector<JDWP::ObjectId>* monitors,
+ std::vector<uint32_t>* stack_depths)
LOCKS_EXCLUDED(Locks::thread_list_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetContendedMonitor(JDWP::ObjectId thread_id,
- JDWP::ObjectId& contended_monitor)
+ JDWP::ObjectId* contended_monitor)
LOCKS_EXCLUDED(Locks::thread_list_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -314,19 +314,19 @@ class Dbg {
// Heap.
//
static JDWP::JdwpError GetInstanceCounts(const std::vector<JDWP::RefTypeId>& class_ids,
- std::vector<uint64_t>& counts)
+ std::vector<uint64_t>* counts)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetInstances(JDWP::RefTypeId class_id, int32_t max_count,
- std::vector<JDWP::ObjectId>& instances)
+ std::vector<JDWP::ObjectId>* instances)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetReferringObjects(JDWP::ObjectId object_id, int32_t max_count,
- std::vector<JDWP::ObjectId>& referring_objects)
+ std::vector<JDWP::ObjectId>* referring_objects)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError DisableCollection(JDWP::ObjectId object_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError EnableCollection(JDWP::ObjectId object_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static JDWP::JdwpError IsCollected(JDWP::ObjectId object_id, bool& is_collected)
+ static JDWP::JdwpError IsCollected(JDWP::ObjectId object_id, bool* is_collected)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void DisposeObject(JDWP::ObjectId object_id, uint32_t reference_count)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -358,7 +358,7 @@ class Dbg {
JDWP::ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static JDWP::JdwpError GetBytecodes(JDWP::RefTypeId class_id, JDWP::MethodId method_id,
- std::vector<uint8_t>& bytecodes)
+ std::vector<uint8_t>* bytecodes)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static std::string GetFieldName(JDWP::FieldId field_id)
@@ -387,7 +387,7 @@ class Dbg {
/*
* Thread, ThreadGroup, Frame
*/
- static JDWP::JdwpError GetThreadName(JDWP::ObjectId thread_id, std::string& name)
+ static JDWP::JdwpError GetThreadName(JDWP::ObjectId thread_id, std::string* name)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
LOCKS_EXCLUDED(Locks::thread_list_lock_);
static JDWP::JdwpError GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply)
@@ -412,12 +412,13 @@ class Dbg {
// Fills 'thread_ids' with the threads in the given thread group. If thread_group_id == 0,
// returns all threads.
- static void GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& thread_ids)
+ static void GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>* thread_ids)
LOCKS_EXCLUDED(Locks::thread_list_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void GetChildThreadGroups(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& child_thread_group_ids);
+ static void GetChildThreadGroups(JDWP::ObjectId thread_group_id,
+ std::vector<JDWP::ObjectId>* child_thread_group_ids);
- static JDWP::JdwpError GetThreadFrameCount(JDWP::ObjectId thread_id, size_t& result)
+ static JDWP::JdwpError GetThreadFrameCount(JDWP::ObjectId thread_id, size_t* result)
LOCKS_EXCLUDED(Locks::thread_list_lock_);
static JDWP::JdwpError GetThreadFrames(JDWP::ObjectId thread_id, size_t start_frame,
size_t frame_count, JDWP::ExpandBuf* buf)
@@ -542,7 +543,7 @@ class Dbg {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void DdmSetThreadNotification(bool enable)
LOCKS_EXCLUDED(Locks::thread_list_lock_);
- static bool DdmHandlePacket(JDWP::Request& request, uint8_t** pReplyBuf, int* pReplyLen);
+ static bool DdmHandlePacket(JDWP::Request* request, uint8_t** pReplyBuf, int* pReplyLen);
static void DdmConnected() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void DdmDisconnected() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void DdmSendChunk(uint32_t type, const std::vector<uint8_t>& bytes)
@@ -595,8 +596,8 @@ class Dbg {
static void DdmSendHeapSegments(bool native)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static TypeCache& GetTypeCache() {
- return type_cache_;
+ static TypeCache* GetTypeCache() {
+ return &type_cache_;
}
private:
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index cf89850fa2..e1c532ece4 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -220,21 +220,18 @@ void ThrowStackOverflowError(Thread* self) {
}
void CheckReferenceResult(mirror::Object* o, Thread* self) {
- if (o == NULL) {
+ if (o == nullptr) {
return;
}
- mirror::ArtMethod* m = self->GetCurrentMethod(NULL);
- if (o == kInvalidIndirectRefObject) {
- Runtime::Current()->GetJavaVM()->JniAbortF(NULL, "invalid reference returned from %s",
- PrettyMethod(m).c_str());
- }
+ mirror::ArtMethod* m = self->GetCurrentMethod(nullptr);
// Make sure that the result is an instance of the type this method was expected to return.
StackHandleScope<1> hs(self);
Handle<mirror::ArtMethod> h_m(hs.NewHandle(m));
mirror::Class* return_type = MethodHelper(h_m).GetReturnType();
if (!o->InstanceOf(return_type)) {
- Runtime::Current()->GetJavaVM()->JniAbortF(NULL, "attempt to return an instance of %s from %s",
+ Runtime::Current()->GetJavaVM()->JniAbortF(nullptr,
+ "attempt to return an instance of %s from %s",
PrettyTypeOf(o).c_str(),
PrettyMethod(h_m.Get()).c_str());
}
diff --git a/runtime/indirect_reference_table-inl.h b/runtime/indirect_reference_table-inl.h
index 00f7b06f1b..9bf3ea258d 100644
--- a/runtime/indirect_reference_table-inl.h
+++ b/runtime/indirect_reference_table-inl.h
@@ -19,6 +19,7 @@
#include "indirect_reference_table.h"
+#include "runtime-inl.h"
#include "verify_object-inl.h"
namespace art {
@@ -26,6 +27,15 @@ namespace mirror {
class Object;
} // namespace mirror
+inline void IrtIterator::SkipNullsAndTombstones() {
+ // We skip NULLs and tombstones. Clients don't want to see implementation details.
+ while (i_ < capacity_ &&
+ (table_[i_].IsNull() ||
+ Runtime::Current()->IsClearedJniWeakGlobal(table_[i_].Read<kWithoutReadBarrier>()))) {
+ ++i_;
+ }
+}
+
// Verifies that the indirect table lookup is valid.
// Returns "false" if something looks bad.
inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const {
@@ -73,15 +83,11 @@ inline bool IndirectReferenceTable::CheckEntry(const char* what, IndirectRef ire
template<ReadBarrierOption kReadBarrierOption>
inline mirror::Object* IndirectReferenceTable::Get(IndirectRef iref) const {
if (!GetChecked(iref)) {
- return kInvalidIndirectRefObject;
+ return nullptr;
}
uint32_t idx = ExtractIndex(iref);
- mirror::Object* obj = table_[idx].Read<kWithoutReadBarrier>();
- if (LIKELY(obj != kClearedJniWeakGlobal)) {
- // The read barrier or VerifyObject won't handle kClearedJniWeakGlobal.
- obj = table_[idx].Read<kReadBarrierOption>();
- VerifyObject(obj);
- }
+ mirror::Object* obj = table_[idx].Read<kReadBarrierOption>();
+ VerifyObject(obj);
return obj;
}
diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc
index 1ba2291adf..49bffa404e 100644
--- a/runtime/indirect_reference_table.cc
+++ b/runtime/indirect_reference_table.cc
@@ -276,10 +276,6 @@ void IndirectReferenceTable::Dump(std::ostream& os) const {
mirror::Object* obj = table_[i].Read<kWithoutReadBarrier>();
if (UNLIKELY(obj == nullptr)) {
// Remove NULLs.
- } else if (UNLIKELY(obj == kClearedJniWeakGlobal)) {
- // ReferenceTable::Dump() will handle kClearedJniWeakGlobal
- // while the read barrier won't.
- entries.push_back(GcRoot<mirror::Object>(obj));
} else {
obj = table_[i].Read();
entries.push_back(GcRoot<mirror::Object>(obj));
diff --git a/runtime/indirect_reference_table.h b/runtime/indirect_reference_table.h
index d25bc42dfc..562ba1e8df 100644
--- a/runtime/indirect_reference_table.h
+++ b/runtime/indirect_reference_table.h
@@ -105,10 +105,6 @@ class MemMap;
*/
typedef void* IndirectRef;
-// Magic failure values; must not pass Heap::ValidateObject() or Heap::IsHeapAddress().
-static mirror::Object* const kInvalidIndirectRefObject = reinterpret_cast<mirror::Object*>(0xdead4321);
-static mirror::Object* const kClearedJniWeakGlobal = reinterpret_cast<mirror::Object*>(0xdead1234);
-
/*
* Indirect reference kind, used as the two low bits of IndirectRef.
*
@@ -229,18 +225,11 @@ class IrtIterator {
}
private:
- void SkipNullsAndTombstones() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // We skip NULLs and tombstones. Clients don't want to see implementation details.
- while (i_ < capacity_ &&
- (table_[i_].IsNull() ||
- table_[i_].Read<kWithoutReadBarrier>() == kClearedJniWeakGlobal)) {
- ++i_;
- }
- }
+ void SkipNullsAndTombstones() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
GcRoot<mirror::Object>* const table_;
size_t i_;
- size_t capacity_;
+ const size_t capacity_;
};
bool inline operator==(const IrtIterator& lhs, const IrtIterator& rhs) {
diff --git a/runtime/indirect_reference_table_test.cc b/runtime/indirect_reference_table_test.cc
index a33a981545..99ee597bb8 100644
--- a/runtime/indirect_reference_table_test.cc
+++ b/runtime/indirect_reference_table_test.cc
@@ -49,15 +49,15 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
IndirectReferenceTable irt(kTableInitial, kTableMax, kGlobal);
mirror::Class* c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
- ASSERT_TRUE(c != NULL);
+ ASSERT_TRUE(c != nullptr);
mirror::Object* obj0 = c->AllocObject(soa.Self());
- ASSERT_TRUE(obj0 != NULL);
+ ASSERT_TRUE(obj0 != nullptr);
mirror::Object* obj1 = c->AllocObject(soa.Self());
- ASSERT_TRUE(obj1 != NULL);
+ ASSERT_TRUE(obj1 != nullptr);
mirror::Object* obj2 = c->AllocObject(soa.Self());
- ASSERT_TRUE(obj2 != NULL);
+ ASSERT_TRUE(obj2 != nullptr);
mirror::Object* obj3 = c->AllocObject(soa.Self());
- ASSERT_TRUE(obj3 != NULL);
+ ASSERT_TRUE(obj3 != nullptr);
const uint32_t cookie = IRT_FIRST_SEGMENT;
@@ -68,13 +68,13 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
// Add three, check, remove in the order in which they were added.
iref0 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref0 != NULL);
+ EXPECT_TRUE(iref0 != nullptr);
CheckDump(&irt, 1, 1);
IndirectRef iref1 = irt.Add(cookie, obj1);
- EXPECT_TRUE(iref1 != NULL);
+ EXPECT_TRUE(iref1 != nullptr);
CheckDump(&irt, 2, 2);
IndirectRef iref2 = irt.Add(cookie, obj2);
- EXPECT_TRUE(iref2 != NULL);
+ EXPECT_TRUE(iref2 != nullptr);
CheckDump(&irt, 3, 3);
EXPECT_EQ(obj0, irt.Get(iref0));
@@ -92,15 +92,15 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
EXPECT_EQ(0U, irt.Capacity());
// Get invalid entry (off the end of the list).
- EXPECT_EQ(kInvalidIndirectRefObject, irt.Get(iref0));
+ EXPECT_TRUE(irt.Get(iref0) == nullptr);
// Add three, remove in the opposite order.
iref0 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref0 != NULL);
+ EXPECT_TRUE(iref0 != nullptr);
iref1 = irt.Add(cookie, obj1);
- EXPECT_TRUE(iref1 != NULL);
+ EXPECT_TRUE(iref1 != nullptr);
iref2 = irt.Add(cookie, obj2);
- EXPECT_TRUE(iref2 != NULL);
+ EXPECT_TRUE(iref2 != nullptr);
CheckDump(&irt, 3, 3);
ASSERT_TRUE(irt.Remove(cookie, iref2));
@@ -116,11 +116,11 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
// Add three, remove middle / middle / bottom / top. (Second attempt
// to remove middle should fail.)
iref0 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref0 != NULL);
+ EXPECT_TRUE(iref0 != nullptr);
iref1 = irt.Add(cookie, obj1);
- EXPECT_TRUE(iref1 != NULL);
+ EXPECT_TRUE(iref1 != nullptr);
iref2 = irt.Add(cookie, obj2);
- EXPECT_TRUE(iref2 != NULL);
+ EXPECT_TRUE(iref2 != nullptr);
CheckDump(&irt, 3, 3);
ASSERT_EQ(3U, irt.Capacity());
@@ -131,7 +131,7 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
CheckDump(&irt, 2, 2);
// Get invalid entry (from hole).
- EXPECT_EQ(kInvalidIndirectRefObject, irt.Get(iref1));
+ EXPECT_TRUE(irt.Get(iref1) == nullptr);
ASSERT_TRUE(irt.Remove(cookie, iref2));
CheckDump(&irt, 1, 1);
@@ -145,20 +145,20 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
// is still 4 (i.e. holes are getting filled). Remove #1 and #3, verify
// that we delete one and don't hole-compact the other.
iref0 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref0 != NULL);
+ EXPECT_TRUE(iref0 != nullptr);
iref1 = irt.Add(cookie, obj1);
- EXPECT_TRUE(iref1 != NULL);
+ EXPECT_TRUE(iref1 != nullptr);
iref2 = irt.Add(cookie, obj2);
- EXPECT_TRUE(iref2 != NULL);
+ EXPECT_TRUE(iref2 != nullptr);
IndirectRef iref3 = irt.Add(cookie, obj3);
- EXPECT_TRUE(iref3 != NULL);
+ EXPECT_TRUE(iref3 != nullptr);
CheckDump(&irt, 4, 4);
ASSERT_TRUE(irt.Remove(cookie, iref1));
CheckDump(&irt, 3, 3);
iref1 = irt.Add(cookie, obj1);
- EXPECT_TRUE(iref1 != NULL);
+ EXPECT_TRUE(iref1 != nullptr);
ASSERT_EQ(4U, irt.Capacity()) << "hole not filled";
CheckDump(&irt, 4, 4);
@@ -181,12 +181,12 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
// iref. They have the same slot number but are for different objects.
// With the extended checks in place, this should fail.
iref0 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref0 != NULL);
+ EXPECT_TRUE(iref0 != nullptr);
CheckDump(&irt, 1, 1);
ASSERT_TRUE(irt.Remove(cookie, iref0));
CheckDump(&irt, 0, 0);
iref1 = irt.Add(cookie, obj1);
- EXPECT_TRUE(iref1 != NULL);
+ EXPECT_TRUE(iref1 != nullptr);
CheckDump(&irt, 1, 1);
ASSERT_FALSE(irt.Remove(cookie, iref0)) << "mismatched del succeeded";
CheckDump(&irt, 1, 1);
@@ -197,12 +197,12 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
// Same as above, but with the same object. A more rigorous checker
// (e.g. with slot serialization) will catch this.
iref0 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref0 != NULL);
+ EXPECT_TRUE(iref0 != nullptr);
CheckDump(&irt, 1, 1);
ASSERT_TRUE(irt.Remove(cookie, iref0));
CheckDump(&irt, 0, 0);
iref1 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref1 != NULL);
+ EXPECT_TRUE(iref1 != nullptr);
CheckDump(&irt, 1, 1);
if (iref0 != iref1) {
// Try 0, should not work.
@@ -212,15 +212,15 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
ASSERT_EQ(0U, irt.Capacity()) << "temporal del not empty";
CheckDump(&irt, 0, 0);
- // NULL isn't a valid iref.
- ASSERT_EQ(kInvalidIndirectRefObject, irt.Get(NULL));
+ // nullptr isn't a valid iref.
+ ASSERT_TRUE(irt.Get(nullptr) == nullptr);
// Stale lookup.
iref0 = irt.Add(cookie, obj0);
- EXPECT_TRUE(iref0 != NULL);
+ EXPECT_TRUE(iref0 != nullptr);
CheckDump(&irt, 1, 1);
ASSERT_TRUE(irt.Remove(cookie, iref0));
- EXPECT_EQ(kInvalidIndirectRefObject, irt.Get(iref0)) << "stale lookup succeeded";
+ EXPECT_TRUE(irt.Get(iref0) == nullptr) << "stale lookup succeeded";
CheckDump(&irt, 0, 0);
// Test table resizing.
@@ -228,12 +228,12 @@ TEST_F(IndirectReferenceTableTest, BasicTest) {
IndirectRef manyRefs[kTableInitial];
for (size_t i = 0; i < kTableInitial; i++) {
manyRefs[i] = irt.Add(cookie, obj0);
- ASSERT_TRUE(manyRefs[i] != NULL) << "Failed adding " << i;
+ ASSERT_TRUE(manyRefs[i] != nullptr) << "Failed adding " << i;
CheckDump(&irt, i + 1, 1);
}
// ...this one causes overflow.
iref0 = irt.Add(cookie, obj0);
- ASSERT_TRUE(iref0 != NULL);
+ ASSERT_TRUE(iref0 != nullptr);
ASSERT_EQ(kTableInitial + 1, irt.Capacity());
CheckDump(&irt, kTableInitial + 1, 1);
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index dd3b7cf2b2..424addb2a8 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -28,6 +28,7 @@
#include "nativebridge/native_bridge.h"
#include "java_vm_ext.h"
#include "parsed_options.h"
+#include "runtime-inl.h"
#include "ScopedLocalRef.h"
#include "scoped_thread_state_change.h"
#include "thread-inl.h"
@@ -761,7 +762,7 @@ void JavaVMExt::SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg) {
mirror::Object* obj = *entry;
mirror::Object* new_obj = callback(obj, arg);
if (new_obj == nullptr) {
- new_obj = kClearedJniWeakGlobal;
+ new_obj = Runtime::Current()->GetClearedJniWeakGlobal();
}
*entry = new_obj;
}
diff --git a/runtime/jdwp/jdwp.h b/runtime/jdwp/jdwp.h
index 8fd07cc11b..b5b6298b84 100644
--- a/runtime/jdwp/jdwp.h
+++ b/runtime/jdwp/jdwp.h
@@ -285,7 +285,7 @@ struct JdwpState {
private:
explicit JdwpState(const JdwpOptions* options);
- size_t ProcessRequest(Request& request, ExpandBuf* pReply);
+ size_t ProcessRequest(Request* request, ExpandBuf* pReply);
bool InvokeInProgress();
bool IsConnected();
void SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id)
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index 36fbed4ea2..fc39cc48d0 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -781,7 +781,7 @@ static void LogMatchingEventsAndThread(JdwpEvent** match_list, size_t match_coun
<< StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId);
}
std::string thread_name;
- JdwpError error = Dbg::GetThreadName(basket.threadId, thread_name);
+ JdwpError error = Dbg::GetThreadName(basket.threadId, &thread_name);
if (error != JDWP::ERR_NONE) {
thread_name = "<unknown>";
}
@@ -924,7 +924,7 @@ bool JdwpState::PostFieldEvent(const JdwpLocation* pLoc, RefTypeId typeId, Field
// Get instance type tag.
uint8_t tag;
- error = Dbg::GetObjectTag(thisPtr, tag);
+ error = Dbg::GetObjectTag(thisPtr, &tag);
if (error != ERR_NONE) {
return false;
}
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 330d235c03..35095f95ca 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -65,7 +65,7 @@ static void WriteValue(ExpandBuf* pReply, int width, uint64_t value) {
static JdwpError WriteTaggedObject(ExpandBuf* reply, ObjectId object_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
uint8_t tag;
- JdwpError rc = Dbg::GetObjectTag(object_id, tag);
+ JdwpError rc = Dbg::GetObjectTag(object_id, &tag);
if (rc == ERR_NONE) {
expandBufAdd1(reply, tag);
expandBufAddObjectId(reply, object_id);
@@ -91,13 +91,13 @@ static JdwpError WriteTaggedObjectList(ExpandBuf* reply, const std::vector<Objec
* If "is_constructor" is set, this returns "object_id" rather than the
* expected-to-be-void return value of the called function.
*/
-static JdwpError FinishInvoke(JdwpState*, Request& request, ExpandBuf* pReply,
+static JdwpError FinishInvoke(JdwpState*, Request* request, ExpandBuf* pReply,
ObjectId thread_id, ObjectId object_id,
RefTypeId class_id, MethodId method_id, bool is_constructor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(!is_constructor || object_id != 0);
- int32_t arg_count = request.ReadSigned32("argument count");
+ int32_t arg_count = request->ReadSigned32("argument count");
VLOG(jdwp) << StringPrintf(" --> thread_id=%#" PRIx64 " object_id=%#" PRIx64,
thread_id, object_id);
@@ -109,14 +109,14 @@ static JdwpError FinishInvoke(JdwpState*, Request& request, ExpandBuf* pReply,
std::unique_ptr<JdwpTag[]> argTypes(arg_count > 0 ? new JdwpTag[arg_count] : NULL);
std::unique_ptr<uint64_t[]> argValues(arg_count > 0 ? new uint64_t[arg_count] : NULL);
for (int32_t i = 0; i < arg_count; ++i) {
- argTypes[i] = request.ReadTag();
+ argTypes[i] = request->ReadTag();
size_t width = Dbg::GetTagWidth(argTypes[i]);
- argValues[i] = request.ReadValue(width);
+ argValues[i] = request->ReadValue(width);
VLOG(jdwp) << " " << argTypes[i] << StringPrintf("(%zd): %#" PRIx64, width,
argValues[i]);
}
- uint32_t options = request.ReadUnsigned32("InvokeOptions bit flags");
+ uint32_t options = request->ReadUnsigned32("InvokeOptions bit flags");
VLOG(jdwp) << StringPrintf(" options=0x%04x%s%s", options,
(options & INVOKE_SINGLE_THREADED) ? " (SINGLE_THREADED)" : "",
(options & INVOKE_NONVIRTUAL) ? " (NONVIRTUAL)" : "");
@@ -161,7 +161,7 @@ static JdwpError FinishInvoke(JdwpState*, Request& request, ExpandBuf* pReply,
return err;
}
-static JdwpError VM_Version(JdwpState*, Request&, ExpandBuf* pReply)
+static JdwpError VM_Version(JdwpState*, Request*, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Text information on runtime version.
std::string version(StringPrintf("Android Runtime %s", Runtime::Current()->GetVersion()));
@@ -185,12 +185,12 @@ static JdwpError VM_Version(JdwpState*, Request&, ExpandBuf* pReply)
* referenceTypeID. We need to send back more than one if the class has
* been loaded by multiple class loaders.
*/
-static JdwpError VM_ClassesBySignature(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError VM_ClassesBySignature(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::string classDescriptor(request.ReadUtf8String());
+ std::string classDescriptor(request->ReadUtf8String());
std::vector<RefTypeId> ids;
- Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), ids);
+ Dbg::FindLoadedClassBySignature(classDescriptor.c_str(), &ids);
expandBufAdd4BE(pReply, ids.size());
@@ -217,10 +217,10 @@ static JdwpError VM_ClassesBySignature(JdwpState*, Request& request, ExpandBuf*
* We exclude ourselves from the list, because we don't allow ourselves
* to be suspended, and that violates some JDWP expectations.
*/
-static JdwpError VM_AllThreads(JdwpState*, Request&, ExpandBuf* pReply)
+static JdwpError VM_AllThreads(JdwpState*, Request*, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::vector<ObjectId> thread_ids;
- Dbg::GetThreads(0, thread_ids);
+ Dbg::GetThreads(0, &thread_ids);
expandBufAdd4BE(pReply, thread_ids.size());
for (uint32_t i = 0; i < thread_ids.size(); ++i) {
@@ -233,7 +233,7 @@ static JdwpError VM_AllThreads(JdwpState*, Request&, ExpandBuf* pReply)
/*
* List all thread groups that do not have a parent.
*/
-static JdwpError VM_TopLevelThreadGroups(JdwpState*, Request&, ExpandBuf* pReply)
+static JdwpError VM_TopLevelThreadGroups(JdwpState*, Request*, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
/*
* TODO: maintain a list of parentless thread groups in the VM.
@@ -254,7 +254,7 @@ static JdwpError VM_TopLevelThreadGroups(JdwpState*, Request&, ExpandBuf* pReply
*
* All IDs are 8 bytes.
*/
-static JdwpError VM_IDSizes(JdwpState*, Request&, ExpandBuf* pReply)
+static JdwpError VM_IDSizes(JdwpState*, Request*, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
expandBufAdd4BE(pReply, sizeof(FieldId));
expandBufAdd4BE(pReply, sizeof(MethodId));
@@ -264,7 +264,7 @@ static JdwpError VM_IDSizes(JdwpState*, Request&, ExpandBuf* pReply)
return ERR_NONE;
}
-static JdwpError VM_Dispose(JdwpState*, Request&, ExpandBuf*)
+static JdwpError VM_Dispose(JdwpState*, Request*, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Dbg::Disposed();
return ERR_NONE;
@@ -276,7 +276,7 @@ static JdwpError VM_Dispose(JdwpState*, Request&, ExpandBuf*)
*
* This needs to increment the "suspend count" on all threads.
*/
-static JdwpError VM_Suspend(JdwpState*, Request&, ExpandBuf*)
+static JdwpError VM_Suspend(JdwpState*, Request*, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Thread* self = Thread::Current();
self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSuspension);
@@ -288,16 +288,16 @@ static JdwpError VM_Suspend(JdwpState*, Request&, ExpandBuf*)
/*
* Resume execution. Decrements the "suspend count" of all threads.
*/
-static JdwpError VM_Resume(JdwpState*, Request&, ExpandBuf*)
+static JdwpError VM_Resume(JdwpState*, Request*, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Dbg::ProcessDelayedFullUndeoptimizations();
Dbg::ResumeVM();
return ERR_NONE;
}
-static JdwpError VM_Exit(JdwpState* state, Request& request, ExpandBuf*)
+static JdwpError VM_Exit(JdwpState* state, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- uint32_t exit_status = request.ReadUnsigned32("exit_status");
+ uint32_t exit_status = request->ReadUnsigned32("exit_status");
state->ExitAfterReplying(exit_status);
return ERR_NONE;
}
@@ -308,9 +308,9 @@ static JdwpError VM_Exit(JdwpState* state, Request& request, ExpandBuf*)
* (Ctrl-Shift-I in Eclipse on an array of objects causes it to create the
* string "java.util.Arrays".)
*/
-static JdwpError VM_CreateString(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError VM_CreateString(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::string str(request.ReadUtf8String());
+ std::string str(request->ReadUtf8String());
ObjectId stringId = Dbg::CreateString(str);
if (stringId == 0) {
return ERR_OUT_OF_MEMORY;
@@ -319,7 +319,7 @@ static JdwpError VM_CreateString(JdwpState*, Request& request, ExpandBuf* pReply
return ERR_NONE;
}
-static JdwpError VM_ClassPaths(JdwpState*, Request&, ExpandBuf* pReply)
+static JdwpError VM_ClassPaths(JdwpState*, Request*, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
expandBufAddUtf8String(pReply, "/");
@@ -340,18 +340,18 @@ static JdwpError VM_ClassPaths(JdwpState*, Request&, ExpandBuf* pReply)
return ERR_NONE;
}
-static JdwpError VM_DisposeObjects(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError VM_DisposeObjects(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- size_t object_count = request.ReadUnsigned32("object_count");
+ size_t object_count = request->ReadUnsigned32("object_count");
for (size_t i = 0; i < object_count; ++i) {
- ObjectId object_id = request.ReadObjectId();
- uint32_t reference_count = request.ReadUnsigned32("reference_count");
+ ObjectId object_id = request->ReadObjectId();
+ uint32_t reference_count = request->ReadUnsigned32("reference_count");
Dbg::DisposeObject(object_id, reference_count);
}
return ERR_NONE;
}
-static JdwpError VM_Capabilities(JdwpState*, Request&, ExpandBuf* reply)
+static JdwpError VM_Capabilities(JdwpState*, Request*, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
expandBufAdd1(reply, true); // canWatchFieldModification
expandBufAdd1(reply, true); // canWatchFieldAccess
@@ -363,7 +363,7 @@ static JdwpError VM_Capabilities(JdwpState*, Request&, ExpandBuf* reply)
return ERR_NONE;
}
-static JdwpError VM_CapabilitiesNew(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError VM_CapabilitiesNew(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// The first few capabilities are the same as those reported by the older call.
VM_Capabilities(NULL, request, reply);
@@ -393,7 +393,7 @@ static JdwpError VM_CapabilitiesNew(JdwpState*, Request& request, ExpandBuf* rep
static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status, bool generic)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::vector<JDWP::RefTypeId> classes;
- Dbg::GetClassList(classes);
+ Dbg::GetClassList(&classes);
expandBufAdd4BE(pReply, classes.size());
@@ -421,29 +421,29 @@ static JdwpError VM_AllClassesImpl(ExpandBuf* pReply, bool descriptor_and_status
return ERR_NONE;
}
-static JdwpError VM_AllClasses(JdwpState*, Request&, ExpandBuf* pReply)
+static JdwpError VM_AllClasses(JdwpState*, Request*, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return VM_AllClassesImpl(pReply, true, false);
}
-static JdwpError VM_AllClassesWithGeneric(JdwpState*, Request&, ExpandBuf* pReply)
+static JdwpError VM_AllClassesWithGeneric(JdwpState*, Request*, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return VM_AllClassesImpl(pReply, true, true);
}
-static JdwpError VM_InstanceCounts(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError VM_InstanceCounts(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- int32_t class_count = request.ReadSigned32("class count");
+ int32_t class_count = request->ReadSigned32("class count");
if (class_count < 0) {
return ERR_ILLEGAL_ARGUMENT;
}
std::vector<RefTypeId> class_ids;
for (int32_t i = 0; i < class_count; ++i) {
- class_ids.push_back(request.ReadRefTypeId());
+ class_ids.push_back(request->ReadRefTypeId());
}
std::vector<uint64_t> counts;
- JdwpError rc = Dbg::GetInstanceCounts(class_ids, counts);
+ JdwpError rc = Dbg::GetInstanceCounts(class_ids, &counts);
if (rc != ERR_NONE) {
return rc;
}
@@ -455,22 +455,22 @@ static JdwpError VM_InstanceCounts(JdwpState*, Request& request, ExpandBuf* pRep
return ERR_NONE;
}
-static JdwpError RT_Modifiers(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_Modifiers(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
return Dbg::GetModifiers(refTypeId, pReply);
}
/*
* Get values from static fields in a reference type.
*/
-static JdwpError RT_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
- int32_t field_count = request.ReadSigned32("field count");
+ RefTypeId refTypeId = request->ReadRefTypeId();
+ int32_t field_count = request->ReadSigned32("field count");
expandBufAdd4BE(pReply, field_count);
for (int32_t i = 0; i < field_count; ++i) {
- FieldId fieldId = request.ReadFieldId();
+ FieldId fieldId = request->ReadFieldId();
JdwpError status = Dbg::GetStaticFieldValue(refTypeId, fieldId, pReply);
if (status != ERR_NONE) {
return status;
@@ -482,11 +482,11 @@ static JdwpError RT_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Get the name of the source file in which a reference type was declared.
*/
-static JdwpError RT_SourceFile(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_SourceFile(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
std::string source_file;
- JdwpError status = Dbg::GetSourceFile(refTypeId, source_file);
+ JdwpError status = Dbg::GetSourceFile(refTypeId, &source_file);
if (status != ERR_NONE) {
return status;
}
@@ -497,9 +497,9 @@ static JdwpError RT_SourceFile(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Return the current status of the reference type.
*/
-static JdwpError RT_Status(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_Status(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
JDWP::JdwpTypeTag type_tag;
uint32_t class_status;
JDWP::JdwpError status = Dbg::GetClassInfo(refTypeId, &type_tag, &class_status, NULL);
@@ -513,20 +513,20 @@ static JdwpError RT_Status(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Return interfaces implemented directly by this class.
*/
-static JdwpError RT_Interfaces(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_Interfaces(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
return Dbg::OutputDeclaredInterfaces(refTypeId, pReply);
}
/*
* Return the class object corresponding to this type.
*/
-static JdwpError RT_ClassObject(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_ClassObject(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
ObjectId class_object_id;
- JdwpError status = Dbg::GetClassObject(refTypeId, class_object_id);
+ JdwpError status = Dbg::GetClassObject(refTypeId, &class_object_id);
if (status != ERR_NONE) {
return status;
}
@@ -540,15 +540,15 @@ static JdwpError RT_ClassObject(JdwpState*, Request& request, ExpandBuf* pReply)
*
* JDB seems interested, but DEX files don't currently support this.
*/
-static JdwpError RT_SourceDebugExtension(JdwpState*, Request&, ExpandBuf*)
+static JdwpError RT_SourceDebugExtension(JdwpState*, Request*, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
/* referenceTypeId in, string out */
return ERR_ABSENT_INFORMATION;
}
-static JdwpError RT_Signature(JdwpState*, Request& request, ExpandBuf* pReply, bool with_generic)
+static JdwpError RT_Signature(JdwpState*, Request* request, ExpandBuf* pReply, bool with_generic)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
std::string signature;
JdwpError status = Dbg::GetSignature(refTypeId, &signature);
@@ -562,12 +562,12 @@ static JdwpError RT_Signature(JdwpState*, Request& request, ExpandBuf* pReply, b
return ERR_NONE;
}
-static JdwpError RT_Signature(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError RT_Signature(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return RT_Signature(state, request, pReply, false);
}
-static JdwpError RT_SignatureWithGeneric(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError RT_SignatureWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return RT_Signature(state, request, pReply, true);
}
@@ -576,9 +576,9 @@ static JdwpError RT_SignatureWithGeneric(JdwpState* state, Request& request, Exp
* Return the instance of java.lang.ClassLoader that loaded the specified
* reference type, or null if it was loaded by the system loader.
*/
-static JdwpError RT_ClassLoader(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_ClassLoader(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
return Dbg::GetClassLoader(refTypeId, pReply);
}
@@ -586,16 +586,16 @@ static JdwpError RT_ClassLoader(JdwpState*, Request& request, ExpandBuf* pReply)
* Given a referenceTypeId, return a block of stuff that describes the
* fields declared by a class.
*/
-static JdwpError RT_FieldsWithGeneric(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_FieldsWithGeneric(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
return Dbg::OutputDeclaredFields(refTypeId, true, pReply);
}
// Obsolete equivalent of FieldsWithGeneric, without the generic type information.
-static JdwpError RT_Fields(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_Fields(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
return Dbg::OutputDeclaredFields(refTypeId, false, pReply);
}
@@ -603,29 +603,29 @@ static JdwpError RT_Fields(JdwpState*, Request& request, ExpandBuf* pReply)
* Given a referenceTypeID, return a block of goodies describing the
* methods declared by a class.
*/
-static JdwpError RT_MethodsWithGeneric(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_MethodsWithGeneric(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
return Dbg::OutputDeclaredMethods(refTypeId, true, pReply);
}
// Obsolete equivalent of MethodsWithGeneric, without the generic type information.
-static JdwpError RT_Methods(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError RT_Methods(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
return Dbg::OutputDeclaredMethods(refTypeId, false, pReply);
}
-static JdwpError RT_Instances(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError RT_Instances(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_id = request.ReadRefTypeId();
- int32_t max_count = request.ReadSigned32("max count");
+ RefTypeId class_id = request->ReadRefTypeId();
+ int32_t max_count = request->ReadSigned32("max count");
if (max_count < 0) {
return ERR_ILLEGAL_ARGUMENT;
}
std::vector<ObjectId> instances;
- JdwpError rc = Dbg::GetInstances(class_id, max_count, instances);
+ JdwpError rc = Dbg::GetInstances(class_id, max_count, &instances);
if (rc != ERR_NONE) {
return rc;
}
@@ -636,11 +636,11 @@ static JdwpError RT_Instances(JdwpState*, Request& request, ExpandBuf* reply)
/*
* Return the immediate superclass of a class.
*/
-static JdwpError CT_Superclass(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError CT_Superclass(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_id = request.ReadRefTypeId();
+ RefTypeId class_id = request->ReadRefTypeId();
RefTypeId superClassId;
- JdwpError status = Dbg::GetSuperclass(class_id, superClassId);
+ JdwpError status = Dbg::GetSuperclass(class_id, &superClassId);
if (status != ERR_NONE) {
return status;
}
@@ -651,18 +651,18 @@ static JdwpError CT_Superclass(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Set static class values.
*/
-static JdwpError CT_SetValues(JdwpState* , Request& request, ExpandBuf*)
+static JdwpError CT_SetValues(JdwpState* , Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_id = request.ReadRefTypeId();
- int32_t values_count = request.ReadSigned32("values count");
+ RefTypeId class_id = request->ReadRefTypeId();
+ int32_t values_count = request->ReadSigned32("values count");
UNUSED(class_id);
for (int32_t i = 0; i < values_count; ++i) {
- FieldId fieldId = request.ReadFieldId();
+ FieldId fieldId = request->ReadFieldId();
JDWP::JdwpTag fieldTag = Dbg::GetStaticFieldBasicTag(fieldId);
size_t width = Dbg::GetTagWidth(fieldTag);
- uint64_t value = request.ReadValue(width);
+ uint64_t value = request->ReadValue(width);
VLOG(jdwp) << " --> field=" << fieldId << " tag=" << fieldTag << " --> " << value;
JdwpError status = Dbg::SetStaticFieldValue(fieldId, value, width);
@@ -680,11 +680,11 @@ static JdwpError CT_SetValues(JdwpState* , Request& request, ExpandBuf*)
* Example: Eclipse sometimes uses java/lang/Class.forName(String s) on
* values in the "variables" display.
*/
-static JdwpError CT_InvokeMethod(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError CT_InvokeMethod(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_id = request.ReadRefTypeId();
- ObjectId thread_id = request.ReadThreadId();
- MethodId method_id = request.ReadMethodId();
+ RefTypeId class_id = request->ReadRefTypeId();
+ ObjectId thread_id = request->ReadThreadId();
+ MethodId method_id = request->ReadMethodId();
return FinishInvoke(state, request, pReply, thread_id, 0, class_id, method_id, false);
}
@@ -696,14 +696,14 @@ static JdwpError CT_InvokeMethod(JdwpState* state, Request& request, ExpandBuf*
* Example: in IntelliJ, create a watch on "new String(myByteArray)" to
* see the contents of a byte[] as a string.
*/
-static JdwpError CT_NewInstance(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError CT_NewInstance(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_id = request.ReadRefTypeId();
- ObjectId thread_id = request.ReadThreadId();
- MethodId method_id = request.ReadMethodId();
+ RefTypeId class_id = request->ReadRefTypeId();
+ ObjectId thread_id = request->ReadThreadId();
+ MethodId method_id = request->ReadMethodId();
ObjectId object_id;
- JdwpError status = Dbg::CreateObject(class_id, object_id);
+ JdwpError status = Dbg::CreateObject(class_id, &object_id);
if (status != ERR_NONE) {
return status;
}
@@ -716,13 +716,13 @@ static JdwpError CT_NewInstance(JdwpState* state, Request& request, ExpandBuf* p
/*
* Create a new array object of the requested type and length.
*/
-static JdwpError AT_newInstance(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError AT_newInstance(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId arrayTypeId = request.ReadRefTypeId();
- int32_t length = request.ReadSigned32("length");
+ RefTypeId arrayTypeId = request->ReadRefTypeId();
+ int32_t length = request->ReadSigned32("length");
ObjectId object_id;
- JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, object_id);
+ JdwpError status = Dbg::CreateArrayObject(arrayTypeId, length, &object_id);
if (status != ERR_NONE) {
return status;
}
@@ -737,21 +737,21 @@ static JdwpError AT_newInstance(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Return line number information for the method, if present.
*/
-static JdwpError M_LineTable(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError M_LineTable(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId refTypeId = request.ReadRefTypeId();
- MethodId method_id = request.ReadMethodId();
+ RefTypeId refTypeId = request->ReadRefTypeId();
+ MethodId method_id = request->ReadMethodId();
Dbg::OutputLineTable(refTypeId, method_id, pReply);
return ERR_NONE;
}
-static JdwpError M_VariableTable(JdwpState*, Request& request, ExpandBuf* pReply,
+static JdwpError M_VariableTable(JdwpState*, Request* request, ExpandBuf* pReply,
bool generic)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_id = request.ReadRefTypeId();
- MethodId method_id = request.ReadMethodId();
+ RefTypeId class_id = request->ReadRefTypeId();
+ MethodId method_id = request->ReadMethodId();
// We could return ERR_ABSENT_INFORMATION here if the DEX file was built without local variable
// information. That will cause Eclipse to make a best-effort attempt at displaying local
@@ -761,23 +761,23 @@ static JdwpError M_VariableTable(JdwpState*, Request& request, ExpandBuf* pReply
return ERR_NONE;
}
-static JdwpError M_VariableTable(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError M_VariableTable(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return M_VariableTable(state, request, pReply, false);
}
-static JdwpError M_VariableTableWithGeneric(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError M_VariableTableWithGeneric(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return M_VariableTable(state, request, pReply, true);
}
-static JdwpError M_Bytecodes(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError M_Bytecodes(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_id = request.ReadRefTypeId();
- MethodId method_id = request.ReadMethodId();
+ RefTypeId class_id = request->ReadRefTypeId();
+ MethodId method_id = request->ReadMethodId();
std::vector<uint8_t> bytecodes;
- JdwpError rc = Dbg::GetBytecodes(class_id, method_id, bytecodes);
+ JdwpError rc = Dbg::GetBytecodes(class_id, method_id, &bytecodes);
if (rc != ERR_NONE) {
return rc;
}
@@ -797,23 +797,23 @@ static JdwpError M_Bytecodes(JdwpState*, Request& request, ExpandBuf* reply)
* This can get called on different things, e.g. thread_id gets
* passed in here.
*/
-static JdwpError OR_ReferenceType(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError OR_ReferenceType(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
+ ObjectId object_id = request->ReadObjectId();
return Dbg::GetReferenceType(object_id, pReply);
}
/*
* Get values from the fields of an object.
*/
-static JdwpError OR_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError OR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
- int32_t field_count = request.ReadSigned32("field count");
+ ObjectId object_id = request->ReadObjectId();
+ int32_t field_count = request->ReadSigned32("field count");
expandBufAdd4BE(pReply, field_count);
for (int32_t i = 0; i < field_count; ++i) {
- FieldId fieldId = request.ReadFieldId();
+ FieldId fieldId = request->ReadFieldId();
JdwpError status = Dbg::GetFieldValue(object_id, fieldId, pReply);
if (status != ERR_NONE) {
return status;
@@ -826,17 +826,17 @@ static JdwpError OR_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Set values in the fields of an object.
*/
-static JdwpError OR_SetValues(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError OR_SetValues(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
- int32_t field_count = request.ReadSigned32("field count");
+ ObjectId object_id = request->ReadObjectId();
+ int32_t field_count = request->ReadSigned32("field count");
for (int32_t i = 0; i < field_count; ++i) {
- FieldId fieldId = request.ReadFieldId();
+ FieldId fieldId = request->ReadFieldId();
JDWP::JdwpTag fieldTag = Dbg::GetFieldBasicTag(fieldId);
size_t width = Dbg::GetTagWidth(fieldTag);
- uint64_t value = request.ReadValue(width);
+ uint64_t value = request->ReadValue(width);
VLOG(jdwp) << " --> fieldId=" << fieldId << " tag=" << fieldTag << "(" << width << ") value=" << value;
JdwpError status = Dbg::SetFieldValue(object_id, fieldId, value, width);
@@ -848,9 +848,9 @@ static JdwpError OR_SetValues(JdwpState*, Request& request, ExpandBuf*)
return ERR_NONE;
}
-static JdwpError OR_MonitorInfo(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError OR_MonitorInfo(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
+ ObjectId object_id = request->ReadObjectId();
return Dbg::GetMonitorInfo(object_id, reply);
}
@@ -865,47 +865,47 @@ static JdwpError OR_MonitorInfo(JdwpState*, Request& request, ExpandBuf* reply)
* object), it will try to invoke the object's toString() function. This
* feature becomes crucial when examining ArrayLists with Eclipse.
*/
-static JdwpError OR_InvokeMethod(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError OR_InvokeMethod(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
- ObjectId thread_id = request.ReadThreadId();
- RefTypeId class_id = request.ReadRefTypeId();
- MethodId method_id = request.ReadMethodId();
+ ObjectId object_id = request->ReadObjectId();
+ ObjectId thread_id = request->ReadThreadId();
+ RefTypeId class_id = request->ReadRefTypeId();
+ MethodId method_id = request->ReadMethodId();
return FinishInvoke(state, request, pReply, thread_id, object_id, class_id, method_id, false);
}
-static JdwpError OR_DisableCollection(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError OR_DisableCollection(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
+ ObjectId object_id = request->ReadObjectId();
return Dbg::DisableCollection(object_id);
}
-static JdwpError OR_EnableCollection(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError OR_EnableCollection(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
+ ObjectId object_id = request->ReadObjectId();
return Dbg::EnableCollection(object_id);
}
-static JdwpError OR_IsCollected(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError OR_IsCollected(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
+ ObjectId object_id = request->ReadObjectId();
bool is_collected;
- JdwpError rc = Dbg::IsCollected(object_id, is_collected);
+ JdwpError rc = Dbg::IsCollected(object_id, &is_collected);
expandBufAdd1(pReply, is_collected ? 1 : 0);
return rc;
}
-static JdwpError OR_ReferringObjects(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError OR_ReferringObjects(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId object_id = request.ReadObjectId();
- int32_t max_count = request.ReadSigned32("max count");
+ ObjectId object_id = request->ReadObjectId();
+ int32_t max_count = request->ReadSigned32("max count");
if (max_count < 0) {
return ERR_ILLEGAL_ARGUMENT;
}
std::vector<ObjectId> referring_objects;
- JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, referring_objects);
+ JdwpError rc = Dbg::GetReferringObjects(object_id, max_count, &referring_objects);
if (rc != ERR_NONE) {
return rc;
}
@@ -916,9 +916,9 @@ static JdwpError OR_ReferringObjects(JdwpState*, Request& request, ExpandBuf* re
/*
* Return the string value in a string object.
*/
-static JdwpError SR_Value(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError SR_Value(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId stringObject = request.ReadObjectId();
+ ObjectId stringObject = request->ReadObjectId();
std::string str(Dbg::StringToUtf8(stringObject));
VLOG(jdwp) << StringPrintf(" --> %s", PrintableString(str.c_str()).c_str());
@@ -931,12 +931,12 @@ static JdwpError SR_Value(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Return a thread's name.
*/
-static JdwpError TR_Name(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TR_Name(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
std::string name;
- JdwpError error = Dbg::GetThreadName(thread_id, name);
+ JdwpError error = Dbg::GetThreadName(thread_id, &name);
if (error != ERR_NONE) {
return error;
}
@@ -952,9 +952,9 @@ static JdwpError TR_Name(JdwpState*, Request& request, ExpandBuf* pReply)
* It's supposed to remain suspended even if interpreted code wants to
* resume it; only the JDI is allowed to resume it.
*/
-static JdwpError TR_Suspend(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError TR_Suspend(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
if (thread_id == Dbg::GetThreadSelfId()) {
LOG(INFO) << " Warning: ignoring request to suspend self";
@@ -971,9 +971,9 @@ static JdwpError TR_Suspend(JdwpState*, Request& request, ExpandBuf*)
/*
* Resume the specified thread.
*/
-static JdwpError TR_Resume(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError TR_Resume(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
if (thread_id == Dbg::GetThreadSelfId()) {
LOG(INFO) << " Warning: ignoring request to resume self";
@@ -989,9 +989,9 @@ static JdwpError TR_Resume(JdwpState*, Request& request, ExpandBuf*)
/*
* Return status of specified thread.
*/
-static JdwpError TR_Status(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TR_Status(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
JDWP::JdwpThreadStatus threadStatus;
JDWP::JdwpSuspendStatus suspendStatus;
@@ -1011,9 +1011,9 @@ static JdwpError TR_Status(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Return the thread group that the specified thread is a member of.
*/
-static JdwpError TR_ThreadGroup(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TR_ThreadGroup(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
return Dbg::GetThreadGroup(thread_id, pReply);
}
@@ -1023,14 +1023,14 @@ static JdwpError TR_ThreadGroup(JdwpState*, Request& request, ExpandBuf* pReply)
* If the thread isn't suspended, the error code isn't defined, but should
* be THREAD_NOT_SUSPENDED.
*/
-static JdwpError TR_Frames(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TR_Frames(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
- uint32_t start_frame = request.ReadUnsigned32("start frame");
- uint32_t length = request.ReadUnsigned32("length");
+ ObjectId thread_id = request->ReadThreadId();
+ uint32_t start_frame = request->ReadUnsigned32("start frame");
+ uint32_t length = request->ReadUnsigned32("length");
size_t actual_frame_count;
- JdwpError error = Dbg::GetThreadFrameCount(thread_id, actual_frame_count);
+ JdwpError error = Dbg::GetThreadFrameCount(thread_id, &actual_frame_count);
if (error != ERR_NONE) {
return error;
}
@@ -1055,12 +1055,12 @@ static JdwpError TR_Frames(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Returns the #of frames on the specified thread, which must be suspended.
*/
-static JdwpError TR_FrameCount(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TR_FrameCount(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
size_t frame_count;
- JdwpError rc = Dbg::GetThreadFrameCount(thread_id, frame_count);
+ JdwpError rc = Dbg::GetThreadFrameCount(thread_id, &frame_count);
if (rc != ERR_NONE) {
return rc;
}
@@ -1069,13 +1069,13 @@ static JdwpError TR_FrameCount(JdwpState*, Request& request, ExpandBuf* pReply)
return ERR_NONE;
}
-static JdwpError TR_OwnedMonitors(Request& request, ExpandBuf* reply, bool with_stack_depths)
+static JdwpError TR_OwnedMonitors(Request* request, ExpandBuf* reply, bool with_stack_depths)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
std::vector<ObjectId> monitors;
std::vector<uint32_t> stack_depths;
- JdwpError rc = Dbg::GetOwnedMonitors(thread_id, monitors, stack_depths);
+ JdwpError rc = Dbg::GetOwnedMonitors(thread_id, &monitors, &stack_depths);
if (rc != ERR_NONE) {
return rc;
}
@@ -1093,31 +1093,31 @@ static JdwpError TR_OwnedMonitors(Request& request, ExpandBuf* reply, bool with_
return ERR_NONE;
}
-static JdwpError TR_OwnedMonitors(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError TR_OwnedMonitors(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return TR_OwnedMonitors(request, reply, false);
}
-static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError TR_OwnedMonitorsStackDepthInfo(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return TR_OwnedMonitors(request, reply, true);
}
-static JdwpError TR_CurrentContendedMonitor(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError TR_CurrentContendedMonitor(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
ObjectId contended_monitor;
- JdwpError rc = Dbg::GetContendedMonitor(thread_id, contended_monitor);
+ JdwpError rc = Dbg::GetContendedMonitor(thread_id, &contended_monitor);
if (rc != ERR_NONE) {
return rc;
}
return WriteTaggedObject(reply, contended_monitor);
}
-static JdwpError TR_Interrupt(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError TR_Interrupt(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
return Dbg::Interrupt(thread_id);
}
@@ -1127,9 +1127,9 @@ static JdwpError TR_Interrupt(JdwpState*, Request& request, ExpandBuf* reply)
* (The thread *might* still be running -- it might not have examined
* its suspend count recently.)
*/
-static JdwpError TR_DebugSuspendCount(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TR_DebugSuspendCount(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
return Dbg::GetThreadDebugSuspendCount(thread_id, pReply);
}
@@ -1138,9 +1138,9 @@ static JdwpError TR_DebugSuspendCount(JdwpState*, Request& request, ExpandBuf* p
*
* The Eclipse debugger recognizes "main" and "system" as special.
*/
-static JdwpError TGR_Name(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TGR_Name(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_group_id = request.ReadThreadGroupId();
+ ObjectId thread_group_id = request->ReadThreadGroupId();
expandBufAddUtf8String(pReply, Dbg::GetThreadGroupName(thread_group_id));
@@ -1151,9 +1151,9 @@ static JdwpError TGR_Name(JdwpState*, Request& request, ExpandBuf* pReply)
* Returns the thread group -- if any -- that contains the specified
* thread group.
*/
-static JdwpError TGR_Parent(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TGR_Parent(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_group_id = request.ReadThreadGroupId();
+ ObjectId thread_group_id = request->ReadThreadGroupId();
ObjectId parentGroup = Dbg::GetThreadGroupParent(thread_group_id);
expandBufAddObjectId(pReply, parentGroup);
@@ -1165,19 +1165,19 @@ static JdwpError TGR_Parent(JdwpState*, Request& request, ExpandBuf* pReply)
* Return the active threads and thread groups that are part of the
* specified thread group.
*/
-static JdwpError TGR_Children(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError TGR_Children(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_group_id = request.ReadThreadGroupId();
+ ObjectId thread_group_id = request->ReadThreadGroupId();
std::vector<ObjectId> thread_ids;
- Dbg::GetThreads(thread_group_id, thread_ids);
+ Dbg::GetThreads(thread_group_id, &thread_ids);
expandBufAdd4BE(pReply, thread_ids.size());
for (uint32_t i = 0; i < thread_ids.size(); ++i) {
expandBufAddObjectId(pReply, thread_ids[i]);
}
std::vector<ObjectId> child_thread_groups_ids;
- Dbg::GetChildThreadGroups(thread_group_id, child_thread_groups_ids);
+ Dbg::GetChildThreadGroups(thread_group_id, &child_thread_groups_ids);
expandBufAdd4BE(pReply, child_thread_groups_ids.size());
for (uint32_t i = 0; i < child_thread_groups_ids.size(); ++i) {
expandBufAddObjectId(pReply, child_thread_groups_ids[i]);
@@ -1189,12 +1189,12 @@ static JdwpError TGR_Children(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Return the #of components in the array.
*/
-static JdwpError AR_Length(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError AR_Length(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId array_id = request.ReadArrayId();
+ ObjectId array_id = request->ReadArrayId();
- int length;
- JdwpError status = Dbg::GetArrayLength(array_id, length);
+ int32_t length;
+ JdwpError status = Dbg::GetArrayLength(array_id, &length);
if (status != ERR_NONE) {
return status;
}
@@ -1208,28 +1208,28 @@ static JdwpError AR_Length(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Return the values from an array.
*/
-static JdwpError AR_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError AR_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId array_id = request.ReadArrayId();
- uint32_t offset = request.ReadUnsigned32("offset");
- uint32_t length = request.ReadUnsigned32("length");
+ ObjectId array_id = request->ReadArrayId();
+ uint32_t offset = request->ReadUnsigned32("offset");
+ uint32_t length = request->ReadUnsigned32("length");
return Dbg::OutputArray(array_id, offset, length, pReply);
}
/*
* Set values in an array.
*/
-static JdwpError AR_SetValues(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError AR_SetValues(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId array_id = request.ReadArrayId();
- uint32_t offset = request.ReadUnsigned32("offset");
- uint32_t count = request.ReadUnsigned32("count");
+ ObjectId array_id = request->ReadArrayId();
+ uint32_t offset = request->ReadUnsigned32("offset");
+ uint32_t count = request->ReadUnsigned32("count");
return Dbg::SetArrayElements(array_id, offset, count, request);
}
-static JdwpError CLR_VisibleClasses(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError CLR_VisibleClasses(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- request.ReadObjectId(); // classLoaderObject
+ request->ReadObjectId(); // classLoaderObject
// TODO: we should only return classes which have the given class loader as a defining or
// initiating loader. The former would be easy; the latter is hard, because we don't have
// any such notion.
@@ -1241,11 +1241,11 @@ static JdwpError CLR_VisibleClasses(JdwpState*, Request& request, ExpandBuf* pRe
*
* Reply with a requestID.
*/
-static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError ER_Set(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- JdwpEventKind event_kind = request.ReadEnum1<JdwpEventKind>("event kind");
- JdwpSuspendPolicy suspend_policy = request.ReadEnum1<JdwpSuspendPolicy>("suspend policy");
- int32_t modifier_count = request.ReadSigned32("modifier count");
+ JdwpEventKind event_kind = request->ReadEnum1<JdwpEventKind>("event kind");
+ JdwpSuspendPolicy suspend_policy = request->ReadEnum1<JdwpSuspendPolicy>("suspend policy");
+ int32_t modifier_count = request->ReadSigned32("modifier count");
CHECK_LT(modifier_count, 256); /* reasonableness check */
@@ -1260,12 +1260,12 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
*/
for (int32_t i = 0; i < modifier_count; ++i) {
JdwpEventMod& mod = pEvent->mods[i];
- mod.modKind = request.ReadModKind();
+ mod.modKind = request->ReadModKind();
switch (mod.modKind) {
case MK_COUNT:
{
// Report once, when "--count" reaches 0.
- uint32_t count = request.ReadUnsigned32("count");
+ uint32_t count = request->ReadUnsigned32("count");
if (count == 0) {
return ERR_INVALID_COUNT;
}
@@ -1275,21 +1275,21 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
case MK_CONDITIONAL:
{
// Conditional on expression.
- uint32_t exprId = request.ReadUnsigned32("expr id");
+ uint32_t exprId = request->ReadUnsigned32("expr id");
mod.conditional.exprId = exprId;
}
break;
case MK_THREAD_ONLY:
{
// Only report events in specified thread.
- ObjectId thread_id = request.ReadThreadId();
+ ObjectId thread_id = request->ReadThreadId();
mod.threadOnly.threadId = thread_id;
}
break;
case MK_CLASS_ONLY:
{
// For ClassPrepare, MethodEntry.
- RefTypeId class_id = request.ReadRefTypeId();
+ RefTypeId class_id = request->ReadRefTypeId();
mod.classOnly.refTypeId = class_id;
}
break;
@@ -1297,7 +1297,7 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
{
// Restrict events to matching classes.
// pattern is "java.foo.*", we want "java/foo/*".
- std::string pattern(request.ReadUtf8String());
+ std::string pattern(request->ReadUtf8String());
std::replace(pattern.begin(), pattern.end(), '.', '/');
mod.classMatch.classPattern = strdup(pattern.c_str());
}
@@ -1306,7 +1306,7 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
{
// Restrict events to non-matching classes.
// pattern is "java.foo.*", we want "java/foo/*".
- std::string pattern(request.ReadUtf8String());
+ std::string pattern(request->ReadUtf8String());
std::replace(pattern.begin(), pattern.end(), '.', '/');
mod.classExclude.classPattern = strdup(pattern.c_str());
}
@@ -1314,23 +1314,23 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
case MK_LOCATION_ONLY:
{
// Restrict certain events based on location.
- JdwpLocation location = request.ReadLocation();
+ JdwpLocation location = request->ReadLocation();
mod.locationOnly.loc = location;
}
break;
case MK_EXCEPTION_ONLY:
{
// Modifies EK_EXCEPTION events,
- mod.exceptionOnly.refTypeId = request.ReadRefTypeId(); // null => all exceptions.
- mod.exceptionOnly.caught = request.ReadEnum1<uint8_t>("caught");
- mod.exceptionOnly.uncaught = request.ReadEnum1<uint8_t>("uncaught");
+ mod.exceptionOnly.refTypeId = request->ReadRefTypeId(); // null => all exceptions.
+ mod.exceptionOnly.caught = request->ReadEnum1<uint8_t>("caught");
+ mod.exceptionOnly.uncaught = request->ReadEnum1<uint8_t>("uncaught");
}
break;
case MK_FIELD_ONLY:
{
// For field access/modification events.
- RefTypeId declaring = request.ReadRefTypeId();
- FieldId fieldId = request.ReadFieldId();
+ RefTypeId declaring = request->ReadRefTypeId();
+ FieldId fieldId = request->ReadFieldId();
mod.fieldOnly.refTypeId = declaring;
mod.fieldOnly.fieldId = fieldId;
}
@@ -1338,9 +1338,9 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
case MK_STEP:
{
// For use with EK_SINGLE_STEP.
- ObjectId thread_id = request.ReadThreadId();
- uint32_t size = request.ReadUnsigned32("step size");
- uint32_t depth = request.ReadUnsigned32("step depth");
+ ObjectId thread_id = request->ReadThreadId();
+ uint32_t size = request->ReadUnsigned32("step size");
+ uint32_t depth = request->ReadUnsigned32("step depth");
VLOG(jdwp) << StringPrintf(" Step: thread=%#" PRIx64, thread_id)
<< " size=" << JdwpStepSize(size) << " depth=" << JdwpStepDepth(depth);
@@ -1352,7 +1352,7 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
case MK_INSTANCE_ONLY:
{
// Report events related to a specific object.
- ObjectId instance = request.ReadObjectId();
+ ObjectId instance = request->ReadObjectId();
mod.instanceOnly.objectId = instance;
}
break;
@@ -1382,10 +1382,10 @@ static JdwpError ER_Set(JdwpState* state, Request& request, ExpandBuf* pReply)
return err;
}
-static JdwpError ER_Clear(JdwpState* state, Request& request, ExpandBuf*)
+static JdwpError ER_Clear(JdwpState* state, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- request.ReadEnum1<JdwpEventKind>("event kind");
- uint32_t requestId = request.ReadUnsigned32("request id");
+ request->ReadEnum1<JdwpEventKind>("event kind");
+ uint32_t requestId = request->ReadUnsigned32("request id");
// Failure to find an event with a matching ID is a no-op
// and does not return an error.
@@ -1396,16 +1396,16 @@ static JdwpError ER_Clear(JdwpState* state, Request& request, ExpandBuf*)
/*
* Return the values of arguments and local variables.
*/
-static JdwpError SF_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError SF_GetValues(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
- FrameId frame_id = request.ReadFrameId();
- int32_t slot_count = request.ReadSigned32("slot count");
+ ObjectId thread_id = request->ReadThreadId();
+ FrameId frame_id = request->ReadFrameId();
+ int32_t slot_count = request->ReadSigned32("slot count");
expandBufAdd4BE(pReply, slot_count); /* "int values" */
for (int32_t i = 0; i < slot_count; ++i) {
- uint32_t slot = request.ReadUnsigned32("slot");
- JDWP::JdwpTag reqSigByte = request.ReadTag();
+ uint32_t slot = request->ReadUnsigned32("slot");
+ JDWP::JdwpTag reqSigByte = request->ReadTag();
VLOG(jdwp) << " --> slot " << slot << " " << reqSigByte;
@@ -1423,17 +1423,17 @@ static JdwpError SF_GetValues(JdwpState*, Request& request, ExpandBuf* pReply)
/*
* Set the values of arguments and local variables.
*/
-static JdwpError SF_SetValues(JdwpState*, Request& request, ExpandBuf*)
+static JdwpError SF_SetValues(JdwpState*, Request* request, ExpandBuf*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
- FrameId frame_id = request.ReadFrameId();
- int32_t slot_count = request.ReadSigned32("slot count");
+ ObjectId thread_id = request->ReadThreadId();
+ FrameId frame_id = request->ReadFrameId();
+ int32_t slot_count = request->ReadSigned32("slot count");
for (int32_t i = 0; i < slot_count; ++i) {
- uint32_t slot = request.ReadUnsigned32("slot");
- JDWP::JdwpTag sigByte = request.ReadTag();
+ uint32_t slot = request->ReadUnsigned32("slot");
+ JDWP::JdwpTag sigByte = request->ReadTag();
size_t width = Dbg::GetTagWidth(sigByte);
- uint64_t value = request.ReadValue(width);
+ uint64_t value = request->ReadValue(width);
VLOG(jdwp) << " --> slot " << slot << " " << sigByte << " " << value;
JdwpError error = Dbg::SetLocalValue(thread_id, frame_id, slot, sigByte, value, width);
@@ -1445,10 +1445,10 @@ static JdwpError SF_SetValues(JdwpState*, Request& request, ExpandBuf*)
return ERR_NONE;
}
-static JdwpError SF_ThisObject(JdwpState*, Request& request, ExpandBuf* reply)
+static JdwpError SF_ThisObject(JdwpState*, Request* request, ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectId thread_id = request.ReadThreadId();
- FrameId frame_id = request.ReadFrameId();
+ ObjectId thread_id = request->ReadThreadId();
+ FrameId frame_id = request->ReadFrameId();
ObjectId object_id;
JdwpError rc = Dbg::GetThisObject(thread_id, frame_id, &object_id);
@@ -1466,16 +1466,16 @@ static JdwpError SF_ThisObject(JdwpState*, Request& request, ExpandBuf* reply)
* reused, whereas ClassIds can be recycled like any other object. (Either
* that, or I have no idea what this is for.)
*/
-static JdwpError COR_ReflectedType(JdwpState*, Request& request, ExpandBuf* pReply)
+static JdwpError COR_ReflectedType(JdwpState*, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- RefTypeId class_object_id = request.ReadRefTypeId();
+ RefTypeId class_object_id = request->ReadRefTypeId();
return Dbg::GetReflectedType(class_object_id, pReply);
}
/*
* Handle a DDM packet with a single chunk in it.
*/
-static JdwpError DDM_Chunk(JdwpState* state, Request& request, ExpandBuf* pReply)
+static JdwpError DDM_Chunk(JdwpState* state, Request* request, ExpandBuf* pReply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
state->NotifyDdmsActive();
uint8_t* replyBuf = NULL;
@@ -1496,7 +1496,7 @@ static JdwpError DDM_Chunk(JdwpState* state, Request& request, ExpandBuf* pReply
/*
* Handler map decl.
*/
-typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, Request& request, ExpandBuf* reply);
+typedef JdwpError (*JdwpRequestHandler)(JdwpState* state, Request* request, ExpandBuf* reply);
struct JdwpHandlerMap {
uint8_t cmdSet;
@@ -1639,20 +1639,20 @@ static const JdwpHandlerMap gHandlers[] = {
{ 199, 1, DDM_Chunk, "DDM.Chunk" },
};
-static const char* GetCommandName(Request& request) {
+static const char* GetCommandName(Request* request) {
for (size_t i = 0; i < arraysize(gHandlers); ++i) {
- if (gHandlers[i].cmdSet == request.GetCommandSet() && gHandlers[i].cmd == request.GetCommand()) {
+ if (gHandlers[i].cmdSet == request->GetCommandSet() && gHandlers[i].cmd == request->GetCommand()) {
return gHandlers[i].name;
}
}
return "?UNKNOWN?";
}
-static std::string DescribeCommand(Request& request) {
+static std::string DescribeCommand(Request* request) {
std::string result;
result += "REQUEST: ";
result += GetCommandName(request);
- result += StringPrintf(" (length=%zu id=0x%06x)", request.GetLength(), request.GetId());
+ result += StringPrintf(" (length=%zu id=0x%06x)", request->GetLength(), request->GetId());
return result;
}
@@ -1661,10 +1661,10 @@ static std::string DescribeCommand(Request& request) {
*
* On entry, the JDWP thread is in VMWAIT.
*/
-size_t JdwpState::ProcessRequest(Request& request, ExpandBuf* pReply) {
+size_t JdwpState::ProcessRequest(Request* request, ExpandBuf* pReply) {
JdwpError result = ERR_NONE;
- if (request.GetCommandSet() != kJDWPDdmCmdSet) {
+ if (request->GetCommandSet() != kJDWPDdmCmdSet) {
/*
* Activity from a debugger, not merely ddms. Mark us as having an
* active debugger session, and zero out the last-activity timestamp
@@ -1684,7 +1684,7 @@ size_t JdwpState::ProcessRequest(Request& request, ExpandBuf* pReply) {
* thread to finish, and then clear the block. Depending on the thread
* suspend policy, this may allow events in other threads to fire,
* but those events have no bearing on what the debugger has sent us
- * in the current request.
+ * in the current request->
*
* Note that we MUST clear the event token before waking the event
* thread up, or risk waiting for the thread to suspend after we've
@@ -1693,7 +1693,7 @@ size_t JdwpState::ProcessRequest(Request& request, ExpandBuf* pReply) {
SetWaitForEventThread(0);
/*
- * We do not want events to be sent while we process a request. Indicate the JDWP thread starts
+ * We do not want events to be sent while we process a request-> Indicate the JDWP thread starts
* to process a request so other threads wait for it to finish before sending an event.
*/
StartProcessingRequest();
@@ -1709,18 +1709,18 @@ size_t JdwpState::ProcessRequest(Request& request, ExpandBuf* pReply) {
size_t i;
for (i = 0; i < arraysize(gHandlers); ++i) {
- if (gHandlers[i].cmdSet == request.GetCommandSet() && gHandlers[i].cmd == request.GetCommand() && gHandlers[i].func != NULL) {
+ if (gHandlers[i].cmdSet == request->GetCommandSet() && gHandlers[i].cmd == request->GetCommand() && gHandlers[i].func != NULL) {
VLOG(jdwp) << DescribeCommand(request);
result = (*gHandlers[i].func)(this, request, pReply);
if (result == ERR_NONE) {
- request.CheckConsumed();
+ request->CheckConsumed();
}
break;
}
}
if (i == arraysize(gHandlers)) {
LOG(ERROR) << "Command not implemented: " << DescribeCommand(request);
- LOG(ERROR) << HexDump(request.data(), request.size(), false, "");
+ LOG(ERROR) << HexDump(request->data(), request->size(), false, "");
result = ERR_NOT_IMPLEMENTED;
}
@@ -1732,11 +1732,11 @@ size_t JdwpState::ProcessRequest(Request& request, ExpandBuf* pReply) {
uint8_t* replyBuf = expandBufGetBuffer(pReply);
size_t replyLength = (result == ERR_NONE) ? expandBufGetLength(pReply) : kJDWPHeaderLen;
Set4BE(replyBuf + 0, replyLength);
- Set4BE(replyBuf + 4, request.GetId());
+ Set4BE(replyBuf + 4, request->GetId());
Set1(replyBuf + 8, kJDWPFlagReply);
Set2BE(replyBuf + 9, result);
- CHECK_GT(expandBufGetLength(pReply), 0U) << GetCommandName(request) << " " << request.GetId();
+ CHECK_GT(expandBufGetLength(pReply), 0U) << GetCommandName(request) << " " << request->GetId();
size_t respLen = expandBufGetLength(pReply) - kJDWPHeaderLen;
VLOG(jdwp) << "REPLY: " << GetCommandName(request) << " " << result << " (length=" << respLen << ")";
@@ -1750,7 +1750,7 @@ size_t JdwpState::ProcessRequest(Request& request, ExpandBuf* pReply) {
* Update last-activity timestamp. We really only need this during
* the initial setup. Only update if this is a non-DDMS packet.
*/
- if (request.GetCommandSet() != kJDWPDdmCmdSet) {
+ if (request->GetCommandSet() != kJDWPDdmCmdSet) {
last_activity_time_ms_.StoreSequentiallyConsistent(MilliTime());
}
diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc
index a4f427ca29..c500ef5311 100644
--- a/runtime/jdwp/jdwp_main.cc
+++ b/runtime/jdwp/jdwp_main.cc
@@ -373,7 +373,7 @@ bool JdwpState::HandlePacket() {
JDWP::Request request(netStateBase->input_buffer_, netStateBase->input_count_);
ExpandBuf* pReply = expandBufAlloc();
- size_t replyLength = ProcessRequest(request, pReply);
+ size_t replyLength = ProcessRequest(&request, pReply);
ssize_t cc = netStateBase->WritePacket(pReply, replyLength);
/*
diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc
index ad18d8a2ce..35aaf0ab8f 100644
--- a/runtime/jdwp/object_registry.cc
+++ b/runtime/jdwp/object_registry.cc
@@ -21,8 +21,6 @@
namespace art {
-mirror::Object* const ObjectRegistry::kInvalidObject = reinterpret_cast<mirror::Object*>(1);
-
std::ostream& operator<<(std::ostream& os, const ObjectRegistryEntry& rhs) {
os << "ObjectRegistryEntry[" << rhs.jni_reference_type
<< ",reference=" << rhs.jni_reference
@@ -129,14 +127,16 @@ void ObjectRegistry::Clear() {
id_to_entry_.clear();
}
-mirror::Object* ObjectRegistry::InternalGet(JDWP::ObjectId id) {
+mirror::Object* ObjectRegistry::InternalGet(JDWP::ObjectId id, JDWP::JdwpError* error) {
Thread* self = Thread::Current();
MutexLock mu(self, lock_);
auto it = id_to_entry_.find(id);
if (it == id_to_entry_.end()) {
- return kInvalidObject;
+ *error = JDWP::ERR_INVALID_OBJECT;
+ return nullptr;
}
ObjectRegistryEntry& entry = *it->second;
+ *error = JDWP::ERR_NONE;
return self->DecodeJObject(entry.jni_reference);
}
diff --git a/runtime/jdwp/object_registry.h b/runtime/jdwp/object_registry.h
index f0314a382f..0e46d5cf20 100644
--- a/runtime/jdwp/object_registry.h
+++ b/runtime/jdwp/object_registry.h
@@ -22,6 +22,7 @@
#include <map>
+#include "base/casts.h"
#include "jdwp/jdwp.h"
#include "safe_map.h"
@@ -64,11 +65,13 @@ class ObjectRegistry {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(Locks::thread_list_lock_);
JDWP::RefTypeId AddRefType(mirror::Class* c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<typename T> T Get(JDWP::ObjectId id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ template<typename T> T Get(JDWP::ObjectId id, JDWP::JdwpError* error)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (id == 0) {
- return NULL;
+ *error = JDWP::ERR_NONE;
+ return nullptr;
}
- return reinterpret_cast<T>(InternalGet(id));
+ return down_cast<T>(InternalGet(id, error));
}
bool Contains(mirror::Object* o) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -85,9 +88,6 @@ class ObjectRegistry {
void DisposeObject(JDWP::ObjectId id, uint32_t reference_count)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- // Returned by Get when passed an invalid object id.
- static mirror::Object* const kInvalidObject;
-
// This is needed to get the jobject instead of the Object*.
// Avoid using this and use standard Get when possible.
jobject GetJObject(JDWP::ObjectId id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -95,7 +95,8 @@ class ObjectRegistry {
private:
JDWP::ObjectId InternalAdd(mirror::Object* o)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(Locks::thread_list_lock_);
- mirror::Object* InternalGet(JDWP::ObjectId id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Object* InternalGet(JDWP::ObjectId id, JDWP::JdwpError* error)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void Demote(ObjectRegistryEntry& entry) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, lock_);
void Promote(ObjectRegistryEntry& entry) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, lock_);
bool Contains(mirror::Object* o, ObjectRegistryEntry** out_entry)
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 919655695a..3e9ae09bde 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -2261,25 +2261,15 @@ class JNI {
IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
IndirectRefKind kind = GetIndirectRefKind(ref);
switch (kind) {
- case kLocal: {
- ScopedObjectAccess soa(env);
- // The local refs don't need a read barrier.
- if (static_cast<JNIEnvExt*>(env)->locals.Get<kWithoutReadBarrier>(ref) !=
- kInvalidIndirectRefObject) {
- return JNILocalRefType;
- }
- return JNIInvalidRefType;
- }
+ case kLocal:
+ return JNILocalRefType;
case kGlobal:
return JNIGlobalRefType;
case kWeakGlobal:
return JNIWeakGlobalRefType;
case kHandleScopeOrInvalid:
- // Is it in a stack IRT?
- if (static_cast<JNIEnvExt*>(env)->self->HandleScopeContains(java_object)) {
- return JNILocalRefType;
- }
- return JNIInvalidRefType;
+ // Assume value is in a handle scope.
+ return JNILocalRefType;
}
LOG(FATAL) << "IndirectRefKind[" << kind << "]";
return JNIInvalidRefType;
diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc
index b236edea9e..20d031c3e5 100644
--- a/runtime/jni_internal_test.cc
+++ b/runtime/jni_internal_test.cc
@@ -1269,13 +1269,14 @@ TEST_F(JniInternalTest, GetObjectRefType) {
jweak weak_global = env_->NewWeakGlobalRef(local);
EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global));
+ CheckJniAbortCatcher jni_abort_catcher;
jobject invalid = reinterpret_cast<jobject>(this);
EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid));
+ jni_abort_catcher.Check("use of invalid jobject");
// TODO: invoke a native method and test that its arguments are considered local references.
// Null as object should fail.
- CheckJniAbortCatcher jni_abort_catcher;
EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr));
jni_abort_catcher.Check("java_object == null");
}
@@ -1687,7 +1688,7 @@ TEST_F(JniInternalTest, DeleteLocalRef) {
CheckJniAbortCatcher check_jni_abort_catcher;
EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
env_->DeleteLocalRef(s);
- std::string expected(StringPrintf("jobject is an invalid local reference: %p", s));
+ std::string expected(StringPrintf("use of deleted local reference %p", s));
check_jni_abort_catcher.Check(expected.c_str());
EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
}
@@ -1723,7 +1724,6 @@ TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
jobject outer;
jobject inner1, inner2;
ScopedObjectAccess soa(env_);
- mirror::Object* inner2_direct_pointer;
{
ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
outer = env_->NewLocalRef(original);
@@ -1732,24 +1732,35 @@ TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) {
ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4));
inner1 = env_->NewLocalRef(outer);
inner2 = env_->NewStringUTF("survivor");
- inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
- env_->PopLocalFrame(inner2);
+ EXPECT_NE(env_->PopLocalFrame(inner2), nullptr);
}
EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer));
- EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
+ {
+ CheckJniAbortCatcher check_jni_abort_catcher;
+ EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
+ check_jni_abort_catcher.Check("use of deleted local reference");
+ }
// Our local reference for the survivor is invalid because the survivor
// gets a new local reference...
- EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
+ {
+ CheckJniAbortCatcher check_jni_abort_catcher;
+ EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
+ check_jni_abort_catcher.Check("use of deleted local reference");
+ }
- env_->PopLocalFrame(nullptr);
+ EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr);
}
EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original));
+ CheckJniAbortCatcher check_jni_abort_catcher;
EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer));
+ check_jni_abort_catcher.Check("use of deleted local reference");
EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1));
+ check_jni_abort_catcher.Check("use of deleted local reference");
EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2));
+ check_jni_abort_catcher.Check("use of deleted local reference");
}
TEST_F(JniInternalTest, NewGlobalRef_nullptr) {
@@ -1788,7 +1799,7 @@ TEST_F(JniInternalTest, DeleteGlobalRef) {
CheckJniAbortCatcher check_jni_abort_catcher;
EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
env_->DeleteGlobalRef(o);
- std::string expected(StringPrintf("jobject is an invalid global reference: %p", o));
+ std::string expected(StringPrintf("use of deleted global reference %p", o));
check_jni_abort_catcher.Check(expected.c_str());
EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
}
@@ -1838,7 +1849,7 @@ TEST_F(JniInternalTest, DeleteWeakGlobalRef) {
CheckJniAbortCatcher check_jni_abort_catcher;
EXPECT_FALSE(vm_->SetCheckJniEnabled(true));
env_->DeleteWeakGlobalRef(o);
- std::string expected(StringPrintf("jobject is an invalid weak global reference: %p", o));
+ std::string expected(StringPrintf("use of deleted weak global reference %p", o));
check_jni_abort_catcher.Check(expected.c_str());
EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni));
}
diff --git a/runtime/reference_table.cc b/runtime/reference_table.cc
index 70aba9bbf1..01c5070869 100644
--- a/runtime/reference_table.cc
+++ b/runtime/reference_table.cc
@@ -24,6 +24,7 @@
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
#include "mirror/string-inl.h"
+#include "runtime-inl.h"
#include "thread.h"
#include "utils.h"
@@ -62,7 +63,9 @@ void ReferenceTable::Remove(mirror::Object* obj) {
// If "obj" is an array, return the number of elements in the array.
// Otherwise, return zero.
static size_t GetElementCount(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (obj == NULL || obj == kClearedJniWeakGlobal || !obj->IsArrayInstance()) {
+ // We assume the special cleared value isn't an array in the if statement below.
+ DCHECK(!Runtime::Current()->GetClearedJniWeakGlobal()->IsArrayInstance());
+ if (obj == nullptr || !obj->IsArrayInstance()) {
return 0;
}
return obj->AsArray()->GetLength();
@@ -81,9 +84,10 @@ struct ObjectComparator {
} else if (obj2 == NULL) {
return false;
}
- if (obj1 == kClearedJniWeakGlobal) {
+ Runtime* runtime = Runtime::Current();
+ if (runtime->IsClearedJniWeakGlobal(obj1)) {
return true;
- } else if (obj2 == kClearedJniWeakGlobal) {
+ } else if (runtime->IsClearedJniWeakGlobal(obj2)) {
return false;
}
@@ -116,7 +120,7 @@ static void DumpSummaryLine(std::ostream& os, mirror::Object* obj, size_t elemen
os << " NULL reference (count=" << equiv << ")\n";
return;
}
- if (obj == kClearedJniWeakGlobal) {
+ if (Runtime::Current()->IsClearedJniWeakGlobal(obj)) {
os << " cleared jweak (count=" << equiv << ")\n";
return;
}
@@ -167,7 +171,7 @@ void ReferenceTable::Dump(std::ostream& os, Table& entries) {
if (ref == NULL) {
continue;
}
- if (ref == kClearedJniWeakGlobal) {
+ if (Runtime::Current()->IsClearedJniWeakGlobal(ref)) {
os << StringPrintf(" %5d: cleared jweak\n", idx);
continue;
}
@@ -209,7 +213,8 @@ void ReferenceTable::Dump(std::ostream& os, Table& entries) {
sorted_entries.pop_back();
}
while (!sorted_entries.empty() &&
- sorted_entries.back().Read<kWithoutReadBarrier>() == kClearedJniWeakGlobal) {
+ Runtime::Current()->IsClearedJniWeakGlobal(
+ sorted_entries.back().Read<kWithoutReadBarrier>())) {
sorted_entries.pop_back();
}
if (sorted_entries.empty()) {
diff --git a/runtime/runtime-inl.h b/runtime/runtime-inl.h
index ac9026b605..8b632b2459 100644
--- a/runtime/runtime-inl.h
+++ b/runtime/runtime-inl.h
@@ -23,6 +23,18 @@
namespace art {
+inline bool Runtime::IsClearedJniWeakGlobal(mirror::Object* obj) {
+ return obj == GetClearedJniWeakGlobal();
+}
+
+inline mirror::Object* Runtime::GetClearedJniWeakGlobal() {
+ mirror::Object* obj = sentinel_.Read();
+ if (obj == nullptr) {
+ LOG(ERROR) << "Failed to return cleared JNI weak global sentinel";
+ }
+ return obj;
+}
+
inline QuickMethodFrameInfo Runtime::GetRuntimeMethodFrameInfo(mirror::ArtMethod* method) {
DCHECK(method != nullptr);
// Cannot be imt-conflict-method or resolution-method.
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 1a682fb2e0..65ae5b79c8 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -796,6 +796,10 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized)
class_linker_->InitWithoutImage(*options->boot_class_path_);
}
CHECK(class_linker_ != nullptr);
+
+ // Initialize the special sentinel_ value early.
+ sentinel_ = GcRoot<mirror::Object>(class_linker_->AllocObject(self));
+
verifier::MethodVerifier::Init();
method_trace_ = options->method_trace_;
@@ -1084,6 +1088,10 @@ void Runtime::VisitConcurrentRoots(RootCallback* callback, void* arg, VisitRootF
void Runtime::VisitNonThreadRoots(RootCallback* callback, void* arg) {
java_vm_->VisitRoots(callback, arg);
+ if (!sentinel_.IsNull()) {
+ sentinel_.VisitRoot(callback, arg, 0, kRootVMInternal);
+ DCHECK(!sentinel_.IsNull());
+ }
if (!pre_allocated_OutOfMemoryError_.IsNull()) {
pre_allocated_OutOfMemoryError_.VisitRoot(callback, arg, 0, kRootVMInternal);
DCHECK(!pre_allocated_OutOfMemoryError_.IsNull());
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 03952c48cf..caed6643fa 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -244,6 +244,12 @@ class Runtime {
return monitor_pool_;
}
+ // Is the given object the special object used to mark a cleared JNI weak global?
+ bool IsClearedJniWeakGlobal(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Get the special object used to mark a cleared JNI weak global.
+ mirror::Object* GetClearedJniWeakGlobal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
mirror::Throwable* GetPreAllocatedOutOfMemoryError() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::Throwable* GetPreAllocatedNoClassDefFoundError()
@@ -517,6 +523,10 @@ class Runtime {
GcRoot<mirror::ArtMethod> imt_conflict_method_;
GcRoot<mirror::ObjectArray<mirror::ArtMethod>> default_imt_;
+ // Special sentinel object used to invalid conditions in JNI (cleared weak references) and
+ // JDWP (invalid references).
+ GcRoot<mirror::Object> sentinel_;
+
InstructionSet instruction_set_;
QuickMethodFrameInfo callee_save_method_frame_infos_[kLastCalleeSaveType];
diff --git a/runtime/thread.cc b/runtime/thread.cc
index e0d67d643a..e3234736e2 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -911,7 +911,6 @@ struct StackDumpVisitor : public StackVisitor {
std::ostream& os;
const Thread* thread;
const bool can_allocate;
- mirror::ArtMethod* method;
mirror::ArtMethod* last_method;
int last_line_number;
int repetition_count;
@@ -1238,7 +1237,7 @@ void Thread::RemoveFromThreadGroup(ScopedObjectAccess& soa) {
size_t Thread::NumHandleReferences() {
size_t count = 0;
- for (HandleScope* cur = tlsPtr_.top_handle_scope; cur; cur = cur->GetLink()) {
+ for (HandleScope* cur = tlsPtr_.top_handle_scope; cur != nullptr; cur = cur->GetLink()) {
count += cur->NumberOfReferences();
}
return count;
@@ -1247,7 +1246,7 @@ size_t Thread::NumHandleReferences() {
bool Thread::HandleScopeContains(jobject obj) const {
StackReference<mirror::Object>* hs_entry =
reinterpret_cast<StackReference<mirror::Object>*>(obj);
- for (HandleScope* cur = tlsPtr_.top_handle_scope; cur; cur = cur->GetLink()) {
+ for (HandleScope* cur = tlsPtr_.top_handle_scope; cur!= nullptr; cur = cur->GetLink()) {
if (cur->Contains(hs_entry)) {
return true;
}
@@ -1280,6 +1279,7 @@ mirror::Object* Thread::DecodeJObject(jobject obj) const {
IndirectRef ref = reinterpret_cast<IndirectRef>(obj);
IndirectRefKind kind = GetIndirectRefKind(ref);
mirror::Object* result;
+ bool expect_null = false;
// The "kinds" below are sorted by the frequency we expect to encounter them.
if (kind == kLocal) {
IndirectReferenceTable& locals = tlsPtr_.jni_env->locals;
@@ -1293,20 +1293,23 @@ mirror::Object* Thread::DecodeJObject(jobject obj) const {
result = reinterpret_cast<StackReference<mirror::Object>*>(obj)->AsMirrorPtr();
VerifyObject(result);
} else {
- result = kInvalidIndirectRefObject;
+ tlsPtr_.jni_env->vm->JniAbortF(nullptr, "use of invalid jobject %p", obj);
+ expect_null = true;
+ result = nullptr;
}
} else if (kind == kGlobal) {
result = tlsPtr_.jni_env->vm->DecodeGlobal(const_cast<Thread*>(this), ref);
} else {
DCHECK_EQ(kind, kWeakGlobal);
result = tlsPtr_.jni_env->vm->DecodeWeakGlobal(const_cast<Thread*>(this), ref);
- if (result == kClearedJniWeakGlobal) {
+ if (Runtime::Current()->IsClearedJniWeakGlobal(result)) {
// This is a special case where it's okay to return nullptr.
- return nullptr;
+ expect_null = true;
+ result = nullptr;
}
}
- if (UNLIKELY(result == nullptr)) {
+ if (UNLIKELY(!expect_null && result == nullptr)) {
tlsPtr_.jni_env->vm->JniAbortF(nullptr, "use of deleted %s %p",
ToStr<IndirectRefKind>(kind).c_str(), obj);
}