Merge "Add missing x86 imul opcode to disassembler"
diff --git a/compiler/dex/arena_allocator.cc b/compiler/dex/arena_allocator.cc
index 95e44b3..132831c 100644
--- a/compiler/dex/arena_allocator.cc
+++ b/compiler/dex/arena_allocator.cc
@@ -28,6 +28,7 @@
 static constexpr bool kUseMemMap = false;
 static constexpr bool kUseMemSet = true && kUseMemMap;
 static constexpr size_t kValgrindRedZoneBytes = 8;
+constexpr size_t Arena::kDefaultSize;
 
 static const char* alloc_names[ArenaAllocator::kNumAllocKinds] = {
   "Misc       ",
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index abafbc5..3368132 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -52,12 +52,6 @@
     return *unit_.GetDexFile();
   }
 
-  // TODO: since the whole compilation pipeline uses a "const DexFile", we need
-  // to "unconst" here. The DEX-to-DEX compiler should work on a non-const DexFile.
-  DexFile& GetModifiableDexFile() {
-    return *const_cast<DexFile*>(unit_.GetDexFile());
-  }
-
   bool PerformOptimizations() const {
     return dex_to_dex_compilation_level_ >= kOptimize;
   }
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc
index fb471ab..b21e37e 100644
--- a/compiler/dex/quick/dex_file_method_inliner.cc
+++ b/compiler/dex/quick/dex_file_method_inliner.cc
@@ -22,6 +22,7 @@
 
 namespace art {
 
+const uint32_t DexFileMethodInliner::kIndexUnresolved;
 const char* DexFileMethodInliner::kClassCacheNames[] = {
     "Z",                       // kClassCacheBoolean
     "B",                       // kClassCacheByte
diff --git a/runtime/base/timing_logger.cc b/runtime/base/timing_logger.cc
index bb32b2d..fe18f66 100644
--- a/runtime/base/timing_logger.cc
+++ b/runtime/base/timing_logger.cc
@@ -31,6 +31,8 @@
 
 namespace art {
 
+constexpr size_t CumulativeLogger::kLowMemoryBucketCount;
+constexpr size_t CumulativeLogger::kDefaultBucketCount;
 CumulativeLogger::CumulativeLogger(const std::string& name)
     : name_(name),
       lock_name_("CumulativeLoggerLock" + name),
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index bb44db8..bcf7267 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -796,18 +796,37 @@
 
 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) {
+    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);
+  // 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) {
+    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_) {
+  mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
+  // JDWP specs state an INVALID_OBJECT error is returned if the object ID is not valid. However
+  // the RI seems to ignore this and does not return any error in this case. Let's comply with
+  // JDWP specs here.
+  if (o == NULL || o == ObjectRegistry::kInvalidObject) {
+    return JDWP::ERR_INVALID_OBJECT;
+  }
   is_collected = gRegistry->IsCollected(object_id);
   return JDWP::ERR_NONE;
 }
@@ -2713,7 +2732,7 @@
         if (argument == ObjectRegistry::kInvalidObject) {
           return JDWP::ERR_INVALID_OBJECT;
         }
-        if (!argument->InstanceOf(parameter_type)) {
+        if (argument != NULL && !argument->InstanceOf(parameter_type)) {
           return JDWP::ERR_ILLEGAL_ARGUMENT;
         }
 
diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc
index be2219c..369eddd 100644
--- a/runtime/jdwp/object_registry.cc
+++ b/runtime/jdwp/object_registry.cc
@@ -118,6 +118,9 @@
 }
 
 jobject ObjectRegistry::GetJObject(JDWP::ObjectId id) {
+  if (id == 0) {
+    return NULL;
+  }
   Thread* self = Thread::Current();
   MutexLock mu(self, lock_);
   id_iterator it = id_to_entry_.find(id);
@@ -130,9 +133,7 @@
   Thread* self = Thread::Current();
   MutexLock mu(self, lock_);
   id_iterator it = id_to_entry_.find(id);
-  if (it == id_to_entry_.end()) {
-    return;
-  }
+  CHECK(it != id_to_entry_.end());
   Promote(*(it->second));
 }
 
@@ -140,9 +141,7 @@
   Thread* self = Thread::Current();
   MutexLock mu(self, lock_);
   id_iterator it = id_to_entry_.find(id);
-  if (it == id_to_entry_.end()) {
-    return;
-  }
+  CHECK(it != id_to_entry_.end());
   Demote(*(it->second));
 }
 
@@ -172,9 +171,7 @@
   Thread* self = Thread::Current();
   MutexLock mu(self, lock_);
   id_iterator it = id_to_entry_.find(id);
-  if (it == id_to_entry_.end()) {
-    return true;  // TODO: can we report that this was an invalid id?
-  }
+  CHECK(it != id_to_entry_.end());
 
   ObjectRegistryEntry& entry = *(it->second);
   if (entry.jni_reference_type == JNIWeakGlobalRefType) {