comparison src/share/vm/prims/unsafe.cpp @ 431:a45484ea312d

6653858: dynamic languages need to be able to load anonymous classes Summary: low-level privileged sun.misc.Unsafe.defineAnonymousClass Reviewed-by: kvn
author jrose
date Wed, 12 Nov 2008 22:33:26 -0800
parents 1ee8caae33af
children df6caf649ff7
comparison
equal deleted inserted replaced
430:4d20a3aaf1ab 431:a45484ea312d
835 835
836 return Unsafe_DefineClass(env, name, data, offset, length, loader, pd); 836 return Unsafe_DefineClass(env, name, data, offset, length, loader, pd);
837 } 837 }
838 UNSAFE_END 838 UNSAFE_END
839 839
840 #define DAC_Args CLS"[B["OBJ
841 // define a class but do not make it known to the class loader or system dictionary
842 // - host_class: supplies context for linkage, access control, protection domain, and class loader
843 // - data: bytes of a class file, a raw memory address (length gives the number of bytes)
844 // - cp_patches: where non-null entries exist, they replace corresponding CP entries in data
845
846 // When you load an anonymous class U, it works as if you changed its name just before loading,
847 // to a name that you will never use again. Since the name is lost, no other class can directly
848 // link to any member of U. Just after U is loaded, the only way to use it is reflectively,
849 // through java.lang.Class methods like Class.newInstance.
850
851 // Access checks for linkage sites within U continue to follow the same rules as for named classes.
852 // The package of an anonymous class is given by the package qualifier on the name under which it was loaded.
853 // An anonymous class also has special privileges to access any member of its host class.
854 // This is the main reason why this loading operation is unsafe. The purpose of this is to
855 // allow language implementations to simulate "open classes"; a host class in effect gets
856 // new code when an anonymous class is loaded alongside it. A less convenient but more
857 // standard way to do this is with reflection, which can also be set to ignore access
858 // restrictions.
859
860 // Access into an anonymous class is possible only through reflection. Therefore, there
861 // are no special access rules for calling into an anonymous class. The relaxed access
862 // rule for the host class is applied in the opposite direction: A host class reflectively
863 // access one of its anonymous classes.
864
865 // If you load the same bytecodes twice, you get two different classes. You can reload
866 // the same bytecodes with or without varying CP patches.
867
868 // By using the CP patching array, you can have a new anonymous class U2 refer to an older one U1.
869 // The bytecodes for U2 should refer to U1 by a symbolic name (doesn't matter what the name is).
870 // The CONSTANT_Class entry for that name can be patched to refer directly to U1.
871
872 // This allows, for example, U2 to use U1 as a superclass or super-interface, or as
873 // an outer class (so that U2 is an anonymous inner class of anonymous U1).
874 // It is not possible for a named class, or an older anonymous class, to refer by
875 // name (via its CP) to a newer anonymous class.
876
877 // CP patching may also be used to modify (i.e., hack) the names of methods, classes,
878 // or type descriptors used in the loaded anonymous class.
879
880 // Finally, CP patching may be used to introduce "live" objects into the constant pool,
881 // instead of "dead" strings. A compiled statement like println((Object)"hello") can
882 // be changed to println(greeting), where greeting is an arbitrary object created before
883 // the anonymous class is loaded. This is useful in dynamic languages, in which
884 // various kinds of metaobjects must be introduced as constants into bytecode.
885 // Note the cast (Object), which tells the verifier to expect an arbitrary object,
886 // not just a literal string. For such ldc instructions, the verifier uses the
887 // type Object instead of String, if the loaded constant is not in fact a String.
888
889 static oop
890 Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
891 jclass host_class, jbyteArray data, jobjectArray cp_patches_jh,
892 HeapWord* *temp_alloc,
893 TRAPS) {
894
895 if (UsePerfData) {
896 ClassLoader::unsafe_defineClassCallCounter()->inc();
897 }
898
899 if (data == NULL) {
900 THROW_0(vmSymbols::java_lang_NullPointerException());
901 }
902
903 jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length();
904 jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord);
905 HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length);
906 if (body == NULL) {
907 THROW_0(vmSymbols::java_lang_OutOfMemoryError());
908 }
909
910 // caller responsible to free it:
911 (*temp_alloc) = body;
912
913 {
914 jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0);
915 Copy::conjoint_words((HeapWord*) array_base, body, word_length);
916 }
917
918 u1* class_bytes = (u1*) body;
919 int class_bytes_length = (int) length;
920 if (class_bytes_length < 0) class_bytes_length = 0;
921 if (class_bytes == NULL
922 || host_class == NULL
923 || length != class_bytes_length)
924 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
925
926 objArrayHandle cp_patches_h;
927 if (cp_patches_jh != NULL) {
928 oop p = JNIHandles::resolve_non_null(cp_patches_jh);
929 if (!p->is_objArray())
930 THROW_0(vmSymbols::java_lang_IllegalArgumentException());
931 cp_patches_h = objArrayHandle(THREAD, (objArrayOop)p);
932 }
933
934 KlassHandle host_klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(host_class)));
935 const char* host_source = host_klass->external_name();
936 Handle host_loader(THREAD, host_klass->class_loader());
937 Handle host_domain(THREAD, host_klass->protection_domain());
938
939 GrowableArray<Handle>* cp_patches = NULL;
940 if (cp_patches_h.not_null()) {
941 int alen = cp_patches_h->length();
942 for (int i = alen-1; i >= 0; i--) {
943 oop p = cp_patches_h->obj_at(i);
944 if (p != NULL) {
945 Handle patch(THREAD, p);
946 if (cp_patches == NULL)
947 cp_patches = new GrowableArray<Handle>(i+1, i+1, Handle());
948 cp_patches->at_put(i, patch);
949 }
950 }
951 }
952
953 ClassFileStream st(class_bytes, class_bytes_length, (char*) host_source);
954
955 instanceKlassHandle anon_klass;
956 {
957 symbolHandle no_class_name;
958 klassOop anonk = SystemDictionary::parse_stream(no_class_name,
959 host_loader, host_domain,
960 &st, host_klass, cp_patches,
961 CHECK_NULL);
962 if (anonk == NULL) return NULL;
963 anon_klass = instanceKlassHandle(THREAD, anonk);
964 }
965
966 // let caller initialize it as needed...
967
968 return anon_klass->java_mirror();
969 }
970
971 UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass(JNIEnv *env, jobject unsafe, jclass host_class, jbyteArray data, jobjectArray cp_patches_jh))
972 {
973 UnsafeWrapper("Unsafe_DefineAnonymousClass");
974 ResourceMark rm(THREAD);
975
976 HeapWord* temp_alloc = NULL;
977
978 jobject res_jh = NULL;
979
980 { oop res_oop = Unsafe_DefineAnonymousClass_impl(env,
981 host_class, data, cp_patches_jh,
982 &temp_alloc, THREAD);
983 if (res_oop != NULL)
984 res_jh = JNIHandles::make_local(env, res_oop);
985 }
986
987 // try/finally clause:
988 if (temp_alloc != NULL) {
989 FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
990 }
991
992 return (jclass) res_jh;
993 }
994 UNSAFE_END
995
996
840 997
841 UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj)) 998 UNSAFE_ENTRY(void, Unsafe_MonitorEnter(JNIEnv *env, jobject unsafe, jobject jobj))
842 UnsafeWrapper("Unsafe_MonitorEnter"); 999 UnsafeWrapper("Unsafe_MonitorEnter");
843 { 1000 {
844 if (jobj == NULL) { 1001 if (jobj == NULL) {
1290 JNINativeMethod memcopy_methods_15[] = { 1447 JNINativeMethod memcopy_methods_15[] = {
1291 {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)}, 1448 {CC"setMemory", CC"("ADR"JB)V", FN_PTR(Unsafe_SetMemory)},
1292 {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)} 1449 {CC"copyMemory", CC"("ADR ADR"J)V", FN_PTR(Unsafe_CopyMemory)}
1293 }; 1450 };
1294 1451
1452 JNINativeMethod anonk_methods[] = {
1453 {CC"defineAnonymousClass", CC"("DAC_Args")"CLS, FN_PTR(Unsafe_DefineAnonymousClass)},
1454 };
1295 1455
1296 #undef CC 1456 #undef CC
1297 #undef FN_PTR 1457 #undef FN_PTR
1298 1458
1299 #undef ADR 1459 #undef ADR
1352 } 1512 }
1353 env->ExceptionClear(); 1513 env->ExceptionClear();
1354 } 1514 }
1355 } 1515 }
1356 } 1516 }
1517 if (AnonymousClasses) {
1518 env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
1519 if (env->ExceptionOccurred()) {
1520 if (PrintMiscellaneous && (Verbose || WizardMode)) {
1521 tty->print_cr("Warning: SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
1522 }
1523 env->ExceptionClear();
1524 }
1525 }
1357 int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod)); 1526 int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
1358 if (env->ExceptionOccurred()) { 1527 if (env->ExceptionOccurred()) {
1359 if (PrintMiscellaneous && (Verbose || WizardMode)) { 1528 if (PrintMiscellaneous && (Verbose || WizardMode)) {
1360 tty->print_cr("Warning: SDK 1.6 version of Unsafe not found."); 1529 tty->print_cr("Warning: SDK 1.6 version of Unsafe not found.");
1361 } 1530 }