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 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1873 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); | 1873 __ ubfx(result, result, Map::kElementsKindShift, Map::kElementsKindBitCount); |
1874 } | 1874 } |
1875 | 1875 |
1876 | 1876 |
1877 void LCodeGen::DoValueOf(LValueOf* instr) { | 1877 void LCodeGen::DoValueOf(LValueOf* instr) { |
1878 Register input = ToRegister(instr->value()); | 1878 Register input = ToRegister(instr->value()); |
1879 Register result = ToRegister(instr->result()); | 1879 Register result = ToRegister(instr->result()); |
1880 Register map = ToRegister(instr->temp()); | 1880 Register map = ToRegister(instr->temp()); |
1881 Label done; | 1881 Label done; |
1882 | 1882 |
1883 // If the object is a smi return the object. | 1883 if (!instr->hydrogen()->value()->IsHeapObject()) { |
1884 __ SmiTst(input); | 1884 // If the object is a smi return the object. |
1885 __ Move(result, input, eq); | 1885 __ SmiTst(input); |
1886 __ b(eq, &done); | 1886 __ Move(result, input, eq); |
| 1887 __ b(eq, &done); |
| 1888 } |
1887 | 1889 |
1888 // If the object is not a value type, return the object. | 1890 // If the object is not a value type, return the object. |
1889 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); | 1891 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); |
1890 __ Move(result, input, ne); | 1892 __ Move(result, input, ne); |
1891 __ b(ne, &done); | 1893 __ b(ne, &done); |
1892 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); | 1894 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); |
1893 | 1895 |
1894 __ bind(&done); | 1896 __ bind(&done); |
1895 } | 1897 } |
1896 | 1898 |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2431 Condition true_cond = | 2433 Condition true_cond = |
2432 EmitIsObject(reg, temp1, | 2434 EmitIsObject(reg, temp1, |
2433 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); | 2435 instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); |
2434 | 2436 |
2435 EmitBranch(instr, true_cond); | 2437 EmitBranch(instr, true_cond); |
2436 } | 2438 } |
2437 | 2439 |
2438 | 2440 |
2439 Condition LCodeGen::EmitIsString(Register input, | 2441 Condition LCodeGen::EmitIsString(Register input, |
2440 Register temp1, | 2442 Register temp1, |
2441 Label* is_not_string) { | 2443 Label* is_not_string, |
2442 __ JumpIfSmi(input, is_not_string); | 2444 SmiCheck check_needed = INLINE_SMI_CHECK) { |
| 2445 if (check_needed == INLINE_SMI_CHECK) { |
| 2446 __ JumpIfSmi(input, is_not_string); |
| 2447 } |
2443 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE); | 2448 __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE); |
2444 | 2449 |
2445 return lt; | 2450 return lt; |
2446 } | 2451 } |
2447 | 2452 |
2448 | 2453 |
2449 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { | 2454 void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { |
2450 Register reg = ToRegister(instr->value()); | 2455 Register reg = ToRegister(instr->value()); |
2451 Register temp1 = ToRegister(instr->temp()); | 2456 Register temp1 = ToRegister(instr->temp()); |
2452 | 2457 |
| 2458 SmiCheck check_needed = |
| 2459 instr->hydrogen()->value()->IsHeapObject() |
| 2460 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
2453 Condition true_cond = | 2461 Condition true_cond = |
2454 EmitIsString(reg, temp1, instr->FalseLabel(chunk_)); | 2462 EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed); |
2455 | 2463 |
2456 EmitBranch(instr, true_cond); | 2464 EmitBranch(instr, true_cond); |
2457 } | 2465 } |
2458 | 2466 |
2459 | 2467 |
2460 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 2468 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
2461 Register input_reg = EmitLoadRegister(instr->value(), ip); | 2469 Register input_reg = EmitLoadRegister(instr->value(), ip); |
2462 __ SmiTst(input_reg); | 2470 __ SmiTst(input_reg); |
2463 EmitBranch(instr, eq); | 2471 EmitBranch(instr, eq); |
2464 } | 2472 } |
2465 | 2473 |
2466 | 2474 |
2467 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { | 2475 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { |
2468 Register input = ToRegister(instr->value()); | 2476 Register input = ToRegister(instr->value()); |
2469 Register temp = ToRegister(instr->temp()); | 2477 Register temp = ToRegister(instr->temp()); |
2470 | 2478 |
2471 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); | 2479 if (!instr->hydrogen()->value()->IsHeapObject()) { |
| 2480 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); |
| 2481 } |
2472 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); | 2482 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
2473 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); | 2483 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); |
2474 __ tst(temp, Operand(1 << Map::kIsUndetectable)); | 2484 __ tst(temp, Operand(1 << Map::kIsUndetectable)); |
2475 EmitBranch(instr, ne); | 2485 EmitBranch(instr, ne); |
2476 } | 2486 } |
2477 | 2487 |
2478 | 2488 |
2479 static Condition ComputeCompareCondition(Token::Value op) { | 2489 static Condition ComputeCompareCondition(Token::Value op) { |
2480 switch (op) { | 2490 switch (op) { |
2481 case Token::EQ_STRICT: | 2491 case Token::EQ_STRICT: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2527 if (from == FIRST_TYPE) return ls; | 2537 if (from == FIRST_TYPE) return ls; |
2528 UNREACHABLE(); | 2538 UNREACHABLE(); |
2529 return eq; | 2539 return eq; |
2530 } | 2540 } |
2531 | 2541 |
2532 | 2542 |
2533 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 2543 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
2534 Register scratch = scratch0(); | 2544 Register scratch = scratch0(); |
2535 Register input = ToRegister(instr->value()); | 2545 Register input = ToRegister(instr->value()); |
2536 | 2546 |
2537 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); | 2547 if (!instr->hydrogen()->value()->IsHeapObject()) { |
| 2548 __ JumpIfSmi(input, instr->FalseLabel(chunk_)); |
| 2549 } |
2538 | 2550 |
2539 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); | 2551 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); |
2540 EmitBranch(instr, BranchCondition(instr->hydrogen())); | 2552 EmitBranch(instr, BranchCondition(instr->hydrogen())); |
2541 } | 2553 } |
2542 | 2554 |
2543 | 2555 |
2544 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { | 2556 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { |
2545 Register input = ToRegister(instr->value()); | 2557 Register input = ToRegister(instr->value()); |
2546 Register result = ToRegister(instr->result()); | 2558 Register result = ToRegister(instr->result()); |
2547 | 2559 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2962 __ cmp(scratch, ip); | 2974 __ cmp(scratch, ip); |
2963 if (instr->hydrogen()->DeoptimizesOnHole()) { | 2975 if (instr->hydrogen()->DeoptimizesOnHole()) { |
2964 DeoptimizeIf(eq, instr->environment()); | 2976 DeoptimizeIf(eq, instr->environment()); |
2965 } else { | 2977 } else { |
2966 __ b(ne, &skip_assignment); | 2978 __ b(ne, &skip_assignment); |
2967 } | 2979 } |
2968 } | 2980 } |
2969 | 2981 |
2970 __ str(value, target); | 2982 __ str(value, target); |
2971 if (instr->hydrogen()->NeedsWriteBarrier()) { | 2983 if (instr->hydrogen()->NeedsWriteBarrier()) { |
2972 HType type = instr->hydrogen()->value()->type(); | |
2973 SmiCheck check_needed = | 2984 SmiCheck check_needed = |
2974 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 2985 instr->hydrogen()->value()->IsHeapObject() |
| 2986 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
2975 __ RecordWriteContextSlot(context, | 2987 __ RecordWriteContextSlot(context, |
2976 target.offset(), | 2988 target.offset(), |
2977 value, | 2989 value, |
2978 scratch, | 2990 scratch, |
2979 GetLinkRegisterState(), | 2991 GetLinkRegisterState(), |
2980 kSaveFPRegs, | 2992 kSaveFPRegs, |
2981 EMIT_REMEMBERED_SET, | 2993 EMIT_REMEMBERED_SET, |
2982 check_needed); | 2994 check_needed); |
2983 } | 2995 } |
2984 | 2996 |
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4202 GetLinkRegisterState(), | 4214 GetLinkRegisterState(), |
4203 kSaveFPRegs, | 4215 kSaveFPRegs, |
4204 OMIT_REMEMBERED_SET, | 4216 OMIT_REMEMBERED_SET, |
4205 OMIT_SMI_CHECK); | 4217 OMIT_SMI_CHECK); |
4206 } | 4218 } |
4207 } | 4219 } |
4208 | 4220 |
4209 // Do the store. | 4221 // Do the store. |
4210 Register value = ToRegister(instr->value()); | 4222 Register value = ToRegister(instr->value()); |
4211 ASSERT(!object.is(value)); | 4223 ASSERT(!object.is(value)); |
4212 HType type = instr->hydrogen()->value()->type(); | |
4213 SmiCheck check_needed = | 4224 SmiCheck check_needed = |
4214 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4225 instr->hydrogen()->value()->IsHeapObject() |
| 4226 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4215 if (access.IsInobject()) { | 4227 if (access.IsInobject()) { |
4216 __ str(value, FieldMemOperand(object, offset)); | 4228 __ str(value, FieldMemOperand(object, offset)); |
4217 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4229 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4218 // Update the write barrier for the object for in-object properties. | 4230 // Update the write barrier for the object for in-object properties. |
4219 __ RecordWriteField(object, | 4231 __ RecordWriteField(object, |
4220 offset, | 4232 offset, |
4221 value, | 4233 value, |
4222 scratch, | 4234 scratch, |
4223 GetLinkRegisterState(), | 4235 GetLinkRegisterState(), |
4224 kSaveFPRegs, | 4236 kSaveFPRegs, |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4413 if (instr->hydrogen()->key()->representation().IsSmi()) { | 4425 if (instr->hydrogen()->key()->representation().IsSmi()) { |
4414 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); | 4426 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); |
4415 } else { | 4427 } else { |
4416 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 4428 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
4417 } | 4429 } |
4418 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | 4430 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); |
4419 } | 4431 } |
4420 __ str(value, FieldMemOperand(store_base, offset)); | 4432 __ str(value, FieldMemOperand(store_base, offset)); |
4421 | 4433 |
4422 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4434 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4423 HType type = instr->hydrogen()->value()->type(); | |
4424 SmiCheck check_needed = | 4435 SmiCheck check_needed = |
4425 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4436 instr->hydrogen()->value()->IsHeapObject() |
| 4437 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4426 // Compute address of modified element and store it into key register. | 4438 // Compute address of modified element and store it into key register. |
4427 __ add(key, store_base, Operand(offset - kHeapObjectTag)); | 4439 __ add(key, store_base, Operand(offset - kHeapObjectTag)); |
4428 __ RecordWrite(elements, | 4440 __ RecordWrite(elements, |
4429 key, | 4441 key, |
4430 value, | 4442 value, |
4431 GetLinkRegisterState(), | 4443 GetLinkRegisterState(), |
4432 kSaveFPRegs, | 4444 kSaveFPRegs, |
4433 EMIT_REMEMBERED_SET, | 4445 EMIT_REMEMBERED_SET, |
4434 check_needed); | 4446 check_needed); |
4435 } | 4447 } |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5137 | 5149 |
5138 | 5150 |
5139 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 5151 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
5140 LOperand* input = instr->value(); | 5152 LOperand* input = instr->value(); |
5141 __ SmiTst(ToRegister(input)); | 5153 __ SmiTst(ToRegister(input)); |
5142 DeoptimizeIf(ne, instr->environment()); | 5154 DeoptimizeIf(ne, instr->environment()); |
5143 } | 5155 } |
5144 | 5156 |
5145 | 5157 |
5146 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 5158 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
5147 LOperand* input = instr->value(); | 5159 if (!instr->hydrogen()->value()->IsHeapObject()) { |
5148 __ SmiTst(ToRegister(input)); | 5160 LOperand* input = instr->value(); |
5149 DeoptimizeIf(eq, instr->environment()); | 5161 __ SmiTst(ToRegister(input)); |
| 5162 DeoptimizeIf(eq, instr->environment()); |
| 5163 } |
5150 } | 5164 } |
5151 | 5165 |
5152 | 5166 |
5153 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 5167 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
5154 Register input = ToRegister(instr->value()); | 5168 Register input = ToRegister(instr->value()); |
5155 Register scratch = scratch0(); | 5169 Register scratch = scratch0(); |
5156 | 5170 |
5157 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 5171 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
5158 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | 5172 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); |
5159 | 5173 |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5894 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5908 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5895 __ ldr(result, FieldMemOperand(scratch, | 5909 __ ldr(result, FieldMemOperand(scratch, |
5896 FixedArray::kHeaderSize - kPointerSize)); | 5910 FixedArray::kHeaderSize - kPointerSize)); |
5897 __ bind(&done); | 5911 __ bind(&done); |
5898 } | 5912 } |
5899 | 5913 |
5900 | 5914 |
5901 #undef __ | 5915 #undef __ |
5902 | 5916 |
5903 } } // namespace v8::internal | 5917 } } // namespace v8::internal |
OLD | NEW |