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 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1CardTable.hpp"
29 #include "gc/g1/g1BarrierSetAssembler.hpp"
30 #include "gc/g1/g1ThreadLocalData.hpp"
31 #include "gc/g1/heapRegion.hpp"
32 #include "gc/shared/collectedHeap.hpp"
33 #include "interpreter/interp_masm.hpp"
34
35 #define __ masm->
36
37 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
38 Register addr, Register count, RegSet saved_regs) {
39 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
40 if (!dest_uninitialized) {
41 __ push(saved_regs, sp);
42 if (count == c_rarg0) {
43 if (addr == c_rarg1) {
44 // exactly backwards!!
45 __ mov(rscratch1, c_rarg0);
46 __ mov(c_rarg0, c_rarg1);
47 __ mov(c_rarg1, rscratch1);
48 } else {
49 __ mov(c_rarg1, count);
50 __ mov(c_rarg0, addr);
51 }
52 } else {
164
165 __ bind(done);
166
167 }
168
169 void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
170 Register store_addr,
171 Register new_val,
172 Register thread,
173 Register tmp,
174 Register tmp2) {
175 assert(thread == rthread, "must be");
176 assert_different_registers(store_addr, new_val, thread, tmp, tmp2,
177 rscratch1);
178 assert(store_addr != noreg && new_val != noreg && tmp != noreg
179 && tmp2 != noreg, "expecting a register");
180
181 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
182 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
183
184 BarrierSet* bs = Universe::heap()->barrier_set();
185 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
186 CardTable* ct = ctbs->card_table();
187 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
188
189 Label done;
190 Label runtime;
191
192 // Does store cross heap regions?
193
194 __ eor(tmp, store_addr, new_val);
195 __ lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
196 __ cbz(tmp, done);
197
198 // crosses regions, storing NULL?
199
200 __ cbz(new_val, done);
201
202 // storing region crossing non-NULL, is card already dirty?
203
204 ExternalAddress cardtable((address) ct->byte_map_base());
|
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 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.inline.hpp"
27 #include "gc/g1/g1BarrierSet.hpp"
28 #include "gc/g1/g1BarrierSetAssembler.hpp"
29 #include "gc/g1/g1CardTable.hpp"
30 #include "gc/g1/g1ThreadLocalData.hpp"
31 #include "gc/g1/heapRegion.hpp"
32 #include "interpreter/interp_masm.hpp"
33
34 #define __ masm->
35
36 void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators,
37 Register addr, Register count, RegSet saved_regs) {
38 bool dest_uninitialized = (decorators & AS_DEST_NOT_INITIALIZED) != 0;
39 if (!dest_uninitialized) {
40 __ push(saved_regs, sp);
41 if (count == c_rarg0) {
42 if (addr == c_rarg1) {
43 // exactly backwards!!
44 __ mov(rscratch1, c_rarg0);
45 __ mov(c_rarg0, c_rarg1);
46 __ mov(c_rarg1, rscratch1);
47 } else {
48 __ mov(c_rarg1, count);
49 __ mov(c_rarg0, addr);
50 }
51 } else {
163
164 __ bind(done);
165
166 }
167
168 void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
169 Register store_addr,
170 Register new_val,
171 Register thread,
172 Register tmp,
173 Register tmp2) {
174 assert(thread == rthread, "must be");
175 assert_different_registers(store_addr, new_val, thread, tmp, tmp2,
176 rscratch1);
177 assert(store_addr != noreg && new_val != noreg && tmp != noreg
178 && tmp2 != noreg, "expecting a register");
179
180 Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
181 Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
182
183 BarrierSet* bs = BarrierSet::barrier_set();
184 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
185 CardTable* ct = ctbs->card_table();
186 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
187
188 Label done;
189 Label runtime;
190
191 // Does store cross heap regions?
192
193 __ eor(tmp, store_addr, new_val);
194 __ lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
195 __ cbz(tmp, done);
196
197 // crosses regions, storing NULL?
198
199 __ cbz(new_val, done);
200
201 // storing region crossing non-NULL, is card already dirty?
202
203 ExternalAddress cardtable((address) ct->byte_map_base());
|