4168
4169 if (use_ReduceInitialCardMarks()
4170 && g1_can_remove_post_barrier(&_gvn, oop_store, adr)) {
4171 return;
4172 }
4173
4174 if (!use_precise) {
4175 // All card marks for a (non-array) instance are in one place:
4176 adr = obj;
4177 }
4178 // (Else it's an array (or unknown), and we want more precise card marks.)
4179 assert(adr != NULL, "");
4180
4181 IdealKit ideal(this, true);
4182
4183 Node* tls = __ thread(); // ThreadLocalStorage
4184
4185 Node* no_base = __ top();
4186 float likely = PROB_LIKELY(0.999);
4187 float unlikely = PROB_UNLIKELY(0.999);
4188 Node* young_card = __ ConI((jint)G1SATBCardTableModRefBS::g1_young_card_val());
4189 Node* dirty_card = __ ConI((jint)CardTableModRefBS::dirty_card_val());
4190 Node* zeroX = __ ConX(0);
4191
4192 // Get the alias_index for raw card-mark memory
4193 const TypePtr* card_type = TypeRawPtr::BOTTOM;
4194
4195 const TypeFunc *tf = OptoRuntime::g1_wb_post_Type();
4196
4197 // Offsets into the thread
4198 const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
4199 PtrQueue::byte_offset_of_index());
4200 const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
4201 PtrQueue::byte_offset_of_buf());
4202
4203 // Pointers into the thread
4204
4205 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
4206 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
4207
4225
4226 if (val != NULL) {
4227 // Does the store cause us to cross regions?
4228
4229 // Should be able to do an unsigned compare of region_size instead of
4230 // and extra shift. Do we have an unsigned compare??
4231 // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes);
4232 Node* xor_res = __ URShiftX ( __ XorX( cast, __ CastPX(__ ctrl(), val)), __ ConI(HeapRegion::LogOfHRGrainBytes));
4233
4234 // if (xor_res == 0) same region so skip
4235 __ if_then(xor_res, BoolTest::ne, zeroX); {
4236
4237 // No barrier if we are storing a NULL
4238 __ if_then(val, BoolTest::ne, null(), unlikely); {
4239
4240 // Ok must mark the card if not already dirty
4241
4242 // load the original value of the card
4243 Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
4244
4245 __ if_then(card_val, BoolTest::ne, young_card); {
4246 sync_kit(ideal);
4247 // Use Op_MemBarVolatile to achieve the effect of a StoreLoad barrier.
4248 insert_mem_bar(Op_MemBarVolatile, oop_store);
4249 __ sync_kit(this);
4250
4251 Node* card_val_reload = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
4252 __ if_then(card_val_reload, BoolTest::ne, dirty_card); {
4253 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
4254 } __ end_if();
4255 } __ end_if();
4256 } __ end_if();
4257 } __ end_if();
4258 } else {
4259 // Object.clone() instrinsic uses this path.
4260 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
4261 }
4262
4263 // Final sync IdealKit and GraphKit.
4264 final_sync(ideal);
4265 }
4266 #undef __
4267
4268
4269
4270 Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
4271 if (java_lang_String::has_offset_field()) {
4272 int offset_offset = java_lang_String::offset_offset_in_bytes();
4273 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
4274 false, NULL, 0);
4275 const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
|
4168
4169 if (use_ReduceInitialCardMarks()
4170 && g1_can_remove_post_barrier(&_gvn, oop_store, adr)) {
4171 return;
4172 }
4173
4174 if (!use_precise) {
4175 // All card marks for a (non-array) instance are in one place:
4176 adr = obj;
4177 }
4178 // (Else it's an array (or unknown), and we want more precise card marks.)
4179 assert(adr != NULL, "");
4180
4181 IdealKit ideal(this, true);
4182
4183 Node* tls = __ thread(); // ThreadLocalStorage
4184
4185 Node* no_base = __ top();
4186 float likely = PROB_LIKELY(0.999);
4187 float unlikely = PROB_UNLIKELY(0.999);
4188 Node* clean_card = __ ConI((jint)CardTableModRefBS::clean_card_val());
4189 Node* young_card = __ ConI((jint)G1SATBCardTableModRefBS::g1_young_card_val());
4190 Node* dirty_card = __ ConI((jint)CardTableModRefBS::dirty_card_val());
4191 Node* zeroX = __ ConX(0);
4192
4193 // Get the alias_index for raw card-mark memory
4194 const TypePtr* card_type = TypeRawPtr::BOTTOM;
4195
4196 const TypeFunc *tf = OptoRuntime::g1_wb_post_Type();
4197
4198 // Offsets into the thread
4199 const int index_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
4200 PtrQueue::byte_offset_of_index());
4201 const int buffer_offset = in_bytes(JavaThread::dirty_card_queue_offset() +
4202 PtrQueue::byte_offset_of_buf());
4203
4204 // Pointers into the thread
4205
4206 Node* buffer_adr = __ AddP(no_base, tls, __ ConX(buffer_offset));
4207 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
4208
4226
4227 if (val != NULL) {
4228 // Does the store cause us to cross regions?
4229
4230 // Should be able to do an unsigned compare of region_size instead of
4231 // and extra shift. Do we have an unsigned compare??
4232 // Node* region_size = __ ConI(1 << HeapRegion::LogOfHRGrainBytes);
4233 Node* xor_res = __ URShiftX ( __ XorX( cast, __ CastPX(__ ctrl(), val)), __ ConI(HeapRegion::LogOfHRGrainBytes));
4234
4235 // if (xor_res == 0) same region so skip
4236 __ if_then(xor_res, BoolTest::ne, zeroX); {
4237
4238 // No barrier if we are storing a NULL
4239 __ if_then(val, BoolTest::ne, null(), unlikely); {
4240
4241 // Ok must mark the card if not already dirty
4242
4243 // load the original value of the card
4244 Node* card_val = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
4245
4246 if (G1ElideMembar) {
4247 __ if_then(card_val, BoolTest::eq, clean_card); {
4248 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
4249 } __ end_if();
4250 } else {
4251 __ if_then(card_val, BoolTest::ne, young_card); {
4252 sync_kit(ideal);
4253 // Use Op_MemBarVolatile to achieve the effect of a StoreLoad barrier.
4254 insert_mem_bar(Op_MemBarVolatile, oop_store);
4255 __ sync_kit(this);
4256
4257 Node* card_val_reload = __ load(__ ctrl(), card_adr, TypeInt::INT, T_BYTE, Compile::AliasIdxRaw);
4258 __ if_then(card_val_reload, BoolTest::ne, dirty_card); {
4259 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
4260 } __ end_if();
4261 } __ end_if();
4262 }
4263 } __ end_if();
4264 } __ end_if();
4265 } else {
4266 // Object.clone() instrinsic uses this path.
4267 g1_mark_card(ideal, card_adr, oop_store, alias_idx, index, index_adr, buffer, tf);
4268 }
4269
4270 // Final sync IdealKit and GraphKit.
4271 final_sync(ideal);
4272 }
4273 #undef __
4274
4275
4276
4277 Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
4278 if (java_lang_String::has_offset_field()) {
4279 int offset_offset = java_lang_String::offset_offset_in_bytes();
4280 const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
4281 false, NULL, 0);
4282 const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
|