| 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 |