Adding Object::InstanceOf and Class::IsAssignableFrom
Summary:
- Add Object::InstanceOf and Class::IsAssignableFrom
- Fix Cloneable and Serializable interfaces on arrays to be == with FindSystemClass results
- Changed Object::Alloc(Class*) to be Class->NewInstance()
Details:
Add Object::InstanceOf and Class::IsAssignableFrom
object.h
common_test.h
object_test.cc
Fix bug where Cloneable and Serializable where created with AllocClass
and never inserted in the classes table with FindSystemClass by just
creating them directly with FindSystemClass
class_linker.cc
object_test.cc
Changed Object::Alloc(Class*) to be Class->NewInstance()
class_linker.cc
object.h
Change-Id: I528767fff43aff32c8dc4f7a2d4157598a7dbb89
diff --git a/src/object.h b/src/object.h
index 5e6c175..c1682ec 100644
--- a/src/object.h
+++ b/src/object.h
@@ -110,12 +110,19 @@
class Object {
public:
- static Object* Alloc(Class* klass);
+ static bool InstanceOf(const Object* object, const Class* klass) {
+ if (object == NULL) {
+ return false;
+ }
+ return object->InstanceOf(klass);
+ }
Class* GetClass() const {
return klass_;
}
+ bool InstanceOf(const Class* klass) const;
+
void MonitorEnter() {
monitor_->Enter();
}
@@ -739,6 +746,10 @@
kPrimNot = -1
};
+ Object* NewInstance() {
+ return Heap::AllocObject(this, this->object_size_);
+ }
+
Class* GetSuperClass() const {
return super_class_;
}
@@ -751,6 +762,20 @@
return super_class_ != NULL;
}
+ bool IsAssignableFrom(const Class* klass) const {
+ DCHECK(klass != NULL);
+ if (this == klass) {
+ return true;
+ }
+ if (IsInterface()) {
+ return klass->Implements(this);
+ }
+ if (klass->IsArray()) {
+ return IsAssignableFromArray(klass);
+ }
+ return klass->IsSubClass(this);
+ }
+
ClassLoader* GetClassLoader() const {
return class_loader_;
}
@@ -898,7 +923,7 @@
return num_reference_instance_fields_;
}
- InstanceField* GetInstanceField(uint32_t i) { // TODO: uint16_t
+ InstanceField* GetInstanceField(uint32_t i) const { // TODO: uint16_t
DCHECK_NE(NumInstanceFields(), 0U);
return ifields_->Get(i);
}
@@ -944,6 +969,18 @@
interfaces_->Set(i, f);
}
+ void SetVerifyErrorClass(Class* klass) {
+ // Note SetFieldObject is used rather than verify_error_class_ directly for the barrier
+ size_t field_offset = OFFSETOF_MEMBER(Class, verify_error_class_);
+ klass->SetFieldObject(field_offset, klass);
+ }
+
+ private:
+ bool Implements(const Class* klass) const;
+ bool IsArrayAssignableFromArray(const Class* klass) const;
+ bool IsAssignableFromArray(const Class* klass) const;
+ bool IsSubClass(const Class* klass) const;
+
public: // TODO: private
// leave space for instance data; we could access fields directly if
// we freeze the definition of java/lang/Class
@@ -970,8 +1007,9 @@
// state of class initialization
Status status_;
- // if class verify fails, we must return same error on subsequent tries
- Class* verify_error_class_;
+ // If class verify fails, we must return same error on subsequent tries.
+ // Update with SetVerifyErrorClass to ensure a write barrier is used.
+ const Class* verify_error_class_;
// threadId, used to check for recursive <clinit> invocation
uint32_t clinit_thread_id_;
@@ -1075,11 +1113,13 @@
};
std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
-inline Object* Object::Alloc(Class* klass) {
+inline bool Object::InstanceOf(const Class* klass) const {
DCHECK(klass != NULL);
- return Heap::AllocObject(klass, klass->object_size_);
+ DCHECK(klass_ != NULL);
+ return klass->IsAssignableFrom(klass_);
}
+
class DataObject : public Object {
public:
uint32_t fields_[0];
@@ -1190,7 +1230,7 @@
static String* Alloc(Class* java_lang_String,
Class* char_array,
int32_t utf16_length) {
- String* string = down_cast<String*>(Object::Alloc(java_lang_String));
+ String* string = down_cast<String*>(java_lang_String->NewInstance());
CharArray* array = CharArray::Alloc(char_array, utf16_length);
string->array_ = array;
string->count_ = utf16_length;