StringPiece clean up.

Profile guided clean up.
Try to avoid creating StringPieces with the contents of a dex file where
the length is known.
Try to avoid RegTypeCache::FromDescriptor when there's a class available.
Make ConstantType::ConstantValue inlinable.
Saving of about 50ms from a 2 threaded ThinkFree compile on host.

Change-Id: I47a12c3c76f46e2c9805be1c3a3e3870fe1f5d85
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 6ee3016..9e107a4 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -111,6 +111,17 @@
     }
   }
 
+  StringPiece GetDescriptorAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    CHECK(klass_ != NULL);
+    if (UNLIKELY(klass_->IsArrayClass() || klass_->IsPrimitive() || klass_->IsProxyClass())) {
+      return StringPiece(GetDescriptor());
+    } else {
+      const DexFile& dex_file = GetDexFile();
+      const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
+      return dex_file.StringDataAsStringPieceByIdx(type_id.descriptor_idx_);
+    }
+  }
+
   const char* GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     std::string result("[");
     const mirror::Class* saved_klass = klass_;
@@ -182,7 +193,7 @@
   }
 
   const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    std::string descriptor(GetDescriptor());
+    std::string descriptor(GetDescriptorAsStringPiece().as_string());
     const DexFile& dex_file = GetDexFile();
     const DexFile::ClassDef* dex_class_def = GetClassDef();
     CHECK(dex_class_def != NULL);
@@ -267,53 +278,77 @@
     }
     field_ = new_f;
   }
+
   const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     uint32_t field_index = field_->GetDexFieldIndex();
-    if (!field_->GetDeclaringClass()->IsProxyClass()) {
-      const DexFile& dex_file = GetDexFile();
-      return dex_file.GetFieldName(dex_file.GetFieldId(field_index));
-    } else {
+    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
       DCHECK(field_->IsStatic());
       DCHECK_LT(field_index, 2U);
       return field_index == 0 ? "interfaces" : "throws";
     }
+    const DexFile& dex_file = GetDexFile();
+    return dex_file.GetFieldName(dex_file.GetFieldId(field_index));
   }
+
+  StringPiece GetNameAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    uint32_t field_index = field_->GetDexFieldIndex();
+    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
+      return StringPiece(GetName());
+    }
+    const DexFile& dex_file = GetDexFile();
+    const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+    return dex_file.StringDataAsStringPieceByIdx(field_id.name_idx_);
+  }
+
   mirror::Class* GetType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     uint32_t field_index = field_->GetDexFieldIndex();
-    if (!field_->GetDeclaringClass()->IsProxyClass()) {
-      const DexFile& dex_file = GetDexFile();
-      const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
-      mirror::Class* type = GetDexCache()->GetResolvedType(field_id.type_idx_);
-      if (resolve && (type == NULL)) {
-        type = GetClassLinker()->ResolveType(field_id.type_idx_, field_);
-        CHECK(type != NULL || Thread::Current()->IsExceptionPending());
-      }
-      return type;
-    } else {
+    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
       return GetClassLinker()->FindSystemClass(GetTypeDescriptor());
     }
+    const DexFile& dex_file = GetDexFile();
+    const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+    mirror::Class* type = GetDexCache()->GetResolvedType(field_id.type_idx_);
+    if (resolve && (type == NULL)) {
+      type = GetClassLinker()->ResolveType(field_id.type_idx_, field_);
+      CHECK(type != NULL || Thread::Current()->IsExceptionPending());
+    }
+    return type;
   }
+
   const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     uint32_t field_index = field_->GetDexFieldIndex();
-    if (!field_->GetDeclaringClass()->IsProxyClass()) {
-      const DexFile& dex_file = GetDexFile();
-      const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
-      return dex_file.GetFieldTypeDescriptor(field_id);
-    } else {
+    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
       DCHECK(field_->IsStatic());
       DCHECK_LT(field_index, 2U);
       // 0 == Class[] interfaces; 1 == Class[][] throws;
       return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
     }
+    const DexFile& dex_file = GetDexFile();
+    const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+    return dex_file.GetFieldTypeDescriptor(field_id);
   }
+
+  StringPiece GetTypeDescriptorAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    uint32_t field_index = field_->GetDexFieldIndex();
+    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
+      return StringPiece(GetTypeDescriptor());
+    }
+    const DexFile& dex_file = GetDexFile();
+    const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+    const DexFile::TypeId& type_id = dex_file.GetTypeId(field_id.type_idx_);
+    return dex_file.StringDataAsStringPieceByIdx(type_id.descriptor_idx_);
+  }
+
   Primitive::Type GetTypeAsPrimitiveType()
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     return Primitive::GetType(GetTypeDescriptor()[0]);
   }
+
   bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     Primitive::Type type = GetTypeAsPrimitiveType();
     return type != Primitive::kPrimNot;
   }
+
   size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     Primitive::Type type = GetTypeAsPrimitiveType();
     return Primitive::FieldSize(type);
@@ -324,18 +359,17 @@
   const char* GetDeclaringClassDescriptor()
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     uint32_t field_index = field_->GetDexFieldIndex();
-    if (!field_->GetDeclaringClass()->IsProxyClass()) {
-      const DexFile& dex_file = GetDexFile();
-      const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
-      return dex_file.GetFieldDeclaringClassDescriptor(field_id);
-    } else {
+    if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
       DCHECK(field_->IsStatic());
       DCHECK_LT(field_index, 2U);
       // 0 == Class[] interfaces; 1 == Class[][] throws;
       ClassHelper kh(field_->GetDeclaringClass());
-      declaring_class_descriptor_ = kh.GetDescriptor();
+      declaring_class_descriptor_ = kh.GetDescriptorAsStringPiece().as_string();
       return declaring_class_descriptor_.c_str();
     }
+    const DexFile& dex_file = GetDexFile();
+    const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
+    return dex_file.GetFieldDeclaringClassDescriptor(field_id);
   }
 
  private:
@@ -417,7 +451,7 @@
   const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     uint32_t dex_method_idx = method_->GetDexMethodIndex();
-    if (dex_method_idx != DexFile::kDexNoIndex) {
+    if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
       return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
     } else {
       Runtime* runtime = Runtime::Current();
@@ -435,6 +469,16 @@
     }
   }
 
+  StringPiece GetNameAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    const DexFile& dex_file = GetDexFile();
+    uint32_t dex_method_idx = method_->GetDexMethodIndex();
+    if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
+      return StringPiece(GetName());
+    }
+    const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
+    return dex_file.StringDataAsStringPieceByIdx(method_id.name_idx_);
+  }
+
   mirror::String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     uint32_t dex_method_idx = method_->GetDexMethodIndex();
@@ -508,11 +552,22 @@
   const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     const DexFile& dex_file = GetDexFile();
     uint32_t dex_method_idx = method_->GetDexMethodIndex();
-    if (dex_method_idx != DexFile::kDexNoIndex) {
-      return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
-    } else {
+    if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
       return "<runtime method>";
     }
+    return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
+  }
+
+  StringPiece GetDeclaringClassDescriptorAsStringPiece()
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    const DexFile& dex_file = GetDexFile();
+    uint32_t dex_method_idx = method_->GetDexMethodIndex();
+    if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
+      return StringPiece("<runtime method>");
+    }
+    const DexFile::MethodId& mid = dex_file.GetMethodId(dex_method_idx);
+    const DexFile::TypeId& type_id = dex_file.GetTypeId(mid.class_idx_);
+    return dex_file.StringDataAsStringPieceByIdx(type_id.descriptor_idx_);
   }
 
   const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -536,7 +591,7 @@
   }
 
   bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return IsStatic() && StringPiece(GetName()) == "<clinit>";
+    return IsStatic() && GetNameAsStringPiece() == "<clinit>";
   }
 
   size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -569,16 +624,56 @@
 
   bool HasSameNameAndSignature(MethodHelper* other)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    const DexFile& dex_file = GetDexFile();
+    const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex());
     if (GetDexCache() == other->GetDexCache()) {
-      const DexFile& dex_file = GetDexFile();
-      const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex());
       const DexFile::MethodId& other_mid =
           dex_file.GetMethodId(other->method_->GetDexMethodIndex());
       return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
     }
-    StringPiece name(GetName());
-    StringPiece other_name(other->GetName());
-    return name == other_name && GetSignature() == other->GetSignature();
+    const DexFile& other_dex_file = other->GetDexFile();
+    const DexFile::MethodId& other_mid =
+        other_dex_file.GetMethodId(other->method_->GetDexMethodIndex());
+    if (dex_file.StringDataAsStringPieceByIdx(mid.name_idx_) !=
+        other_dex_file.StringDataAsStringPieceByIdx(other_mid.name_idx_)) {
+      return false;  // Name mismatch.
+    }
+    const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(mid);
+    const DexFile::ProtoId& other_proto_id = other_dex_file.GetMethodPrototype(other_mid);
+    if (dex_file.StringDataAsStringPieceByIdx(proto_id.shorty_idx_) !=
+        other_dex_file.StringDataAsStringPieceByIdx(other_proto_id.shorty_idx_)) {
+      return false;  // Shorty mismatch.
+    }
+    const DexFile::TypeId& return_type_id = dex_file.GetTypeId(proto_id.return_type_idx_);
+    const DexFile::TypeId& other_return_type_id =
+        other_dex_file.GetTypeId(other_proto_id.return_type_idx_);
+    if (dex_file.StringDataAsStringPieceByIdx(return_type_id.descriptor_idx_) !=
+        other_dex_file.StringDataAsStringPieceByIdx(other_return_type_id.descriptor_idx_)) {
+      return false;  // Return type mismatch.
+    }
+    const DexFile::TypeList* params = dex_file.GetProtoParameters(proto_id);
+    const DexFile::TypeList* other_params = other_dex_file.GetProtoParameters(other_proto_id);
+    if (params == nullptr) {
+      return other_params == nullptr;  // Check both lists are empty.
+    }
+    if (other_params == nullptr) {
+      return false;  // Parameter list size mismatch.
+    }
+    uint32_t params_size = params->Size();
+    uint32_t other_params_size = other_params->Size();
+    if (params_size != other_params_size) {
+      return false;  // Parameter list size mismatch.
+    }
+    for (uint32_t i = 0; i < params_size; ++i) {
+      const DexFile::TypeId& param_id = dex_file.GetTypeId(params->GetTypeItem(i).type_idx_);
+      const DexFile::TypeId& other_param_id =
+          other_dex_file.GetTypeId(other_params->GetTypeItem(i).type_idx_);
+      if (dex_file.StringDataAsStringPieceByIdx(param_id.descriptor_idx_) !=
+          other_dex_file.StringDataAsStringPieceByIdx(other_param_id.descriptor_idx_)) {
+        return false;  // Parameter type mismatch.
+      }
+    }
+    return true;
   }
 
   const DexFile::CodeItem* GetCodeItem()