diff options
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | src/check_jni.cc | 3 | ||||
-rw-r--r-- | src/compiler/codegen/arm/Thumb2/Gen.cc | 1 | ||||
-rw-r--r-- | src/java_lang_Class.cc | 2 | ||||
-rw-r--r-- | src/java_lang_reflect_Constructor.cc | 5 | ||||
-rw-r--r-- | src/jni_internal.cc | 4 | ||||
-rw-r--r-- | src/object.cc | 1 | ||||
-rw-r--r-- | src/object.h | 13 | ||||
-rw-r--r-- | src/object_test.cc | 11 | ||||
-rw-r--r-- | src/runtime.cc | 7 | ||||
-rw-r--r-- | src/thread.cc | 7 | ||||
-rw-r--r-- | src/thread.h | 2 | ||||
-rw-r--r-- | test/IntMath/IntMath.java | 6 |
13 files changed, 42 insertions, 22 deletions
@@ -156,7 +156,7 @@ test-art-target-oat-process-Calculator: $(TARGET_OUT_APPS)/Calculator.oat $(TARG # oatdump targets .PHONY: dump-oat -dump-oat: dump-oat-core dump-oat-boot +dump-oat: dump-oat-core dump-oat-boot dump-oat-Calculator .PHONY: dump-oat-core dump-oat-core: $(TARGET_CORE_OAT) $(OATDUMP) diff --git a/src/check_jni.cc b/src/check_jni.cc index 6ff0fd7..2208d14 100644 --- a/src/check_jni.cc +++ b/src/check_jni.cc @@ -236,9 +236,10 @@ public: return; } + CHECK(fid != NULL) << PrettyTypeOf(o); Field* f = DecodeField(fid); Class* f_type = f->GetType(); - // check invariant that all jfieldIDs have resovled types + // check invariant that all jfieldIDs have resolved types DCHECK(f_type != NULL); Class* c = o->GetClass(); if (c->FindInstanceField(f->GetName()->ToModifiedUtf8(), f_type) == NULL) { diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc index c9d1bb9..e3893d3 100644 --- a/src/compiler/codegen/arm/Thumb2/Gen.cc +++ b/src/compiler/codegen/arm/Thumb2/Gen.cc @@ -707,6 +707,7 @@ STATIC void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest, // At this point, r2 has class loadValueDirectFixed(cUnit, rlSrc, r3); /* Ref */ /* When taken r0 has NULL which can be used for store directly */ + loadConstant(cUnit, r0, 0); /* Assume false */ ArmLIR* branch1 = genCmpImmBranch(cUnit, kArmCondEq, r3, 0); /* load object->clazz */ DCHECK_EQ(Object::ClassOffset().Int32Value(), 0); diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc index 4fe3191..68b83f2 100644 --- a/src/java_lang_Class.cc +++ b/src/java_lang_Class.cc @@ -327,7 +327,7 @@ jboolean Class_isInstance(JNIEnv* env, jobject javaClass, jobject javaObject) { if (o == NULL) { return JNI_FALSE; } - return Object::InstanceOf(o, c) ? JNI_TRUE : JNI_FALSE; + return o->InstanceOf(c) ? JNI_TRUE : JNI_FALSE; } jboolean Class_isInterface(JNIEnv* env, jobject javaThis) { diff --git a/src/java_lang_reflect_Constructor.cc b/src/java_lang_reflect_Constructor.cc index 10a8f07..6cc8ea7 100644 --- a/src/java_lang_reflect_Constructor.cc +++ b/src/java_lang_reflect_Constructor.cc @@ -40,6 +40,11 @@ jobject Constructor_constructNative(JNIEnv* env, jobject javaMethod, jobjectArra return NULL; } + if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true)) { + DCHECK(Thread::Current()->IsExceptionPending()); + return NULL; + } + Object* receiver = c->AllocObject(); if (receiver == NULL) { return NULL; diff --git a/src/jni_internal.cc b/src/jni_internal.cc index fd6d314..0436500 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -691,12 +691,12 @@ class JNI { ScopedJniThreadState ts(env); CHECK_NE(static_cast<jclass>(NULL), clazz); // TODO: ReportJniError if (jobj == NULL) { - // NB. JNI is different from regular Java instanceof in this respect + // Note: JNI is different from regular Java instanceof in this respect return JNI_TRUE; } else { Object* obj = Decode<Object*>(ts, jobj); Class* klass = Decode<Class*>(ts, clazz); - return Object::InstanceOf(obj, klass) ? JNI_TRUE : JNI_FALSE; + return obj->InstanceOf(klass) ? JNI_TRUE : JNI_FALSE; } } diff --git a/src/object.cc b/src/object.cc index cfc18bf..5017c23 100644 --- a/src/object.cc +++ b/src/object.cc @@ -807,6 +807,7 @@ Object* Class::AllocObject() { DCHECK(!IsAbstract()) << PrettyClass(this); DCHECK(!IsInterface()) << PrettyClass(this); DCHECK(!IsPrimitive()) << PrettyClass(this); + DCHECK(!Runtime::Current()->IsStarted() || IsInitializing()) << PrettyClass(this); return Heap::AllocObject(this, this->object_size_); } diff --git a/src/object.h b/src/object.h index 1a137bd..47aa98d 100644 --- a/src/object.h +++ b/src/object.h @@ -191,11 +191,9 @@ static const uint32_t kAccReferenceFlagsMask = (kAccClassIsReference // C++ mirror of java.lang.Object class MANAGED Object { public: - static bool InstanceOf(const Object* object, const Class* klass) { - if (object == NULL) { - return false; - } - return object->InstanceOf(klass); + static uint32_t InstanceOfFromCode(const Object* object, const Class* klass) { + DCHECK(object != NULL); + return object->InstanceOf(klass) ? 1 : 0; } static MemberOffset ClassOffset() { @@ -1295,6 +1293,11 @@ class MANAGED Class : public StaticStorageBase { return GetStatus() >= kStatusVerified; } + // Returns true if the class is initializing. + bool IsInitializing() const { + return GetStatus() >= kStatusInitializing; + } + // Returns true if the class is initialized. bool IsInitialized() const { return GetStatus() == kStatusInitialized; diff --git a/src/object_test.cc b/src/object_test.cc index d6705d7..f263872 100644 --- a/src/object_test.cc +++ b/src/object_test.cc @@ -328,18 +328,15 @@ TEST_F(ObjectTest, InstanceOf) { ASSERT_TRUE(X != NULL); ASSERT_TRUE(Y != NULL); - EXPECT_FALSE(Object::InstanceOf(NULL, X)); - EXPECT_FALSE(Object::InstanceOf(NULL, Y)); - Object* x = X->AllocObject(); Object* y = Y->AllocObject(); ASSERT_TRUE(x != NULL); ASSERT_TRUE(y != NULL); - EXPECT_TRUE(Object::InstanceOf(x, X)); - EXPECT_FALSE(Object::InstanceOf(x, Y)); - EXPECT_TRUE(Object::InstanceOf(y, X)); - EXPECT_TRUE(Object::InstanceOf(y, Y)); + EXPECT_EQ(1U, Object::InstanceOfFromCode(x, X)); + EXPECT_EQ(0U, Object::InstanceOfFromCode(x, Y)); + EXPECT_EQ(1U, Object::InstanceOfFromCode(y, X)); + EXPECT_EQ(1U, Object::InstanceOfFromCode(y, Y)); EXPECT_TRUE(x->InstanceOf(X)); EXPECT_FALSE(x->InstanceOf(Y)); diff --git a/src/runtime.cc b/src/runtime.cc index ca1d4f8..eb5e498 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -359,14 +359,17 @@ Runtime* Runtime::Create(const Options& options, bool ignore_unrecognized) { } void Runtime::Start() { - started_ = true; - InitNativeMethods(); Thread::FinishStartup(); class_linker_->RunRootClinits(); + // Class::AllocObject asserts that all objects allocated better be + // initialized after Runtime::IsStarted is true, so this needs to + // come after ClassLinker::RunRootClinits. + started_ = true; + StartDaemonThreads(); } diff --git a/src/thread.cc b/src/thread.cc index 4e3e8d1..d79e1c5 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -230,6 +230,11 @@ extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method) { return NULL; // Failure } } + if (!klass->IsInitialized() + && !Runtime::Current()->GetClassLinker()->EnsureInitialized(klass, true)) { + DCHECK(Thread::Current()->IsExceptionPending()); + return NULL; // Failure + } return klass->AllocObject(); } @@ -497,7 +502,7 @@ void Thread::InitFunctionPointers() { pSetObjStatic = Field::SetObjStaticFromCode; pInitializeTypeFromCode = InitializeTypeFromCode; pResolveMethodFromCode = ResolveMethodFromCode; - pInstanceofNonTrivialFromCode = Object::InstanceOf; + pInstanceofNonTrivialFromCode = Object::InstanceOfFromCode; pLockObjectFromCode = LockObjectFromCode; pFindInstanceFieldFromCode = Field::FindInstanceFieldFromCode; pCheckSuspendFromCode = artCheckSuspendFromCode; diff --git a/src/thread.h b/src/thread.h index 01cc1cc..123a376 100644 --- a/src/thread.h +++ b/src/thread.h @@ -210,7 +210,7 @@ class PACKED Thread { Object* (*pGetObjStatic)(uint32_t, const Method*); void (*pSetObjStatic)(uint32_t, const Method*, Object*); void (*pCanPutArrayElementFromCode)(void*, void*); - bool (*pInstanceofNonTrivialFromCode) (const Object*, const Class*); + uint32_t (*pInstanceofNonTrivialFromCode) (const Object*, const Class*); void (*pCheckCastFromCode) (void*, void*); Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); void (*pUnlockObjectFromCode)(void*, void*); diff --git a/test/IntMath/IntMath.java b/test/IntMath/IntMath.java index 7b0d5f8..21f84bb 100644 --- a/test/IntMath/IntMath.java +++ b/test/IntMath/IntMath.java @@ -54,6 +54,10 @@ class IntMath extends IntMathBase { IntMathBase a = new IntMathBase(); IntMath b = new IntMath(); + if (!(null instanceof IntMathBase)) { + x = x + 42; + } + if (a instanceof IntMathBase) { x = x * 2; } @@ -1116,7 +1120,7 @@ class IntMath extends IntMathBase { } res = instanceTest(10); - if (res == 1352) { + if (res == 1436) { System.out.println("instanceTest PASSED"); } else { System.out.println("instanceTest FAILED: " + res); |