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

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

Issue 16026023: Avoid Unnecessary Smi Checks (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 } 1829 }
1830 1830
1831 1831
1832 void LCodeGen::DoValueOf(LValueOf* instr) { 1832 void LCodeGen::DoValueOf(LValueOf* instr) {
1833 Register input = ToRegister(instr->value()); 1833 Register input = ToRegister(instr->value());
1834 Register result = ToRegister(instr->result()); 1834 Register result = ToRegister(instr->result());
1835 Register map = ToRegister(instr->temp()); 1835 Register map = ToRegister(instr->temp());
1836 ASSERT(input.is(result)); 1836 ASSERT(input.is(result));
1837 1837
1838 Label done; 1838 Label done;
1839 // If the object is a smi return the object. 1839
1840 __ JumpIfSmi(input, &done, Label::kNear); 1840 if (!instr->hydrogen()->value()->IsHeapObject()) {
1841 // If the object is a smi return the object.
1842 __ JumpIfSmi(input, &done, Label::kNear);
1843 }
1841 1844
1842 // If the object is not a value type, return the object. 1845 // If the object is not a value type, return the object.
1843 __ CmpObjectType(input, JS_VALUE_TYPE, map); 1846 __ CmpObjectType(input, JS_VALUE_TYPE, map);
1844 __ j(not_equal, &done, Label::kNear); 1847 __ j(not_equal, &done, Label::kNear);
1845 __ mov(result, FieldOperand(input, JSValue::kValueOffset)); 1848 __ mov(result, FieldOperand(input, JSValue::kValueOffset));
1846 1849
1847 __ bind(&done); 1850 __ bind(&done);
1848 } 1851 }
1849 1852
1850 1853
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
2383 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2386 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2384 2387
2385 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label); 2388 Condition true_cond = EmitIsObject(reg, temp, false_label, true_label);
2386 2389
2387 EmitBranch(true_block, false_block, true_cond); 2390 EmitBranch(true_block, false_block, true_cond);
2388 } 2391 }
2389 2392
2390 2393
2391 Condition LCodeGen::EmitIsString(Register input, 2394 Condition LCodeGen::EmitIsString(Register input,
2392 Register temp1, 2395 Register temp1,
2393 Label* is_not_string) { 2396 Label* is_not_string,
2394 __ JumpIfSmi(input, is_not_string); 2397 SmiCheck check_needed = INLINE_SMI_CHECK) {
2398 if (check_needed == INLINE_SMI_CHECK) {
2399 __ JumpIfSmi(input, is_not_string);
2400 }
2395 2401
2396 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 2402 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
2397 2403
2398 return cond; 2404 return cond;
2399 } 2405 }
2400 2406
2401 2407
2402 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2408 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2403 Register reg = ToRegister(instr->value()); 2409 Register reg = ToRegister(instr->value());
2404 Register temp = ToRegister(instr->temp()); 2410 Register temp = ToRegister(instr->temp());
2405 2411
2406 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2412 int true_block = chunk_->LookupDestination(instr->true_block_id());
2407 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2413 int false_block = chunk_->LookupDestination(instr->false_block_id());
2408 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2414 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2409 2415
2410 Condition true_cond = EmitIsString(reg, temp, false_label); 2416 SmiCheck check_needed =
2417 instr->hydrogen()->value()->IsHeapObject()
2418 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2419
2420 Condition true_cond = EmitIsString(reg, temp, false_label, check_needed);
2411 2421
2412 EmitBranch(true_block, false_block, true_cond); 2422 EmitBranch(true_block, false_block, true_cond);
2413 } 2423 }
2414 2424
2415 2425
2416 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2426 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2417 Operand input = ToOperand(instr->value()); 2427 Operand input = ToOperand(instr->value());
2418 2428
2419 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2429 int true_block = chunk_->LookupDestination(instr->true_block_id());
2420 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2430 int false_block = chunk_->LookupDestination(instr->false_block_id());
2421 2431
2422 __ test(input, Immediate(kSmiTagMask)); 2432 __ test(input, Immediate(kSmiTagMask));
2423 EmitBranch(true_block, false_block, zero); 2433 EmitBranch(true_block, false_block, zero);
2424 } 2434 }
2425 2435
2426 2436
2427 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2437 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2428 Register input = ToRegister(instr->value()); 2438 Register input = ToRegister(instr->value());
2429 Register temp = ToRegister(instr->temp()); 2439 Register temp = ToRegister(instr->temp());
2430 2440
2431 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2441 int true_block = chunk_->LookupDestination(instr->true_block_id());
2432 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2442 int false_block = chunk_->LookupDestination(instr->false_block_id());
2433 2443
2434 STATIC_ASSERT(kSmiTag == 0); 2444 if (!instr->hydrogen()->value()->IsHeapObject()) {
2435 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); 2445 STATIC_ASSERT(kSmiTag == 0);
2446 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
2447 }
2436 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 2448 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
2437 __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 2449 __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
2438 1 << Map::kIsUndetectable); 2450 1 << Map::kIsUndetectable);
2439 EmitBranch(true_block, false_block, not_zero); 2451 EmitBranch(true_block, false_block, not_zero);
2440 } 2452 }
2441 2453
2442 2454
2443 static Condition ComputeCompareCondition(Token::Value op) { 2455 static Condition ComputeCompareCondition(Token::Value op) {
2444 switch (op) { 2456 switch (op) {
2445 case Token::EQ_STRICT: 2457 case Token::EQ_STRICT:
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 2509
2498 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2510 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2499 Register input = ToRegister(instr->value()); 2511 Register input = ToRegister(instr->value());
2500 Register temp = ToRegister(instr->temp()); 2512 Register temp = ToRegister(instr->temp());
2501 2513
2502 int true_block = chunk_->LookupDestination(instr->true_block_id()); 2514 int true_block = chunk_->LookupDestination(instr->true_block_id());
2503 int false_block = chunk_->LookupDestination(instr->false_block_id()); 2515 int false_block = chunk_->LookupDestination(instr->false_block_id());
2504 2516
2505 Label* false_label = chunk_->GetAssemblyLabel(false_block); 2517 Label* false_label = chunk_->GetAssemblyLabel(false_block);
2506 2518
2507 __ JumpIfSmi(input, false_label); 2519 if (!instr->hydrogen()->value()->IsHeapObject()) {
2520 __ JumpIfSmi(input, false_label);
2521 }
2508 2522
2509 __ CmpObjectType(input, TestType(instr->hydrogen()), temp); 2523 __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
2510 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); 2524 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen()));
2511 } 2525 }
2512 2526
2513 2527
2514 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2528 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2515 Register input = ToRegister(instr->value()); 2529 Register input = ToRegister(instr->value());
2516 Register result = ToRegister(instr->result()); 2530 Register result = ToRegister(instr->result());
2517 2531
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
2945 __ cmp(target, factory()->the_hole_value()); 2959 __ cmp(target, factory()->the_hole_value());
2946 if (instr->hydrogen()->DeoptimizesOnHole()) { 2960 if (instr->hydrogen()->DeoptimizesOnHole()) {
2947 DeoptimizeIf(equal, instr->environment()); 2961 DeoptimizeIf(equal, instr->environment());
2948 } else { 2962 } else {
2949 __ j(not_equal, &skip_assignment, Label::kNear); 2963 __ j(not_equal, &skip_assignment, Label::kNear);
2950 } 2964 }
2951 } 2965 }
2952 2966
2953 __ mov(target, value); 2967 __ mov(target, value);
2954 if (instr->hydrogen()->NeedsWriteBarrier()) { 2968 if (instr->hydrogen()->NeedsWriteBarrier()) {
2955 HType type = instr->hydrogen()->value()->type();
2956 SmiCheck check_needed = 2969 SmiCheck check_needed =
2957 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2970 instr->hydrogen()->value()->IsHeapObject()
2971 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2958 Register temp = ToRegister(instr->temp()); 2972 Register temp = ToRegister(instr->temp());
2959 int offset = Context::SlotOffset(instr->slot_index()); 2973 int offset = Context::SlotOffset(instr->slot_index());
2960 __ RecordWriteContextSlot(context, 2974 __ RecordWriteContextSlot(context,
2961 offset, 2975 offset,
2962 value, 2976 value,
2963 temp, 2977 temp,
2964 GetSaveFPRegsMode(), 2978 GetSaveFPRegsMode(),
2965 EMIT_REMEMBERED_SET, 2979 EMIT_REMEMBERED_SET,
2966 check_needed); 2980 check_needed);
2967 } 2981 }
(...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after
4320 HeapObject::kMapOffset, 4334 HeapObject::kMapOffset,
4321 temp_map, 4335 temp_map,
4322 temp, 4336 temp,
4323 GetSaveFPRegsMode(), 4337 GetSaveFPRegsMode(),
4324 OMIT_REMEMBERED_SET, 4338 OMIT_REMEMBERED_SET,
4325 OMIT_SMI_CHECK); 4339 OMIT_SMI_CHECK);
4326 } 4340 }
4327 } 4341 }
4328 4342
4329 // Do the store. 4343 // Do the store.
4330 HType type = instr->hydrogen()->value()->type();
4331 SmiCheck check_needed = 4344 SmiCheck check_needed =
4332 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4345 instr->hydrogen()->value()->IsHeapObject()
4346 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4333 4347
4334 Register write_register = object; 4348 Register write_register = object;
4335 if (!access.IsInobject()) { 4349 if (!access.IsInobject()) {
4336 write_register = ToRegister(instr->temp()); 4350 write_register = ToRegister(instr->temp());
4337 __ mov(write_register, 4351 __ mov(write_register,
4338 FieldOperand(object, JSObject::kPropertiesOffset)); 4352 FieldOperand(object, JSObject::kPropertiesOffset));
4339 } 4353 }
4340 4354
4341 if (instr->value()->IsConstantOperand()) { 4355 if (instr->value()->IsConstantOperand()) {
4342 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4356 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4559 } else { 4573 } else {
4560 Handle<Object> handle_value = ToHandle(operand_value); 4574 Handle<Object> handle_value = ToHandle(operand_value);
4561 __ mov(operand, handle_value); 4575 __ mov(operand, handle_value);
4562 } 4576 }
4563 } 4577 }
4564 4578
4565 if (instr->hydrogen()->NeedsWriteBarrier()) { 4579 if (instr->hydrogen()->NeedsWriteBarrier()) {
4566 ASSERT(instr->value()->IsRegister()); 4580 ASSERT(instr->value()->IsRegister());
4567 Register value = ToRegister(instr->value()); 4581 Register value = ToRegister(instr->value());
4568 ASSERT(!instr->key()->IsConstantOperand()); 4582 ASSERT(!instr->key()->IsConstantOperand());
4569 HType type = instr->hydrogen()->value()->type();
4570 SmiCheck check_needed = 4583 SmiCheck check_needed =
4571 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4584 instr->hydrogen()->value()->IsHeapObject()
4585 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4572 // Compute address of modified element and store it into key register. 4586 // Compute address of modified element and store it into key register.
4573 __ lea(key, operand); 4587 __ lea(key, operand);
4574 __ RecordWrite(elements, 4588 __ RecordWrite(elements,
4575 key, 4589 key,
4576 value, 4590 value,
4577 GetSaveFPRegsMode(), 4591 GetSaveFPRegsMode(),
4578 EMIT_REMEMBERED_SET, 4592 EMIT_REMEMBERED_SET,
4579 check_needed); 4593 check_needed);
4580 } 4594 }
4581 } 4595 }
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
5702 5716
5703 5717
5704 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5718 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5705 LOperand* input = instr->value(); 5719 LOperand* input = instr->value();
5706 __ test(ToOperand(input), Immediate(kSmiTagMask)); 5720 __ test(ToOperand(input), Immediate(kSmiTagMask));
5707 DeoptimizeIf(not_zero, instr->environment()); 5721 DeoptimizeIf(not_zero, instr->environment());
5708 } 5722 }
5709 5723
5710 5724
5711 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 5725 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
5712 LOperand* input = instr->value(); 5726 if (!instr->hydrogen()->value()->IsHeapObject()) {
ulan 2013/06/20 07:53:54 This check is not present on arm and x64.
5713 __ test(ToOperand(input), Immediate(kSmiTagMask)); 5727 LOperand* input = instr->value();
5714 DeoptimizeIf(zero, instr->environment()); 5728 __ test(ToOperand(input), Immediate(kSmiTagMask));
5729 DeoptimizeIf(zero, instr->environment());
5730 }
5715 } 5731 }
5716 5732
5717 5733
5718 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 5734 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
5719 Register input = ToRegister(instr->value()); 5735 Register input = ToRegister(instr->value());
5720 Register temp = ToRegister(instr->temp()); 5736 Register temp = ToRegister(instr->temp());
5721 5737
5722 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 5738 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
5723 5739
5724 if (instr->hydrogen()->is_interval_check()) { 5740 if (instr->hydrogen()->is_interval_check()) {
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after
6504 FixedArray::kHeaderSize - kPointerSize)); 6520 FixedArray::kHeaderSize - kPointerSize));
6505 __ bind(&done); 6521 __ bind(&done);
6506 } 6522 }
6507 6523
6508 6524
6509 #undef __ 6525 #undef __
6510 6526
6511 } } // namespace v8::internal 6527 } } // namespace v8::internal
6512 6528
6513 #endif // V8_TARGET_ARCH_IA32 6529 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698