Thu, 07 Apr 2011 09:53:20 -0700
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes
1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #ifndef CPU_SPARC_VM_VM_VERSION_SPARC_HPP
26 #define CPU_SPARC_VM_VM_VERSION_SPARC_HPP
28 #include "runtime/globals_extension.hpp"
29 #include "runtime/vm_version.hpp"
31 class VM_Version: public Abstract_VM_Version {
32 protected:
33 enum Feature_Flag {
34 v8_instructions = 0,
35 hardware_mul32 = 1,
36 hardware_div32 = 2,
37 hardware_fsmuld = 3,
38 hardware_popc = 4,
39 v9_instructions = 5,
40 vis1_instructions = 6,
41 vis2_instructions = 7,
42 sun4v_instructions = 8,
43 blk_init_instructions = 9,
44 fmaf_instructions = 10,
45 fmau_instructions = 11,
46 vis3_instructions = 12,
47 sparc64_family = 13,
48 T_family = 14,
49 T1_model = 15
50 };
52 enum Feature_Flag_Set {
53 unknown_m = 0,
54 all_features_m = -1,
56 v8_instructions_m = 1 << v8_instructions,
57 hardware_mul32_m = 1 << hardware_mul32,
58 hardware_div32_m = 1 << hardware_div32,
59 hardware_fsmuld_m = 1 << hardware_fsmuld,
60 hardware_popc_m = 1 << hardware_popc,
61 v9_instructions_m = 1 << v9_instructions,
62 vis1_instructions_m = 1 << vis1_instructions,
63 vis2_instructions_m = 1 << vis2_instructions,
64 sun4v_m = 1 << sun4v_instructions,
65 blk_init_instructions_m = 1 << blk_init_instructions,
66 fmaf_instructions_m = 1 << fmaf_instructions,
67 fmau_instructions_m = 1 << fmau_instructions,
68 vis3_instructions_m = 1 << vis3_instructions,
69 sparc64_family_m = 1 << sparc64_family,
70 T_family_m = 1 << T_family,
71 T1_model_m = 1 << T1_model,
73 generic_v8_m = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
74 generic_v9_m = generic_v8_m | v9_instructions_m,
75 ultra3_m = generic_v9_m | vis1_instructions_m | vis2_instructions_m,
77 // Temporary until we have something more accurate
78 niagara1_unique_m = sun4v_m,
79 niagara1_m = generic_v9_m | niagara1_unique_m
80 };
82 static int _features;
83 static const char* _features_str;
85 static void print_features();
86 static int determine_features();
87 static int platform_features(int features);
89 // Returns true if the platform is in the niagara line (T series)
90 static bool is_T_family(int features) { return (features & T_family_m) != 0; }
91 static bool is_niagara() { return is_T_family(_features); }
92 DEBUG_ONLY( static bool is_niagara(int features) { return (features & sun4v_m) != 0; } )
94 // Returns true if it is niagara1 (T1).
95 static bool is_T1_model(int features) { return is_T_family(features) && ((features & T1_model_m) != 0); }
97 static int maximum_niagara1_processor_count() { return 32; }
99 public:
100 // Initialization
101 static void initialize();
103 // Instruction support
104 static bool has_v8() { return (_features & v8_instructions_m) != 0; }
105 static bool has_v9() { return (_features & v9_instructions_m) != 0; }
106 static bool has_hardware_mul32() { return (_features & hardware_mul32_m) != 0; }
107 static bool has_hardware_div32() { return (_features & hardware_div32_m) != 0; }
108 static bool has_hardware_fsmuld() { return (_features & hardware_fsmuld_m) != 0; }
109 static bool has_hardware_popc() { return (_features & hardware_popc_m) != 0; }
110 static bool has_vis1() { return (_features & vis1_instructions_m) != 0; }
111 static bool has_vis2() { return (_features & vis2_instructions_m) != 0; }
112 static bool has_vis3() { return (_features & vis3_instructions_m) != 0; }
113 static bool has_blk_init() { return (_features & blk_init_instructions_m) != 0; }
115 static bool supports_compare_and_exchange()
116 { return has_v9(); }
118 static bool is_ultra3() { return (_features & ultra3_m) == ultra3_m; }
119 static bool is_sun4v() { return (_features & sun4v_m) != 0; }
120 // Returns true if the platform is in the niagara line (T series)
121 // and newer than the niagara1.
122 static bool is_niagara_plus() { return is_T_family(_features) && !is_T1_model(_features); }
123 // Fujitsu SPARC64
124 static bool is_sparc64() { return (_features & sparc64_family_m) != 0; }
126 static bool has_fast_fxtof() { return is_niagara() || is_sparc64() || has_v9() && !is_ultra3(); }
127 static bool has_fast_idiv() { return is_niagara_plus() || is_sparc64(); }
129 static const char* cpu_features() { return _features_str; }
131 static intx L1_data_cache_line_size() {
132 return 64; // default prefetch block size on sparc
133 }
135 // Prefetch
136 static intx prefetch_copy_interval_in_bytes() {
137 intx interval = PrefetchCopyIntervalInBytes;
138 return interval >= 0 ? interval : (has_v9() ? 512 : 0);
139 }
140 static intx prefetch_scan_interval_in_bytes() {
141 intx interval = PrefetchScanIntervalInBytes;
142 return interval >= 0 ? interval : (has_v9() ? 512 : 0);
143 }
144 static intx prefetch_fields_ahead() {
145 intx count = PrefetchFieldsAhead;
146 return count >= 0 ? count : (is_ultra3() ? 1 : 0);
147 }
149 static intx allocate_prefetch_distance() {
150 // This method should be called before allocate_prefetch_style().
151 intx count = AllocatePrefetchDistance;
152 if (count < 0) { // default is not defined ?
153 count = 512;
154 }
155 return count;
156 }
157 static intx allocate_prefetch_style() {
158 assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive");
159 // Return 0 if AllocatePrefetchDistance was not defined.
160 return AllocatePrefetchDistance > 0 ? AllocatePrefetchStyle : 0;
161 }
163 // Legacy
164 static bool v8_instructions_work() { return has_v8() && !has_v9(); }
165 static bool v9_instructions_work() { return has_v9(); }
167 // Assembler testing
168 static void allow_all();
169 static void revert();
171 // Override the Abstract_VM_Version implementation.
172 static uint page_size_count() { return is_sun4v() ? 4 : 2; }
174 // Calculates the number of parallel threads
175 static unsigned int calc_parallel_worker_threads();
176 };
178 #endif // CPU_SPARC_VM_VM_VERSION_SPARC_HPP