Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 8256016: Eliminate write barrier for global stores at compile time if value stored is a smi. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2233 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); 2244 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
2245 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 2245 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
2246 __ cmp(scratch2, ip); 2246 __ cmp(scratch2, ip);
2247 DeoptimizeIf(eq, instr->environment()); 2247 DeoptimizeIf(eq, instr->environment());
2248 } 2248 }
2249 2249
2250 // Store the value. 2250 // Store the value.
2251 __ str(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); 2251 __ str(value, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
2252 2252
2253 // Cells are always in the remembered set. 2253 // Cells are always in the remembered set.
2254 __ RecordWriteField(scratch, 2254 if (instr->hydrogen()->NeedsWriteBarrier()) {
2255 JSGlobalPropertyCell::kValueOffset, 2255 HType type = instr->hydrogen()->value()->type();
2256 value, 2256 SmiCheck check_needed =
2257 scratch2, 2257 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2258 kLRHasBeenSaved, 2258 __ RecordWriteField(scratch,
2259 kSaveFPRegs, 2259 JSGlobalPropertyCell::kValueOffset,
2260 OMIT_REMEMBERED_SET); 2260 value,
2261 scratch2,
2262 kLRHasBeenSaved,
2263 kSaveFPRegs,
2264 OMIT_REMEMBERED_SET,
2265 check_needed);
2266 }
2261 } 2267 }
2262 2268
2263 2269
2264 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 2270 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
2265 ASSERT(ToRegister(instr->global_object()).is(r1)); 2271 ASSERT(ToRegister(instr->global_object()).is(r1));
2266 ASSERT(ToRegister(instr->value()).is(r0)); 2272 ASSERT(ToRegister(instr->value()).is(r0));
2267 2273
2268 __ mov(r2, Operand(instr->name())); 2274 __ mov(r2, Operand(instr->name()));
2269 Handle<Code> ic = instr->strict_mode() 2275 Handle<Code> ic = instr->strict_mode()
2270 ? isolate()->builtins()->StoreIC_Initialize_Strict() 2276 ? isolate()->builtins()->StoreIC_Initialize_Strict()
2271 : isolate()->builtins()->StoreIC_Initialize(); 2277 : isolate()->builtins()->StoreIC_Initialize();
2272 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); 2278 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
2273 } 2279 }
2274 2280
2275 2281
2276 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 2282 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
2277 Register context = ToRegister(instr->context()); 2283 Register context = ToRegister(instr->context());
2278 Register result = ToRegister(instr->result()); 2284 Register result = ToRegister(instr->result());
2279 __ ldr(result, ContextOperand(context, instr->slot_index())); 2285 __ ldr(result, ContextOperand(context, instr->slot_index()));
2280 } 2286 }
2281 2287
2282 2288
2283 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { 2289 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
2284 Register context = ToRegister(instr->context()); 2290 Register context = ToRegister(instr->context());
2285 Register value = ToRegister(instr->value()); 2291 Register value = ToRegister(instr->value());
2286 MemOperand target = ContextOperand(context, instr->slot_index()); 2292 MemOperand target = ContextOperand(context, instr->slot_index());
2287 __ str(value, target); 2293 __ str(value, target);
2288 if (instr->needs_write_barrier()) { 2294 if (instr->hydrogen()->NeedsWriteBarrier()) {
2295 HType type = instr->hydrogen()->value()->type();
2296 SmiCheck check_needed =
2297 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2289 __ RecordWriteContextSlot(context, 2298 __ RecordWriteContextSlot(context,
2290 target.offset(), 2299 target.offset(),
2291 value, 2300 value,
2292 scratch0(), 2301 scratch0(),
2293 kLRHasBeenSaved, 2302 kLRHasBeenSaved,
2294 kSaveFPRegs); 2303 kSaveFPRegs,
2304 EMIT_REMEMBERED_SET,
2305 check_needed);
2295 } 2306 }
2296 } 2307 }
2297 2308
2298 2309
2299 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 2310 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2300 Register object = ToRegister(instr->InputAt(0)); 2311 Register object = ToRegister(instr->InputAt(0));
2301 Register result = ToRegister(instr->result()); 2312 Register result = ToRegister(instr->result());
2302 if (instr->hydrogen()->is_in_object()) { 2313 if (instr->hydrogen()->is_in_object()) {
2303 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset())); 2314 __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset()));
2304 } else { 2315 } else {
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after
3290 int offset = instr->offset(); 3301 int offset = instr->offset();
3291 3302
3292 ASSERT(!object.is(value)); 3303 ASSERT(!object.is(value));
3293 3304
3294 if (!instr->transition().is_null()) { 3305 if (!instr->transition().is_null()) {
3295 __ mov(scratch, Operand(instr->transition())); 3306 __ mov(scratch, Operand(instr->transition()));
3296 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); 3307 __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
3297 } 3308 }
3298 3309
3299 // Do the store. 3310 // Do the store.
3311 HType type = instr->hydrogen()->value()->type();
3312 SmiCheck check_needed =
3313 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3300 if (instr->is_in_object()) { 3314 if (instr->is_in_object()) {
3301 __ str(value, FieldMemOperand(object, offset)); 3315 __ str(value, FieldMemOperand(object, offset));
3302 if (instr->needs_write_barrier()) { 3316 if (instr->hydrogen()->NeedsWriteBarrier()) {
3303 // Update the write barrier for the object for in-object properties. 3317 // Update the write barrier for the object for in-object properties.
3304 __ RecordWriteField( 3318 __ RecordWriteField(
3305 object, offset, value, scratch, kLRHasBeenSaved, kSaveFPRegs); 3319 object, offset, value, scratch, kLRHasBeenSaved, kSaveFPRegs,
Vyacheslav Egorov (Chromium) 2011/10/13 14:07:57 argument per line
3320 EMIT_REMEMBERED_SET, check_needed);
3306 } 3321 }
3307 } else { 3322 } else {
3308 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); 3323 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
3309 __ str(value, FieldMemOperand(scratch, offset)); 3324 __ str(value, FieldMemOperand(scratch, offset));
3310 if (instr->needs_write_barrier()) { 3325 if (instr->hydrogen()->NeedsWriteBarrier()) {
3311 // Update the write barrier for the properties array. 3326 // Update the write barrier for the properties array.
3312 // object is used as a scratch register. 3327 // object is used as a scratch register.
3313 __ RecordWriteField( 3328 __ RecordWriteField(
Vyacheslav Egorov (Chromium) 2011/10/13 14:07:57 argument per line
3314 scratch, offset, value, object, kLRHasBeenSaved, kSaveFPRegs); 3329 scratch, offset, value, object, kLRHasBeenSaved, kSaveFPRegs,
3330 EMIT_REMEMBERED_SET, check_needed);
3315 } 3331 }
3316 } 3332 }
3317 } 3333 }
3318 3334
3319 3335
3320 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 3336 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
3321 ASSERT(ToRegister(instr->object()).is(r1)); 3337 ASSERT(ToRegister(instr->object()).is(r1));
3322 ASSERT(ToRegister(instr->value()).is(r0)); 3338 ASSERT(ToRegister(instr->value()).is(r0));
3323 3339
3324 // Name is always in r2. 3340 // Name is always in r2.
(...skipping 30 matching lines...) Expand all
3355 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3371 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3356 int offset = 3372 int offset =
3357 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 3373 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize;
3358 __ str(value, FieldMemOperand(elements, offset)); 3374 __ str(value, FieldMemOperand(elements, offset));
3359 } else { 3375 } else {
3360 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 3376 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
3361 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 3377 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
3362 } 3378 }
3363 3379
3364 if (instr->hydrogen()->NeedsWriteBarrier()) { 3380 if (instr->hydrogen()->NeedsWriteBarrier()) {
3381 HType type = instr->hydrogen()->value()->type();
3382 SmiCheck check_needed =
3383 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3365 // Compute address of modified element and store it into key register. 3384 // Compute address of modified element and store it into key register.
3366 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3385 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3367 __ RecordWrite(elements, key, value, kLRHasBeenSaved, kSaveFPRegs); 3386 __ RecordWrite(elements, key, value, kLRHasBeenSaved, kSaveFPRegs,
Vyacheslav Egorov (Chromium) 2011/10/13 14:07:57 ditto
3387 EMIT_REMEMBERED_SET, check_needed);
3368 } 3388 }
3369 } 3389 }
3370 3390
3371 3391
3372 void LCodeGen::DoStoreKeyedFastDoubleElement( 3392 void LCodeGen::DoStoreKeyedFastDoubleElement(
3373 LStoreKeyedFastDoubleElement* instr) { 3393 LStoreKeyedFastDoubleElement* instr) {
3374 DwVfpRegister value = ToDoubleRegister(instr->value()); 3394 DwVfpRegister value = ToDoubleRegister(instr->value());
3375 Register elements = ToRegister(instr->elements()); 3395 Register elements = ToRegister(instr->elements());
3376 Register key = no_reg; 3396 Register key = no_reg;
3377 Register scratch = scratch0(); 3397 Register scratch = scratch0();
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
4342 Register input = ToRegister(instr->InputAt(0)); 4362 Register input = ToRegister(instr->InputAt(0));
4343 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4363 int true_block = chunk_->LookupDestination(instr->true_block_id());
4344 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4364 int false_block = chunk_->LookupDestination(instr->false_block_id());
4345 Label* true_label = chunk_->GetAssemblyLabel(true_block); 4365 Label* true_label = chunk_->GetAssemblyLabel(true_block);
4346 Label* false_label = chunk_->GetAssemblyLabel(false_block); 4366 Label* false_label = chunk_->GetAssemblyLabel(false_block);
4347 4367
4348 Condition final_branch_condition = EmitTypeofIs(true_label, 4368 Condition final_branch_condition = EmitTypeofIs(true_label,
4349 false_label, 4369 false_label,
4350 input, 4370 input,
4351 instr->type_literal()); 4371 instr->type_literal());
4352 4372 if (final_branch_condition != kNoCondition) {
4353 EmitBranch(true_block, false_block, final_branch_condition); 4373 EmitBranch(true_block, false_block, final_branch_condition);
4374 }
4354 } 4375 }
4355 4376
4356 4377
4357 Condition LCodeGen::EmitTypeofIs(Label* true_label, 4378 Condition LCodeGen::EmitTypeofIs(Label* true_label,
4358 Label* false_label, 4379 Label* false_label,
4359 Register input, 4380 Register input,
4360 Handle<String> type_name) { 4381 Handle<String> type_name) {
4361 Condition final_branch_condition = kNoCondition; 4382 Condition final_branch_condition = kNoCondition;
4362 Register scratch = scratch0(); 4383 Register scratch = scratch0();
4363 if (type_name->Equals(heap()->number_symbol())) { 4384 if (type_name->Equals(heap()->number_symbol())) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4413 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 4434 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
4414 __ b(lt, false_label); 4435 __ b(lt, false_label);
4415 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4436 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4416 __ b(gt, false_label); 4437 __ b(gt, false_label);
4417 // Check for undetectable objects => false. 4438 // Check for undetectable objects => false.
4418 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 4439 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
4419 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 4440 __ tst(ip, Operand(1 << Map::kIsUndetectable));
4420 final_branch_condition = eq; 4441 final_branch_condition = eq;
4421 4442
4422 } else { 4443 } else {
4423 final_branch_condition = ne;
4424 __ b(false_label); 4444 __ b(false_label);
4425 // A dead branch instruction will be generated after this point.
4426 } 4445 }
4427 4446
4428 return final_branch_condition; 4447 return final_branch_condition;
4429 } 4448 }
4430 4449
4431 4450
4432 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 4451 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
4433 Register temp1 = ToRegister(instr->TempAt(0)); 4452 Register temp1 = ToRegister(instr->TempAt(0));
4434 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4453 int true_block = chunk_->LookupDestination(instr->true_block_id());
4435 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4454 int false_block = chunk_->LookupDestination(instr->false_block_id());
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
4566 ASSERT(osr_pc_offset_ == -1); 4585 ASSERT(osr_pc_offset_ == -1);
4567 osr_pc_offset_ = masm()->pc_offset(); 4586 osr_pc_offset_ = masm()->pc_offset();
4568 } 4587 }
4569 4588
4570 4589
4571 4590
4572 4591
4573 #undef __ 4592 #undef __
4574 4593
4575 } } // namespace v8::internal 4594 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698