From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19368 invoked by alias); 18 Oct 2004 22:05:15 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 19354 invoked from network); 18 Oct 2004 22:05:13 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org with SMTP; 18 Oct 2004 22:05:13 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11/8.12.10) with ESMTP id i9IM5D7p029936; Mon, 18 Oct 2004 18:05:13 -0400 Received: from pobox.toronto.redhat.com (pobox.toronto.redhat.com [172.16.14.4]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i9IM5Cr30662; Mon, 18 Oct 2004 18:05:12 -0400 Received: from [172.16.14.67] (towel.toronto.redhat.com [172.16.14.67]) by pobox.toronto.redhat.com (8.12.8/8.12.8) with ESMTP id i9IM5CbU016450; Mon, 18 Oct 2004 18:05:12 -0400 Message-ID: <41743E18.4090907@redhat.com> Date: Mon, 18 Oct 2004 22:06:00 -0000 From: Bryce McKinlay User-Agent: Mozilla Thunderbird 0.8 (X11/20040913) MIME-Version: 1.0 To: Java Patches , GCC Patches Subject: Java: [BC] Verifier fixes and new -fnew-verifier option Content-Type: multipart/mixed; boundary="------------000706090700030309040102" X-SW-Source: 2004-10/txt/msg01559.txt.bz2 This is a multi-part message in MIME format. --------------000706090700030309040102 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 431 This patch adds a new argument, -fnew-verifier, to the Java front end which enables the new verifier. It also fixes several verifier thinkos and adds some missing initialization code. I'm checking this in to the BC branch. The verifier now runs successfully for the small .class files I tried it on, but the compiler will still currently crash later on due to missing type maps that the old verifier was generating. Bryce --------------000706090700030309040102 Content-Type: text/x-patch; name="java-verifier-3.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="java-verifier-3.patch" Content-length: 9404 2004-10-15 Bryce McKinlay * expr.c (expand_bytecode): Use verify_jvm_instructions_new if flag_new_verifier is set. * java-tree.h (flag_new_verifier): Declare. * lang.opt (fnew-verifier): New option. * verify-impl.c: Work around namespace pollution by undef'ing 'current_class'. (struct verifier_context): Make 'bytecode' const. (verify_fail_pc): Pass -1 PC argument to vfy_fail. (types_compatible): For the BC-ABI, always consider reference types compatible. (check_class_constant): Use vfr->current_class. (check_constant): Likewise. (check_wide_constant): Likewise. (check_field_constant): Check for 'L' at start of type name. (get_one_type): Return pointer instead of type. Set type result in caller via passed type pointer. (compute_argument_types): Update to use new get_one_type arguments. (compute_return_type): Likewise. (make_verifier_context): New. Allocate and initialize 'vfr'. (free_verifier_context): New. Free 'vfr' and its contents. (verify_method): Remove ATTRIBUTE_UNUSED. Call make_verifier_context and free_verifier_context. Index: expr.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v retrieving revision 1.185.2.14 diff -u -r1.185.2.14 expr.c --- expr.c 12 Oct 2004 12:42:43 -0000 1.185.2.14 +++ expr.c 18 Oct 2004 21:49:41 -0000 @@ -2872,8 +2872,16 @@ } } - if (! verify_jvm_instructions (jcf, byte_ops, length)) - return; + if (flag_new_verifier) + { + if (! verify_jvm_instructions_new (jcf, byte_ops, length)) + return; + } + else + { + if (! verify_jvm_instructions (jcf, byte_ops, length)) + return; + } /* Translate bytecodes. */ linenumber_pointer = linenumber_table; Index: java-tree.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v retrieving revision 1.197.2.10 diff -u -r1.197.2.10 java-tree.h --- java-tree.h 12 Oct 2004 12:42:46 -0000 1.197.2.10 +++ java-tree.h 18 Oct 2004 21:49:41 -0000 @@ -227,6 +227,9 @@ /* When zero, don't generate runtime array store checks. */ extern int flag_store_check; +/* When nonzero, use the new bytecode verifier. */ +extern int flag_new_verifier; + /* Encoding used for source files. */ extern const char *current_encoding; Index: lang.opt =================================================================== RCS file: /cvs/gcc/gcc/gcc/java/lang.opt,v retrieving revision 1.7.2.2 diff -u -r1.7.2.2 lang.opt --- lang.opt 12 Oct 2004 12:42:51 -0000 1.7.2.2 +++ lang.opt 18 Oct 2004 21:49:41 -0000 @@ -175,5 +175,9 @@ Java Var(flag_use_divide_subroutine) Init(1) Call a library routine to do integer divisions +fnew-verifier +Java Var(flag_new_verifier) +Enable the new bytecode verifier + version Java Index: verify-impl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/java/Attic/verify-impl.c,v retrieving revision 1.1.2.5 diff -u -r1.1.2.5 verify-impl.c --- verify-impl.c 15 Oct 2004 17:23:19 -0000 1.1.2.5 +++ verify-impl.c 18 Oct 2004 21:49:42 -0000 @@ -15,6 +15,9 @@ #include "verify.h" +/* Hack to work around namespace pollution from java-tree.h. */ +#undef current_class + #ifdef VERIFY_DEBUG #include #endif /* VERIFY_DEBUG */ @@ -193,7 +196,7 @@ char *flags; /* The bytecode itself. */ - unsigned char *bytecode; + const unsigned char *bytecode; /* The exceptions. */ vfy_exception *exception; @@ -238,8 +241,6 @@ static void verify_fail_pc (const char *s, int pc) { - if (pc == -1) - pc = vfr->start_PC; vfy_fail (s, pc, vfr->current_class, vfr->current_method); } @@ -774,7 +775,13 @@ return false; } - return ref_compatible (t->klass, k->klass); + /* Reference types are always compatible for the BC-ABI. We defer this test + till runtime. + FIXME: 1. type assertion generation + 2. implement real test for old ABI ?? */ + + return true; + /* return ref_compatible (t->klass, k->klass); */ } static bool @@ -2101,7 +2108,7 @@ { type t; check_pool_index (index); - vfy_constants *pool = vfy_get_constants (current_class); + vfy_constants *pool = vfy_get_constants (vfr->current_class); if (vfy_tag (pool, index) == JV_CONSTANT_ResolvedString || vfy_tag (pool, index) == JV_CONSTANT_String) init_type_from_class (&t, vfy_string_type ()); @@ -2119,7 +2126,7 @@ { type t; check_pool_index (index); - vfy_constants *pool = vfy_get_constants (current_class); + vfy_constants *pool = vfy_get_constants (vfr->current_class); if (vfy_tag (pool, index) == JV_CONSTANT_Long) init_type_from_tag (&t, long_type); else if (vfy_tag (pool, index) == JV_CONSTANT_Double) @@ -2136,7 +2143,7 @@ vfy_string *name, vfy_string *fmtype) { check_pool_index (index); - vfy_constants *pool = vfy_get_constants (current_class); + vfy_constants *pool = vfy_get_constants (vfr->current_class); if (vfy_tag (pool, index) != expected) verify_fail_pc ("didn't see expected constant", vfr->start_PC); /* Once we know we have a Fieldref or Methodref we assume that it @@ -2169,7 +2176,7 @@ *class_type = ct; typec = vfy_string_bytes (field_type); len = vfy_string_length (field_type); - if (typec[0] == '[' || typec[len - 1] == 'L') + if (typec[0] == '[' || typec[0] == 'L') init_type_from_string (&t, field_type); else init_type_from_tag (&t, get_type_val_for_signature (typec[0])); @@ -2188,8 +2195,8 @@ method_name, method_signature); } -static type -get_one_type (const char *p) +static char * +get_one_type (char *p, type *t) { const char *start = p; @@ -2208,7 +2215,8 @@ ++p; ++p; vfy_string name = vfy_get_string (start, p - start); - return make_type_from_string (name); + *t = make_type_from_string (name); + return p; } /* Casting to jchar here is ok since we are looking at an ASCII @@ -2219,15 +2227,17 @@ { /* Callers of this function eventually push their arguments on the stack. So, promote them here. */ - type t = make_type (rt); - vfy_promote_type (&t); - return t; + type new_t = make_type (rt); + vfy_promote_type (&new_t); + *t = new_t; + return p; } vfy_jclass k = construct_primitive_array_type (rt); while (--arraycount > 0) k = vfy_get_array_class (k); - return make_type_from_class (k); + *t = make_type_from_class (k); + return p; } static void @@ -2240,17 +2250,19 @@ int i = 0; while (*p != ')') - types[i++] = get_one_type (p); + p = get_one_type (p, &types[i++]); } static type compute_return_type (vfy_string signature) { char *p = (char *) vfy_string_bytes (signature); + type t; while (*p != ')') ++p; ++p; - return get_one_type (p); + get_one_type (p, &t); + return t; } static void @@ -3335,9 +3347,17 @@ debug_print ("--------------------------------\n"); debug_print ("-- Verifying method `%s'\n", m->self->name->chars()); +} +#endif + +static void +make_verifier_context (vfy_method *m) +{ + vfr = (verifier_context *) vfy_alloc (sizeof (struct verifier_context)); + vfr->current_method = m; - bytecode = m->bytecode (); - exception = m->exceptions (); + vfr->bytecode = vfy_get_bytecode (m); + vfr->exception = vfy_get_exceptions (m); vfr->current_class = m->defining_class; vfr->states = NULL; @@ -3346,53 +3366,64 @@ vfr->isect_list = NULL; } -~_Jv_BytecodeVerifier () +static void +free_verifier_context (void) { - if (flags) - _Jv_Free (flags); + vfy_string_list *utf8_list; + ref_intersection *isect_list; + + if (vfr->flags) + vfy_free (vfr->flags); + utf8_list = vfr->utf8_list; while (utf8_list != NULL) { - linked<_Jv_Utf8Const> *n = utf8_list->next; - _Jv_Free (utf8_list); + vfy_string_list *n = utf8_list->next; + vfy_free (utf8_list); utf8_list = n; } + isect_list = vfr->isect_list; while (isect_list != NULL) { ref_intersection *next = isect_list->alloc_next; - delete isect_list; + vfy_free (isect_list); isect_list = next; } - if (vfr->states) + if (vfr->states != NULL) { - for (int i = 0; i < vfr->current_method->code_length; ++i) + int i; + for (i = 0; i < vfr->current_method->code_length; ++i) { - linked *iter = vfr->states[i]; + state_list *iter = vfr->states[i]; while (iter != NULL) { - linked *next = iter->next; - delete iter->val; + state_list *next = iter->next; + vfy_free (iter->val); vfy_free (iter); iter = next; } } - vfy_free (states); + vfy_free (vfr->states); } + + vfy_free (vfr); } -#endif - int -verify_method (vfy_method *meth ATTRIBUTE_UNUSED) +verify_method (vfy_method *meth) { - /* static verifier initialization .. init type_int etc */ + printf ("verify_method (%s) %i\n", vfy_string_bytes (meth->name), + meth->code_length); + + if (vfr != NULL) + verify_fail ("verifier re-entered"); - /* push_verifier_context () */ - /* _Jv_BytecodeVerifier v (meth); */ - /* init_verifier_context () */ + make_verifier_context (meth); verify_instructions (); - /* pop_verifier_context () */ + free_verifier_context (); + vfr = NULL; + return 0; } --------------000706090700030309040102--