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

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
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(object,
3305 object, offset, value, scratch, kLRHasBeenSaved, kSaveFPRegs); 3319 offset,
3320 value,
3321 scratch,
3322 kLRHasBeenSaved,
3323 kSaveFPRegs,
3324 EMIT_REMEMBERED_SET,
3325 check_needed);
3306 } 3326 }
3307 } else { 3327 } else {
3308 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); 3328 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
3309 __ str(value, FieldMemOperand(scratch, offset)); 3329 __ str(value, FieldMemOperand(scratch, offset));
3310 if (instr->needs_write_barrier()) { 3330 if (instr->hydrogen()->NeedsWriteBarrier()) {
3311 // Update the write barrier for the properties array. 3331 // Update the write barrier for the properties array.
3312 // object is used as a scratch register. 3332 // object is used as a scratch register.
3313 __ RecordWriteField( 3333 __ RecordWriteField(scratch,
3314 scratch, offset, value, object, kLRHasBeenSaved, kSaveFPRegs); 3334 offset,
3335 value,
3336 object,
3337 kLRHasBeenSaved,
3338 kSaveFPRegs,
3339 EMIT_REMEMBERED_SET,
3340 check_needed);
3315 } 3341 }
3316 } 3342 }
3317 } 3343 }
3318 3344
3319 3345
3320 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 3346 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
3321 ASSERT(ToRegister(instr->object()).is(r1)); 3347 ASSERT(ToRegister(instr->object()).is(r1));
3322 ASSERT(ToRegister(instr->value()).is(r0)); 3348 ASSERT(ToRegister(instr->value()).is(r0));
3323 3349
3324 // Name is always in r2. 3350 // Name is always in r2.
(...skipping 30 matching lines...) Expand all
3355 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3381 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3356 int offset = 3382 int offset =
3357 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 3383 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize;
3358 __ str(value, FieldMemOperand(elements, offset)); 3384 __ str(value, FieldMemOperand(elements, offset));
3359 } else { 3385 } else {
3360 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 3386 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
3361 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 3387 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
3362 } 3388 }
3363 3389
3364 if (instr->hydrogen()->NeedsWriteBarrier()) { 3390 if (instr->hydrogen()->NeedsWriteBarrier()) {
3391 HType type = instr->hydrogen()->value()->type();
3392 SmiCheck check_needed =
3393 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3365 // Compute address of modified element and store it into key register. 3394 // Compute address of modified element and store it into key register.
3366 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3395 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3367 __ RecordWrite(elements, key, value, kLRHasBeenSaved, kSaveFPRegs); 3396 __ RecordWrite(elements,
3397 key,
3398 value,
3399 kLRHasBeenSaved,
3400 kSaveFPRegs,
3401 EMIT_REMEMBERED_SET,
3402 check_needed);
3368 } 3403 }
3369 } 3404 }
3370 3405
3371 3406
3372 void LCodeGen::DoStoreKeyedFastDoubleElement( 3407 void LCodeGen::DoStoreKeyedFastDoubleElement(
3373 LStoreKeyedFastDoubleElement* instr) { 3408 LStoreKeyedFastDoubleElement* instr) {
3374 DwVfpRegister value = ToDoubleRegister(instr->value()); 3409 DwVfpRegister value = ToDoubleRegister(instr->value());
3375 Register elements = ToRegister(instr->elements()); 3410 Register elements = ToRegister(instr->elements());
3376 Register key = no_reg; 3411 Register key = no_reg;
3377 Register scratch = scratch0(); 3412 Register scratch = scratch0();
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
4342 Register input = ToRegister(instr->InputAt(0)); 4377 Register input = ToRegister(instr->InputAt(0));
4343 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4378 int true_block = chunk_->LookupDestination(instr->true_block_id());
4344 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4379 int false_block = chunk_->LookupDestination(instr->false_block_id());
4345 Label* true_label = chunk_->GetAssemblyLabel(true_block); 4380 Label* true_label = chunk_->GetAssemblyLabel(true_block);
4346 Label* false_label = chunk_->GetAssemblyLabel(false_block); 4381 Label* false_label = chunk_->GetAssemblyLabel(false_block);
4347 4382
4348 Condition final_branch_condition = EmitTypeofIs(true_label, 4383 Condition final_branch_condition = EmitTypeofIs(true_label,
4349 false_label, 4384 false_label,
4350 input, 4385 input,
4351 instr->type_literal()); 4386 instr->type_literal());
4352 4387 if (final_branch_condition != kNoCondition) {
4353 EmitBranch(true_block, false_block, final_branch_condition); 4388 EmitBranch(true_block, false_block, final_branch_condition);
4389 }
4354 } 4390 }
4355 4391
4356 4392
4357 Condition LCodeGen::EmitTypeofIs(Label* true_label, 4393 Condition LCodeGen::EmitTypeofIs(Label* true_label,
4358 Label* false_label, 4394 Label* false_label,
4359 Register input, 4395 Register input,
4360 Handle<String> type_name) { 4396 Handle<String> type_name) {
4361 Condition final_branch_condition = kNoCondition; 4397 Condition final_branch_condition = kNoCondition;
4362 Register scratch = scratch0(); 4398 Register scratch = scratch0();
4363 if (type_name->Equals(heap()->number_symbol())) { 4399 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); 4449 FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
4414 __ b(lt, false_label); 4450 __ b(lt, false_label);
4415 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4451 __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4416 __ b(gt, false_label); 4452 __ b(gt, false_label);
4417 // Check for undetectable objects => false. 4453 // Check for undetectable objects => false.
4418 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset)); 4454 __ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
4419 __ tst(ip, Operand(1 << Map::kIsUndetectable)); 4455 __ tst(ip, Operand(1 << Map::kIsUndetectable));
4420 final_branch_condition = eq; 4456 final_branch_condition = eq;
4421 4457
4422 } else { 4458 } else {
4423 final_branch_condition = ne;
4424 __ b(false_label); 4459 __ b(false_label);
4425 // A dead branch instruction will be generated after this point.
4426 } 4460 }
4427 4461
4428 return final_branch_condition; 4462 return final_branch_condition;
4429 } 4463 }
4430 4464
4431 4465
4432 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 4466 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
4433 Register temp1 = ToRegister(instr->TempAt(0)); 4467 Register temp1 = ToRegister(instr->TempAt(0));
4434 int true_block = chunk_->LookupDestination(instr->true_block_id()); 4468 int true_block = chunk_->LookupDestination(instr->true_block_id());
4435 int false_block = chunk_->LookupDestination(instr->false_block_id()); 4469 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); 4600 ASSERT(osr_pc_offset_ == -1);
4567 osr_pc_offset_ = masm()->pc_offset(); 4601 osr_pc_offset_ = masm()->pc_offset();
4568 } 4602 }
4569 4603
4570 4604
4571 4605
4572 4606
4573 #undef __ 4607 #undef __
4574 4608
4575 } } // namespace v8::internal 4609 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698