diff options
author | Andrew Haley <aph@redhat.com> | 2006-09-01 16:50:49 +0000 |
---|---|---|
committer | Andrew Haley <aph@redhat.com> | 2006-09-01 16:50:49 +0000 |
commit | 53cad73923f715fea760022380abb07c6c9cc816 (patch) | |
tree | e491de0830a3e60ad749329b448695d646eb4fe4 /gcc/java/class.c | |
parent | 8464facb22fb4d76ca4364a28e80f89239929de0 (diff) |
2006-09-01 Andrew Haley <aph@redhat.com>
* class.c (find_tls_thunk): New function.
(build_tls_thunks): New function.
(build_tls_thunk): New function.
(make_class_data): Spurious hacks.
* parse.y (java_expand_method_bodies): Call build_tls_thunks().
* jcf-parse.c (parse_class_file): Likewise.
* java-gimplify.c (java_maybe_replace_init_expr): New function.
(java_gimplify_modify_expr): Call java_maybe_replace_init_expr.
2006-09-01 Andrew Haley <aph@redhat.com>
* Makefile.in: Rebuild.
* sources.am: Rebuild.
* java/lang/natThreadLocal.cc: New file.
* java/lang/ThreadLocal.java: Lotsa hacks.
* Makefile.am: Add java/lang/natThreadLocal.cc.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcj/gcj-tls-experimental-branch@116632 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/class.c')
-rw-r--r-- | gcc/java/class.c | 107 |
1 files changed, 101 insertions, 6 deletions
diff --git a/gcc/java/class.c b/gcc/java/class.c index cdb298e77a1..ea9bf719822 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -65,6 +65,7 @@ static int assume_compiled (const char *); static tree build_symbol_entry (tree, tree); static tree emit_assertion_table (tree); static void register_class (void); +static void build_tls_thunk (tree decl); struct obstack temporary_obstack; @@ -1616,6 +1617,96 @@ supers_all_compiled (tree type) return 1; } +tree +find_tls_thunk (tree decl) +{ + char *buf = alloca (4096); + tree id; + + sprintf (buf, "_Jv_thread_local_thunk_%s_%s", + IDENTIFIER_POINTER (DECL_NAME (decl)), + IDENTIFIER_POINTER (mangled_classname ("", DECL_CONTEXT (decl)))); + id = get_identifier (buf); + return id ? IDENTIFIER_GLOBAL_VALUE (id) : NULL_TREE; +} + +void +build_tls_thunks (tree class) +{ + tree field; + + if (targetm.have_tls) + for (field = TYPE_FIELDS (class); field != NULL_TREE; field = TREE_CHAIN (field)) + { + if (TREE_CODE (field) == VAR_DECL + && TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE + && FIELD_STATIC (field) + && ((DECL_NAME (TYPE_NAME (TREE_TYPE (TREE_TYPE (field))))) + == get_identifier ("java.lang.ThreadLocal"))) + build_tls_thunk (field); + } +} + +static void +build_tls_thunk (tree decl) +{ + tree fdecl, vdecl; + char *buf = alloca (4096); + tree stmts; + tree_stmt_iterator it; + tree ret_stmt; + tree result_decl; + tree function_identifier; + tree buf_type = make_node (RECORD_TYPE); + + { + tree id_field = build_decl (FIELD_DECL, NULL_TREE, long_type_node); + tree ptr_field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node); + TYPE_FIELDS (buf_type) = id_field; + TREE_CHAIN (id_field) = ptr_field; + layout_type (buf_type); + } + + sprintf (buf, "_Jv_thread_local_%s_%s", + IDENTIFIER_POINTER (DECL_NAME (decl)), + IDENTIFIER_POINTER (mangled_classname ("", DECL_CONTEXT (decl)))); + vdecl = build_decl (VAR_DECL, get_identifier (buf), buf_type); + DECL_TLS_MODEL (vdecl) = decl_default_tls_model (vdecl); + TREE_STATIC (vdecl) = 1; + DECL_IGNORED_P (vdecl) = 1; + DECL_ARTIFICIAL (vdecl) = 1; + rest_of_decl_compilation (vdecl, 1, 0); + + sprintf (buf, "_Jv_thread_local_thunk_%s_%s", + IDENTIFIER_POINTER (DECL_NAME (decl)), + IDENTIFIER_POINTER (mangled_classname ("", DECL_CONTEXT (decl)))); + function_identifier = get_identifier (buf); + fdecl = build_decl (FUNCTION_DECL, function_identifier, + build_function_type_list (ptr_type_node, + void_type_node, + NULL_TREE)); + IDENTIFIER_GLOBAL_VALUE (function_identifier) = fdecl; + result_decl = build_result_decl (fdecl); + + ret_stmt + = build1 (RETURN_EXPR, ptr_type_node, + (build2 (MODIFY_EXPR, ptr_type_node, + result_decl, + fold_convert (ptr_type_node, + build_address_of (vdecl))))); + + stmts = make_node (STATEMENT_LIST); + it = tsi_last (stmts); + tsi_link_after (&it, ret_stmt, TSI_CONTINUE_LINKING); + TREE_TYPE (stmts) = void_type_node; + + DECL_SAVED_TREE (fdecl) = stmts; + DECL_INITIAL (fdecl) = make_node (BLOCK); + + java_genericize (fdecl); + cgraph_finalize_function (fdecl, false); +} + void make_class_data (tree type) { @@ -1646,6 +1737,7 @@ make_class_data (tree type) to where objects actually point at, following new g++ ABI. */ tree dtable_start_offset = build_int_cst (NULL_TREE, 2 * POINTER_SIZE / BITS_PER_UNIT); + tree first_field; this_class_addr = build_static_class_ref (type); decl = TREE_OPERAND (this_class_addr, 0); @@ -1667,13 +1759,16 @@ make_class_data (tree type) class_dtable_decl = dtable_decl; } + /* Find the first real field. */ + first_field = TYPE_FIELDS (type); + while (first_field && DECL_ARTIFICIAL (first_field)) + first_field = TREE_CHAIN (first_field); /* Skip dummy fields. */ + if (first_field && DECL_NAME (first_field) == NULL_TREE) + first_field = TREE_CHAIN (first_field); /* Skip dummy field + for inherited data. */ + /* Build Field array. */ - field = TYPE_FIELDS (type); - while (field && DECL_ARTIFICIAL (field)) - field = TREE_CHAIN (field); /* Skip dummy fields. */ - if (field && DECL_NAME (field) == NULL_TREE) - field = TREE_CHAIN (field); /* Skip dummy field for inherited data. */ - for ( ; field != NULL_TREE; field = TREE_CHAIN (field)) + for (field = first_field; field != NULL_TREE; field = TREE_CHAIN (field)) { if (! DECL_ARTIFICIAL (field)) { |