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

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

Issue 16026023: Avoid Unnecessary Smi Checks (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address review 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
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 __ and_(result, Immediate(Map::kElementsKindMask)); 1579 __ and_(result, Immediate(Map::kElementsKindMask));
1580 __ shr(result, Immediate(Map::kElementsKindShift)); 1580 __ shr(result, Immediate(Map::kElementsKindShift));
1581 } 1581 }
1582 1582
1583 1583
1584 void LCodeGen::DoValueOf(LValueOf* instr) { 1584 void LCodeGen::DoValueOf(LValueOf* instr) {
1585 Register input = ToRegister(instr->value()); 1585 Register input = ToRegister(instr->value());
1586 Register result = ToRegister(instr->result()); 1586 Register result = ToRegister(instr->result());
1587 ASSERT(input.is(result)); 1587 ASSERT(input.is(result));
1588 Label done; 1588 Label done;
1589 // If the object is a smi return the object. 1589
1590 __ JumpIfSmi(input, &done, Label::kNear); 1590 if (!instr->hydrogen()->value()->IsHeapObject()) {
1591 // If the object is a smi return the object.
1592 __ JumpIfSmi(input, &done, Label::kNear);
1593 }
1591 1594
1592 // If the object is not a value type, return the object. 1595 // If the object is not a value type, return the object.
1593 __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister); 1596 __ CmpObjectType(input, JS_VALUE_TYPE, kScratchRegister);
1594 __ j(not_equal, &done, Label::kNear); 1597 __ j(not_equal, &done, Label::kNear);
1595 __ movq(result, FieldOperand(input, JSValue::kValueOffset)); 1598 __ movq(result, FieldOperand(input, JSValue::kValueOffset));
1596 1599
1597 __ bind(&done); 1600 __ bind(&done);
1598 } 1601 }
1599 1602
1600 1603
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 2147
2145 Condition true_cond = EmitIsObject( 2148 Condition true_cond = EmitIsObject(
2146 reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); 2149 reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
2147 2150
2148 EmitBranch(instr, true_cond); 2151 EmitBranch(instr, true_cond);
2149 } 2152 }
2150 2153
2151 2154
2152 Condition LCodeGen::EmitIsString(Register input, 2155 Condition LCodeGen::EmitIsString(Register input,
2153 Register temp1, 2156 Register temp1,
2154 Label* is_not_string) { 2157 Label* is_not_string,
2155 __ JumpIfSmi(input, is_not_string); 2158 SmiCheck check_needed = INLINE_SMI_CHECK) {
2159 if (check_needed == INLINE_SMI_CHECK) {
2160 __ JumpIfSmi(input, is_not_string);
2161 }
2162
2156 Condition cond = masm_->IsObjectStringType(input, temp1, temp1); 2163 Condition cond = masm_->IsObjectStringType(input, temp1, temp1);
2157 2164
2158 return cond; 2165 return cond;
2159 } 2166 }
2160 2167
2161 2168
2162 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { 2169 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
2163 Register reg = ToRegister(instr->value()); 2170 Register reg = ToRegister(instr->value());
2164 Register temp = ToRegister(instr->temp()); 2171 Register temp = ToRegister(instr->temp());
2165 2172
2166 Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_)); 2173 SmiCheck check_needed =
2174 instr->hydrogen()->value()->IsHeapObject()
2175 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2176
2177 Condition true_cond = EmitIsString(
2178 reg, temp, instr->FalseLabel(chunk_), check_needed);
2167 2179
2168 EmitBranch(instr, true_cond); 2180 EmitBranch(instr, true_cond);
2169 } 2181 }
2170 2182
2171 2183
2172 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 2184 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
2173 Condition is_smi; 2185 Condition is_smi;
2174 if (instr->value()->IsRegister()) { 2186 if (instr->value()->IsRegister()) {
2175 Register input = ToRegister(instr->value()); 2187 Register input = ToRegister(instr->value());
2176 is_smi = masm()->CheckSmi(input); 2188 is_smi = masm()->CheckSmi(input);
2177 } else { 2189 } else {
2178 Operand input = ToOperand(instr->value()); 2190 Operand input = ToOperand(instr->value());
2179 is_smi = masm()->CheckSmi(input); 2191 is_smi = masm()->CheckSmi(input);
2180 } 2192 }
2181 EmitBranch(instr, is_smi); 2193 EmitBranch(instr, is_smi);
2182 } 2194 }
2183 2195
2184 2196
2185 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { 2197 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
2186 Register input = ToRegister(instr->value()); 2198 Register input = ToRegister(instr->value());
2187 Register temp = ToRegister(instr->temp()); 2199 Register temp = ToRegister(instr->temp());
2188 2200
2189 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 2201 if (!instr->hydrogen()->value()->IsHeapObject()) {
2202 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2203 }
2190 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); 2204 __ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
2191 __ testb(FieldOperand(temp, Map::kBitFieldOffset), 2205 __ testb(FieldOperand(temp, Map::kBitFieldOffset),
2192 Immediate(1 << Map::kIsUndetectable)); 2206 Immediate(1 << Map::kIsUndetectable));
2193 EmitBranch(instr, not_zero); 2207 EmitBranch(instr, not_zero);
2194 } 2208 }
2195 2209
2196 2210
2197 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { 2211 void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
2198 Token::Value op = instr->op(); 2212 Token::Value op = instr->op();
2199 2213
(...skipping 23 matching lines...) Expand all
2223 if (to == LAST_TYPE) return above_equal; 2237 if (to == LAST_TYPE) return above_equal;
2224 if (from == FIRST_TYPE) return below_equal; 2238 if (from == FIRST_TYPE) return below_equal;
2225 UNREACHABLE(); 2239 UNREACHABLE();
2226 return equal; 2240 return equal;
2227 } 2241 }
2228 2242
2229 2243
2230 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { 2244 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
2231 Register input = ToRegister(instr->value()); 2245 Register input = ToRegister(instr->value());
2232 2246
2233 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); 2247 if (!instr->hydrogen()->value()->IsHeapObject()) {
2248 __ JumpIfSmi(input, instr->FalseLabel(chunk_));
2249 }
2234 2250
2235 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); 2251 __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
2236 EmitBranch(instr, BranchCondition(instr->hydrogen())); 2252 EmitBranch(instr, BranchCondition(instr->hydrogen()));
2237 } 2253 }
2238 2254
2239 2255
2240 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { 2256 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
2241 Register input = ToRegister(instr->value()); 2257 Register input = ToRegister(instr->value());
2242 Register result = ToRegister(instr->result()); 2258 Register result = ToRegister(instr->result());
2243 2259
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
2633 __ CompareRoot(target, Heap::kTheHoleValueRootIndex); 2649 __ CompareRoot(target, Heap::kTheHoleValueRootIndex);
2634 if (instr->hydrogen()->DeoptimizesOnHole()) { 2650 if (instr->hydrogen()->DeoptimizesOnHole()) {
2635 DeoptimizeIf(equal, instr->environment()); 2651 DeoptimizeIf(equal, instr->environment());
2636 } else { 2652 } else {
2637 __ j(not_equal, &skip_assignment); 2653 __ j(not_equal, &skip_assignment);
2638 } 2654 }
2639 } 2655 }
2640 __ movq(target, value); 2656 __ movq(target, value);
2641 2657
2642 if (instr->hydrogen()->NeedsWriteBarrier()) { 2658 if (instr->hydrogen()->NeedsWriteBarrier()) {
2643 HType type = instr->hydrogen()->value()->type();
2644 SmiCheck check_needed = 2659 SmiCheck check_needed =
2645 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 2660 instr->hydrogen()->value()->IsHeapObject()
2661 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
2646 int offset = Context::SlotOffset(instr->slot_index()); 2662 int offset = Context::SlotOffset(instr->slot_index());
2647 Register scratch = ToRegister(instr->temp()); 2663 Register scratch = ToRegister(instr->temp());
2648 __ RecordWriteContextSlot(context, 2664 __ RecordWriteContextSlot(context,
2649 offset, 2665 offset,
2650 value, 2666 value,
2651 scratch, 2667 scratch,
2652 kSaveFPRegs, 2668 kSaveFPRegs,
2653 EMIT_REMEMBERED_SET, 2669 EMIT_REMEMBERED_SET,
2654 check_needed); 2670 check_needed);
2655 } 2671 }
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after
3958 HeapObject::kMapOffset, 3974 HeapObject::kMapOffset,
3959 kScratchRegister, 3975 kScratchRegister,
3960 temp, 3976 temp,
3961 kSaveFPRegs, 3977 kSaveFPRegs,
3962 OMIT_REMEMBERED_SET, 3978 OMIT_REMEMBERED_SET,
3963 OMIT_SMI_CHECK); 3979 OMIT_SMI_CHECK);
3964 } 3980 }
3965 } 3981 }
3966 3982
3967 // Do the store. 3983 // Do the store.
3968 HType type = instr->hydrogen()->value()->type();
3969 SmiCheck check_needed = 3984 SmiCheck check_needed =
3970 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3985 instr->hydrogen()->value()->IsHeapObject()
3986 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3971 3987
3972 Register write_register = object; 3988 Register write_register = object;
3973 if (!access.IsInobject()) { 3989 if (!access.IsInobject()) {
3974 write_register = ToRegister(instr->temp()); 3990 write_register = ToRegister(instr->temp());
3975 __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); 3991 __ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset));
3976 } 3992 }
3977 3993
3978 if (instr->value()->IsConstantOperand()) { 3994 if (instr->value()->IsConstantOperand()) {
3979 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 3995 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3980 if (operand_value->IsRegister()) { 3996 if (operand_value->IsRegister()) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
4199 } else { 4215 } else {
4200 Handle<Object> handle_value = ToHandle(operand_value); 4216 Handle<Object> handle_value = ToHandle(operand_value);
4201 __ Move(operand, handle_value); 4217 __ Move(operand, handle_value);
4202 } 4218 }
4203 } 4219 }
4204 4220
4205 if (instr->hydrogen()->NeedsWriteBarrier()) { 4221 if (instr->hydrogen()->NeedsWriteBarrier()) {
4206 ASSERT(instr->value()->IsRegister()); 4222 ASSERT(instr->value()->IsRegister());
4207 Register value = ToRegister(instr->value()); 4223 Register value = ToRegister(instr->value());
4208 ASSERT(!instr->key()->IsConstantOperand()); 4224 ASSERT(!instr->key()->IsConstantOperand());
4209 HType type = instr->hydrogen()->value()->type();
4210 SmiCheck check_needed = 4225 SmiCheck check_needed =
4211 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4226 instr->hydrogen()->value()->IsHeapObject()
4227 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4212 // Compute address of modified element and store it into key register. 4228 // Compute address of modified element and store it into key register.
4213 Register key_reg(ToRegister(key)); 4229 Register key_reg(ToRegister(key));
4214 __ lea(key_reg, operand); 4230 __ lea(key_reg, operand);
4215 __ RecordWrite(elements, 4231 __ RecordWrite(elements,
4216 key_reg, 4232 key_reg,
4217 value, 4233 value,
4218 kSaveFPRegs, 4234 kSaveFPRegs,
4219 EMIT_REMEMBERED_SET, 4235 EMIT_REMEMBERED_SET,
4220 check_needed); 4236 check_needed);
4221 } 4237 }
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
4867 4883
4868 4884
4869 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 4885 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
4870 LOperand* input = instr->value(); 4886 LOperand* input = instr->value();
4871 Condition cc = masm()->CheckSmi(ToRegister(input)); 4887 Condition cc = masm()->CheckSmi(ToRegister(input));
4872 DeoptimizeIf(NegateCondition(cc), instr->environment()); 4888 DeoptimizeIf(NegateCondition(cc), instr->environment());
4873 } 4889 }
4874 4890
4875 4891
4876 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { 4892 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
4877 LOperand* input = instr->value(); 4893 if (!instr->hydrogen()->value()->IsHeapObject()) {
4878 Condition cc = masm()->CheckSmi(ToRegister(input)); 4894 LOperand* input = instr->value();
4879 DeoptimizeIf(cc, instr->environment()); 4895 Condition cc = masm()->CheckSmi(ToRegister(input));
4896 DeoptimizeIf(cc, instr->environment());
4897 }
4880 } 4898 }
4881 4899
4882 4900
4883 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 4901 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
4884 Register input = ToRegister(instr->value()); 4902 Register input = ToRegister(instr->value());
4885 4903
4886 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset)); 4904 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset));
4887 4905
4888 if (instr->hydrogen()->is_interval_check()) { 4906 if (instr->hydrogen()->is_interval_check()) {
4889 InstanceType first; 4907 InstanceType first;
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
5632 FixedArray::kHeaderSize - kPointerSize)); 5650 FixedArray::kHeaderSize - kPointerSize));
5633 __ bind(&done); 5651 __ bind(&done);
5634 } 5652 }
5635 5653
5636 5654
5637 #undef __ 5655 #undef __
5638 5656
5639 } } // namespace v8::internal 5657 } } // namespace v8::internal
5640 5658
5641 #endif // V8_TARGET_ARCH_X64 5659 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698