summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
}