OLD | NEW |
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 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); | 1702 __ Ext(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); |
1703 } | 1703 } |
1704 | 1704 |
1705 | 1705 |
1706 void LCodeGen::DoValueOf(LValueOf* instr) { | 1706 void LCodeGen::DoValueOf(LValueOf* instr) { |
1707 Register input = ToRegister(instr->value()); | 1707 Register input = ToRegister(instr->value()); |
1708 Register result = ToRegister(instr->result()); | 1708 Register result = ToRegister(instr->result()); |
1709 Register map = ToRegister(instr->temp()); | 1709 Register map = ToRegister(instr->temp()); |
1710 Label done; | 1710 Label done; |
1711 | 1711 |
1712 // If the object is a smi return the object. | 1712 if (!instr->hydrogen()->value()->IsHeapObject()) { |
1713 __ Move(result, input); | 1713 // If the object is a smi return the object. |
1714 __ JumpIfSmi(input, &done); | 1714 __ Move(result, input); |
| 1715 __ JumpIfSmi(input, &done); |
| 1716 } |
1715 | 1717 |
1716 // If the object is not a value type, return the object. | 1718 // If the object is not a value type, return the object. |
1717 __ GetObjectType(input, map, map); | 1719 __ GetObjectType(input, map, map); |
1718 __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE)); | 1720 __ Branch(&done, ne, map, Operand(JS_VALUE_TYPE)); |
1719 __ lw(result, FieldMemOperand(input, JSValue::kValueOffset)); | 1721 __ lw(result, FieldMemOperand(input, JSValue::kValueOffset)); |
1720 | 1722 |
1721 __ bind(&done); | 1723 __ bind(&done); |
1722 } | 1724 } |
1723 | 1725 |
1724 | 1726 |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2298 EmitIsObject(reg, temp1, temp2, | 2300 EmitIsObject(reg, temp1, temp2, |
2299 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); | 2301 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); |
2300 | 2302 |
2301 EmitBranch(instr, true_cond, temp2, | 2303 EmitBranch(instr, true_cond, temp2, |
2302 Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2304 Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
2303 } | 2305 } |
2304 | 2306 |
2305 | 2307 |
2306 Condition LCodeGen::EmitIsString(Register input, | 2308 Condition LCodeGen::EmitIsString(Register input, |
2307 Register temp1, | 2309 Register temp1, |
2308 Label* is_not_string) { | 2310 Label* is_not_string, |
2309 __ JumpIfSmi(input, is_not_string); | 2311 SmiCheck check_needed = INLINE_SMI_CHECK) { |
| 2312 if (check_needed == INLINE_SMI_CHECK) { |
| 2313 __ JumpIfSmi(input, is_not_string); |
| 2314 } |
2310 __ GetObjectType(input, temp1, temp1); | 2315 __ GetObjectType(input, temp1, temp1); |
2311 | 2316 |
2312 return lt; | 2317 return lt; |
2313 } | 2318 } |
2314 | 2319 |
2315 | 2320 |
2316 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { | 2321 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { |
2317 Register reg = ToRegister(instr->value()); | 2322 Register reg = ToRegister(instr->value()); |
2318 Register temp1 = ToRegister(instr->temp()); | 2323 Register temp1 = ToRegister(instr->temp()); |
2319 | 2324 |
| 2325 SmiCheck check_needed = |
| 2326 instr->hydrogen()->value()->IsHeapObject() |
| 2327 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
2320 Condition true_cond = | 2328 Condition true_cond = |
2321 EmitIsString(reg, temp1, instr->FalseLabel(chunk_)); | 2329 EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed); |
2322 | 2330 |
2323 EmitBranch(instr, true_cond, temp1, | 2331 EmitBranch(instr, true_cond, temp1, |
2324 Operand(FIRST_NONSTRING_TYPE)); | 2332 Operand(FIRST_NONSTRING_TYPE)); |
2325 } | 2333 } |
2326 | 2334 |
2327 | 2335 |
2328 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 2336 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
2329 Register input_reg = EmitLoadRegister(instr->value(), at); | 2337 Register input_reg = EmitLoadRegister(instr->value(), at); |
2330 __ And(at, input_reg, kSmiTagMask); | 2338 __ And(at, input_reg, kSmiTagMask); |
2331 EmitBranch(instr, eq, at, Operand(zero_reg)); | 2339 EmitBranch(instr, eq, at, Operand(zero_reg)); |
2332 } | 2340 } |
2333 | 2341 |
2334 | 2342 |
2335 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { | 2343 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { |
2336 Register input = ToRegister(instr->value()); | 2344 Register input = ToRegister(instr->value()); |
2337 Register temp = ToRegister(instr->temp()); | 2345 Register temp = ToRegister(instr->temp()); |
2338 | 2346 |
2339 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); | 2347 if (!instr->hydrogen()->value()->IsHeapObject()) { |
| 2348 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); |
| 2349 } |
2340 __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset)); | 2350 __ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
2341 __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); | 2351 __ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); |
2342 __ And(at, temp, Operand(1 << Map::kIsUndetectable)); | 2352 __ And(at, temp, Operand(1 << Map::kIsUndetectable)); |
2343 EmitBranch(instr, ne, at, Operand(zero_reg)); | 2353 EmitBranch(instr, ne, at, Operand(zero_reg)); |
2344 } | 2354 } |
2345 | 2355 |
2346 | 2356 |
2347 static Condition ComputeCompareCondition(Token::Value op) { | 2357 static Condition ComputeCompareCondition(Token::Value op) { |
2348 switch (op) { | 2358 switch (op) { |
2349 case Token::EQ_STRICT: | 2359 case Token::EQ_STRICT: |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2393 if (from == FIRST_TYPE) return ls; | 2403 if (from == FIRST_TYPE) return ls; |
2394 UNREACHABLE(); | 2404 UNREACHABLE(); |
2395 return eq; | 2405 return eq; |
2396 } | 2406 } |
2397 | 2407 |
2398 | 2408 |
2399 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 2409 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
2400 Register scratch = scratch0(); | 2410 Register scratch = scratch0(); |
2401 Register input = ToRegister(instr->value()); | 2411 Register input = ToRegister(instr->value()); |
2402 | 2412 |
2403 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); | 2413 if (!instr->hydrogen()->value()->IsHeapObject()) { |
| 2414 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); |
| 2415 } |
2404 | 2416 |
2405 __ GetObjectType(input, scratch, scratch); | 2417 __ GetObjectType(input, scratch, scratch); |
2406 EmitBranch(instr, | 2418 EmitBranch(instr, |
2407 BranchCondition(instr->hydrogen()), | 2419 BranchCondition(instr->hydrogen()), |
2408 scratch, | 2420 scratch, |
2409 Operand(TestType(instr->hydrogen()))); | 2421 Operand(TestType(instr->hydrogen()))); |
2410 } | 2422 } |
2411 | 2423 |
2412 | 2424 |
2413 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { | 2425 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2830 | 2842 |
2831 if (instr->hydrogen()->DeoptimizesOnHole()) { | 2843 if (instr->hydrogen()->DeoptimizesOnHole()) { |
2832 DeoptimizeIf(eq, instr->environment(), scratch, Operand(at)); | 2844 DeoptimizeIf(eq, instr->environment(), scratch, Operand(at)); |
2833 } else { | 2845 } else { |
2834 __ Branch(&skip_assignment, ne, scratch, Operand(at)); | 2846 __ Branch(&skip_assignment, ne, scratch, Operand(at)); |
2835 } | 2847 } |
2836 } | 2848 } |
2837 | 2849 |
2838 __ sw(value, target); | 2850 __ sw(value, target); |
2839 if (instr->hydrogen()->NeedsWriteBarrier()) { | 2851 if (instr->hydrogen()->NeedsWriteBarrier()) { |
2840 HType type = instr->hydrogen()->value()->type(); | |
2841 SmiCheck check_needed = | 2852 SmiCheck check_needed = |
2842 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 2853 instr->hydrogen()->value()->IsHeapObject() |
| 2854 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
2843 __ RecordWriteContextSlot(context, | 2855 __ RecordWriteContextSlot(context, |
2844 target.offset(), | 2856 target.offset(), |
2845 value, | 2857 value, |
2846 scratch0(), | 2858 scratch0(), |
2847 GetRAState(), | 2859 GetRAState(), |
2848 kSaveFPRegs, | 2860 kSaveFPRegs, |
2849 EMIT_REMEMBERED_SET, | 2861 EMIT_REMEMBERED_SET, |
2850 check_needed); | 2862 check_needed); |
2851 } | 2863 } |
2852 | 2864 |
(...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4120 GetRAState(), | 4132 GetRAState(), |
4121 kSaveFPRegs, | 4133 kSaveFPRegs, |
4122 OMIT_REMEMBERED_SET, | 4134 OMIT_REMEMBERED_SET, |
4123 OMIT_SMI_CHECK); | 4135 OMIT_SMI_CHECK); |
4124 } | 4136 } |
4125 } | 4137 } |
4126 | 4138 |
4127 // Do the store. | 4139 // Do the store. |
4128 Register value = ToRegister(instr->value()); | 4140 Register value = ToRegister(instr->value()); |
4129 ASSERT(!object.is(value)); | 4141 ASSERT(!object.is(value)); |
4130 HType type = instr->hydrogen()->value()->type(); | |
4131 SmiCheck check_needed = | 4142 SmiCheck check_needed = |
4132 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4143 instr->hydrogen()->value()->IsHeapObject() |
| 4144 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4133 if (access.IsInobject()) { | 4145 if (access.IsInobject()) { |
4134 __ sw(value, FieldMemOperand(object, offset)); | 4146 __ sw(value, FieldMemOperand(object, offset)); |
4135 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4147 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4136 // Update the write barrier for the object for in-object properties. | 4148 // Update the write barrier for the object for in-object properties. |
4137 __ RecordWriteField(object, | 4149 __ RecordWriteField(object, |
4138 offset, | 4150 offset, |
4139 value, | 4151 value, |
4140 scratch, | 4152 scratch, |
4141 GetRAState(), | 4153 GetRAState(), |
4142 kSaveFPRegs, | 4154 kSaveFPRegs, |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4347 __ addu(scratch, elements, scratch); | 4359 __ addu(scratch, elements, scratch); |
4348 } else { | 4360 } else { |
4349 __ sll(scratch, key, kPointerSizeLog2); | 4361 __ sll(scratch, key, kPointerSizeLog2); |
4350 __ addu(scratch, elements, scratch); | 4362 __ addu(scratch, elements, scratch); |
4351 } | 4363 } |
4352 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | 4364 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); |
4353 } | 4365 } |
4354 __ sw(value, FieldMemOperand(store_base, offset)); | 4366 __ sw(value, FieldMemOperand(store_base, offset)); |
4355 | 4367 |
4356 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4368 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4357 HType type = instr->hydrogen()->value()->type(); | |
4358 SmiCheck check_needed = | 4369 SmiCheck check_needed = |
4359 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4370 instr->hydrogen()->value()->IsHeapObject() |
| 4371 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4360 // Compute address of modified element and store it into key register. | 4372 // Compute address of modified element and store it into key register. |
4361 __ Addu(key, store_base, Operand(offset - kHeapObjectTag)); | 4373 __ Addu(key, store_base, Operand(offset - kHeapObjectTag)); |
4362 __ RecordWrite(elements, | 4374 __ RecordWrite(elements, |
4363 key, | 4375 key, |
4364 value, | 4376 value, |
4365 GetRAState(), | 4377 GetRAState(), |
4366 kSaveFPRegs, | 4378 kSaveFPRegs, |
4367 EMIT_REMEMBERED_SET, | 4379 EMIT_REMEMBERED_SET, |
4368 check_needed); | 4380 check_needed); |
4369 } | 4381 } |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5100 | 5112 |
5101 | 5113 |
5102 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 5114 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
5103 LOperand* input = instr->value(); | 5115 LOperand* input = instr->value(); |
5104 __ And(at, ToRegister(input), Operand(kSmiTagMask)); | 5116 __ And(at, ToRegister(input), Operand(kSmiTagMask)); |
5105 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); | 5117 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); |
5106 } | 5118 } |
5107 | 5119 |
5108 | 5120 |
5109 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 5121 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
5110 LOperand* input = instr->value(); | 5122 if (!instr->hydrogen()->value()->IsHeapObject()) { |
5111 __ And(at, ToRegister(input), Operand(kSmiTagMask)); | 5123 LOperand* input = instr->value(); |
5112 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); | 5124 __ And(at, ToRegister(input), Operand(kSmiTagMask)); |
| 5125 DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg)); |
| 5126 } |
5113 } | 5127 } |
5114 | 5128 |
5115 | 5129 |
5116 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 5130 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
5117 Register input = ToRegister(instr->value()); | 5131 Register input = ToRegister(instr->value()); |
5118 Register scratch = scratch0(); | 5132 Register scratch = scratch0(); |
5119 | 5133 |
5120 __ GetObjectType(input, scratch, scratch); | 5134 __ GetObjectType(input, scratch, scratch); |
5121 | 5135 |
5122 if (instr->hydrogen()->is_interval_check()) { | 5136 if (instr->hydrogen()->is_interval_check()) { |
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5890 __ Subu(scratch, result, scratch); | 5904 __ Subu(scratch, result, scratch); |
5891 __ lw(result, FieldMemOperand(scratch, | 5905 __ lw(result, FieldMemOperand(scratch, |
5892 FixedArray::kHeaderSize - kPointerSize)); | 5906 FixedArray::kHeaderSize - kPointerSize)); |
5893 __ bind(&done); | 5907 __ bind(&done); |
5894 } | 5908 } |
5895 | 5909 |
5896 | 5910 |
5897 #undef __ | 5911 #undef __ |
5898 | 5912 |
5899 } } // namespace v8::internal | 5913 } } // namespace v8::internal |
OLD | NEW |