Filling in some Class, Method, and Field native code needed during startup and I/O
Change-Id: Ia2f2a0ec295d1bd848e6f65254bd9fec2fde56f6
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index 7648425..4bc1caa 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -60,6 +60,27 @@
return env->NewObjectArray(0, java_lang_Class_class, NULL);
}
+jobject Class_getDeclaredField(JNIEnv* env, jclass java_lang_Class_class, jclass jklass, jobject jname) {
+ Class* klass = Decode<Class*>(env, jklass);
+ DCHECK(klass->IsClass());
+ String* name = Decode<String*>(env, jname);
+ DCHECK(name->IsString());
+
+ for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
+ Field* f = klass->GetInstanceField(i);
+ if (f->GetName()->Equals(name)) {
+ return AddLocalReference<jclass>(env, f);
+ }
+ }
+ for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
+ Field* f = klass->GetStaticField(i);
+ if (f->GetName()->Equals(name)) {
+ return AddLocalReference<jclass>(env, f);
+ }
+ }
+ return NULL;
+}
+
jclass Class_getDeclaringClass(JNIEnv* env, jobject javaThis) {
UNIMPLEMENTED(WARNING) << "needs annotations";
return NULL;
@@ -148,7 +169,7 @@
NATIVE_METHOD(Class, getDeclaredClasses, "(Ljava/lang/Class;Z)[Ljava/lang/Class;"),
//NATIVE_METHOD(Class, getDeclaredConstructorOrMethod, "(Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Member;"),
//NATIVE_METHOD(Class, getDeclaredConstructors, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Constructor;"),
- //NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;"),
+ NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Field;"),
//NATIVE_METHOD(Class, getDeclaredFields, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Field;"),
//NATIVE_METHOD(Class, getDeclaredMethods, "(Ljava/lang/Class;Z)[Ljava/lang/reflect/Method;"),
NATIVE_METHOD(Class, getDeclaringClass, "()Ljava/lang/Class;"),
diff --git a/src/java_lang_reflect_Field.cc b/src/java_lang_reflect_Field.cc
new file mode 100644
index 0000000..528c09f
--- /dev/null
+++ b/src/java_lang_reflect_Field.cc
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni_internal.h"
+#include "class_linker.h"
+#include "object.h"
+
+#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
+
+namespace art {
+
+namespace {
+
+jint Field_getFieldModifiers(JNIEnv* env, jobject jfield, jclass javaDeclaringClass, jint slot) {
+ return Decode<Object*>(env, jfield)->AsField()->GetAccessFlags() & kAccFieldFlagsMask;
+}
+
+static JNINativeMethod gMethods[] = {
+ //NATIVE_METHOD(Field, getAnnotation, "(Ljava/lang/Class;ILjava/lang/Class;)Ljava/lang/annotation/Annotation;"),
+ //NATIVE_METHOD(Field, getBField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)B"),
+ //NATIVE_METHOD(Field, getCField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)C"),
+ //NATIVE_METHOD(Field, getDField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)D"),
+ //NATIVE_METHOD(Field, getDeclaredAnnotations, "(Ljava/lang/Class;I)[Ljava/lang/annotation/Annotation;"),
+ //NATIVE_METHOD(Field, getFField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)F"),
+ //NATIVE_METHOD(Field, getField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;"),
+ NATIVE_METHOD(Field, getFieldModifiers, "(Ljava/lang/Class;I)I"),
+ //NATIVE_METHOD(Field, getIField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)I"),
+ //NATIVE_METHOD(Field, getJField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)J"),
+ //NATIVE_METHOD(Field, getSField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)S"),
+ //NATIVE_METHOD(Field, getSignatureAnnotation, "(Ljava/lang/Class;I)[Ljava/lang/Object;"),
+ //NATIVE_METHOD(Field, getZField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZC)Z"),
+ //NATIVE_METHOD(Field, isAnnotationPresent, "(Ljava/lang/Class;ILjava/lang/Class;)Z"),
+ //NATIVE_METHOD(Field, setBField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCB)V"),
+ //NATIVE_METHOD(Field, setCField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCC)V"),
+ //NATIVE_METHOD(Field, setDField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCD)V"),
+ //NATIVE_METHOD(Field, setFField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCF)V"),
+ //NATIVE_METHOD(Field, setField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZLjava/lang/Object;)V"),
+ //NATIVE_METHOD(Field, setIField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCI)V"),
+ //NATIVE_METHOD(Field, setJField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCJ)V"),
+ //NATIVE_METHOD(Field, setSField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCS)V"),
+ //NATIVE_METHOD(Field, setZField, "(Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/Class;IZCZ)V"),
+};
+
+} // namespace
+
+void register_java_lang_reflect_Field(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "java/lang/reflect/Field", gMethods, NELEM(gMethods));
+}
+
+} // namespace art
diff --git a/src/java_lang_reflect_Method.cc b/src/java_lang_reflect_Method.cc
new file mode 100644
index 0000000..c886f59
--- /dev/null
+++ b/src/java_lang_reflect_Method.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni_internal.h"
+#include "class_linker.h"
+#include "object.h"
+
+#include "JniConstants.h" // Last to avoid problems with LOG redefinition.
+
+namespace art {
+
+namespace {
+
+
+// We move the DECLARED_SYNCHRONIZED flag into the SYNCHRONIZED
+// position, because the callers of this function are trying to convey
+// the "traditional" meaning of the flags to their callers.
+uint32_t FixupMethodFlags(uint32_t access_flags) {
+ access_flags &= ~kAccSynchronized;
+ if ((access_flags & kAccDeclaredSynchronized) != 0) {
+ access_flags |= kAccSynchronized;
+ }
+ return access_flags & kAccMethodFlagsMask;
+}
+
+jint Method_getMethodModifiers(JNIEnv* env, jclass, jclass javaDeclaringClass, jobject jmethod, jint slot) {
+ return FixupMethodFlags(Decode<Object*>(env, jmethod)->AsMethod()->GetAccessFlags());
+}
+
+static JNINativeMethod gMethods[] = {
+ //NATIVE_METHOD(Method, getAnnotation, "(Ljava/lang/Class;ILjava/lang/Class;)Ljava/lang/annotation/Annotation;"),
+ //NATIVE_METHOD(Method, getDeclaredAnnotations, "(Ljava/lang/Class;I)[Ljava/lang/annotation/Annotation;"),
+ //NATIVE_METHOD(Method, getDefaultValue, "(Ljava/lang/Class;I)Ljava/lang/Object;"),
+ NATIVE_METHOD(Method, getMethodModifiers, "(Ljava/lang/Class;Ljava/lang/reflect/AccessibleObject;I)I"),
+ //NATIVE_METHOD(Method, getParameterAnnotations, "(Ljava/lang/Class;I)[[Ljava/lang/annotation/Annotation;"),
+ //NATIVE_METHOD(Method, getSignatureAnnotation, "(Ljava/lang/Class;I)[Ljava/lang/Object;"),
+ //NATIVE_METHOD(Method, invokeNative, "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Class;[Ljava/lang/Class;Ljava/lang/Class;IZ)Ljava/lang/Object;"),
+ //NATIVE_METHOD(Method, isAnnotationPresent, "(Ljava/lang/Class;ILjava/lang/Class;)Z"),
+};
+
+} // namespace
+
+void register_java_lang_reflect_Method(JNIEnv* env) {
+ jniRegisterNativeMethods(env, "java/lang/reflect/Method", gMethods, NELEM(gMethods));
+}
+
+} // namespace art
diff --git a/src/oatexec.cc b/src/oatexec.cc
index 68c67e1..3730b43 100644
--- a/src/oatexec.cc
+++ b/src/oatexec.cc
@@ -30,7 +30,6 @@
return false;
}
static const int PUBLIC = 0x0001; // java.lang.reflect.Modifiers.PUBLIC
-#if 0 // reflect.Method.getModifiers not yet implemented
jmethodID get_modifiers = env->GetMethodID(method.get(),
"getModifiers",
"()I");
@@ -39,10 +38,6 @@
return false;
}
int modifiers = env->CallIntMethod(reflected.get(), get_modifiers);
-#else
- int modifiers = PUBLIC;
- UNIMPLEMENTED(WARNING) << "assuming main is public...";
-#endif
if ((modifiers & PUBLIC) == 0) {
return false;
}
diff --git a/src/object.cc b/src/object.cc
index 8d3a94f..157bfc9 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -611,7 +611,7 @@
if (have_executable_code && stub != NULL) {
LOG(INFO) << "invoking " << PrettyMethod(this) << " code=" << (void*) GetCode() << " stub=" << (void*) stub;
(*stub)(this, receiver, self, args, result);
- LOG(INFO) << "returning " << PrettyMethod(this) << " code=" << (void*) GetCode() << " stub=" << (void*) stub;
+ LOG(INFO) << "returned " << PrettyMethod(this) << " code=" << (void*) GetCode() << " stub=" << (void*) stub;
} else {
LOG(WARNING) << "Not invoking method with no associated code: " << PrettyMethod(this);
if (result != NULL) {
diff --git a/src/runtime.cc b/src/runtime.cc
index e0a0b20..b9120fa 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -361,9 +361,20 @@
// Finish attaching the main thread.
Thread::Current()->CreatePeer("main", false);
+ RunImageClinits();
+
StartDaemonThreads();
}
+// initialize classes that have instances in the image but that have
+// <clinit> methods so they could not be initialized by the compiler.
+void Runtime::RunImageClinits() {
+ Class* Field_class = class_linker_->FindSystemClass("Ljava/lang/reflect/Field;");
+ CHECK(Field_class->FindDeclaredDirectMethod("<clinit>", "()V") != NULL);
+ class_linker_->EnsureInitialized(Field_class);
+ CHECK(!Thread::Current()->IsExceptionPending());
+}
+
void Runtime::StartDaemonThreads() {
signal_catcher_ = new SignalCatcher;
@@ -372,8 +383,6 @@
Method* m = c->FindDirectMethod("start", "()V");
CHECK(m != NULL);
// m->Invoke(Thread::Current(), NULL, NULL, NULL);
-
- signal_catcher_->HandleSigQuit();
}
bool Runtime::IsStarted() {
@@ -458,8 +467,8 @@
//REGISTER(register_java_lang_reflect_AccessibleObject);
//REGISTER(register_java_lang_reflect_Array);
//REGISTER(register_java_lang_reflect_Constructor);
- //REGISTER(register_java_lang_reflect_Field);
- //REGISTER(register_java_lang_reflect_Method);
+ REGISTER(register_java_lang_reflect_Field);
+ REGISTER(register_java_lang_reflect_Method);
//REGISTER(register_java_lang_reflect_Proxy);
REGISTER(register_java_util_concurrent_atomic_AtomicLong);
//REGISTER(register_org_apache_harmony_dalvik_ddmc_DdmServer);
diff --git a/src/runtime.h b/src/runtime.h
index 35f8ef7..6d11cf3 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -163,6 +163,7 @@
bool Init(const Options& options, bool ignore_unrecognized);
void InitLibraries();
void RegisterRuntimeNativeMethods(JNIEnv*);
+ void RunImageClinits();
void StartDaemonThreads();
std::string boot_class_path_;